Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-08-11 17:42:58 +03:00
239 changed files with 3835 additions and 1991 deletions
+2 -2
View File
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="pty4j">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/pty4j-0.4.17.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/pty4j-0.4.19.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/pty4j-0.4.17-src.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/src/pty4j-0.4.19-src.jar!/" />
</SOURCES>
</library>
</component>
@@ -16,9 +16,7 @@
package com.intellij.packaging.impl.artifacts;
import com.intellij.compiler.server.BuildManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.application.*;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
@@ -193,9 +191,18 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
@Override
public void loadState(ArtifactManagerState managerState) {
final List<ArtifactImpl> artifacts = new ArrayList<ArtifactImpl>();
for (ArtifactState state : managerState.getArtifacts()) {
artifacts.add(loadArtifact(state));
List<ArtifactState> artifactStates = managerState.getArtifacts();
final List<ArtifactImpl> artifacts = new ArrayList<ArtifactImpl>(artifactStates.size());
if (!artifactStates.isEmpty()) {
AccessToken token = ReadAction.start();
try {
for (ArtifactState state : artifactStates) {
artifacts.add(loadArtifact(state));
}
}
finally {
token.finish();
}
}
if (myLoaded) {
@@ -49,7 +49,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
private final DfaValueFactory myFactory;
private final List<EqClass> myEqClasses;
// dfa value id -> indices in myEqClasses list of the classes which contain the id (or negated or wrapped)
// dfa value id -> indices in myEqClasses list of the classes which contain the id (or wrapped)
private final TIntObjectHashMap<int[]> myIdToEqClassesIndices;
private final Stack<DfaValue> myStack;
private final TLongHashSet myDistinctClasses;
@@ -321,7 +321,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
}
private void removeFromMap(int id, int index) {
if (id < 0) return;
id = unwrap(myFactory.getValue(id)).getID();
int[] classes = myIdToEqClassesIndices.get(id);
if (classes != null) {
@@ -487,11 +486,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
}
EqClass newClass = new EqClass(c1);
for (int i = 0; i < newClass.size(); i++) {
int c = newClass.get(i);
removeFromMap(c, c1Index);
addToMap(c, c1Index);
}
myEqClasses.set(c1Index, newClass);
for (int i = 0; i < c2.size(); i++) {
@@ -376,10 +376,13 @@ public class DuplicatesFinder {
final PsiClass patternClass = RefactoringChangeUtil.getThisClass(pattern);
final PsiClass candidateClass = RefactoringChangeUtil.getThisClass(candidate);
if (resolveResult1 == resolveResult2 &&
resolveResult1 instanceof PsiMember &&
!InheritanceUtil.isInheritorOrSelf(candidateClass, patternClass, true) &&
InheritanceUtil.isInheritorOrSelf(candidateClass, ((PsiMember)resolveResult1).getContainingClass(), true)) {
return false;
resolveResult1 instanceof PsiMember) {
final PsiClass containingClass = ((PsiMember)resolveResult1).getContainingClass();
if (!InheritanceUtil.isInheritorOrSelf(candidateClass, patternClass, true) &&
InheritanceUtil.isInheritorOrSelf(candidateClass, containingClass, true) &&
InheritanceUtil.isInheritorOrSelf(patternClass, containingClass, true)) {
return false;
}
}
}
@@ -42,12 +42,14 @@ import com.intellij.psi.PsiReference;
import com.intellij.psi.statistics.JavaStatisticsManager;
import com.intellij.psi.statistics.StatisticsManager;
import com.intellij.ui.popup.list.ListPopupImpl;
import com.intellij.ui.popup.list.PopupListElementRenderer;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@@ -161,7 +163,18 @@ public class AddImportAction implements QuestionAction {
ListPopupImpl popup = new ListPopupImpl(step) {
@Override
protected ListCellRenderer getListElementRenderer() {
return new DefaultPsiElementCellRenderer();
final PopupListElementRenderer baseRenderer = (PopupListElementRenderer)super.getListElementRenderer();
final DefaultPsiElementCellRenderer psiRenderer = new DefaultPsiElementCellRenderer();
return new ListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JPanel panel = new JPanel(new BorderLayout());
baseRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
panel.add(baseRenderer.getNextStepLabel(), BorderLayout.EAST);
panel.add(psiRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus));
return panel;
}
};
}
};
popup.showInBestPositionFor(myEditor);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,12 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.intention.impl.ParameterClassMember;
import com.intellij.ide.util.MemberChooser;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,24 +34,42 @@ import java.util.List;
*/
public class DefineParamsDefaultValueAction extends DelegateWithDefaultParamValueIntentionAction {
@NotNull
@Override
public String getText() {
return "Define params default value";
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
if (!JavaLanguage.INSTANCE.equals(element.getLanguage())) {
return false;
}
final PsiElement parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiCodeBlock.class);
if (!(parent instanceof PsiMethod)) {
return false;
}
final PsiMethod method = (PsiMethod)parent;
final PsiParameterList parameterList = method.getParameterList();
if (parameterList.getParametersCount() == 0) {
return false;
}
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null || (containingClass.isInterface() && !PsiUtil.isLanguageLevel8OrHigher(method))) {
return false;
}
setText("Generate overloaded " + (method.isConstructor() ? "constructor" : "method") + " with default parameter values");
return true;
}
@Nullable
@Override
protected PsiParameter[] getParams(PsiElement element) {
final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
assert method != null;
final PsiParameter[] parameters = method.getParameterList().getParameters();
final ParameterClassMember[] members = new ParameterClassMember[parameters.length];
for (int i = 0; i < members.length; i++) {
members[i] = new ParameterClassMember(parameters[i]);
}
final MemberChooser<ParameterClassMember> chooser = new MemberChooser<ParameterClassMember>(members, false, true, element.getProject());
final MemberChooser<ParameterClassMember> chooser =
new MemberChooser<ParameterClassMember>(members, false, true, element.getProject());
chooser.selectElements(members);
chooser.setTitle("Choose " + (method.isConstructor() ? "Constructor" : "Method") + " Parameters");
chooser.setTitle("Choose Default Value Parameters");
if (chooser.showAndGet()) {
final List<ParameterClassMember> elements = chooser.getSelectedElements();
if (elements != null) {
@@ -67,4 +87,10 @@ public class DefineParamsDefaultValueAction extends DelegateWithDefaultParamValu
public boolean startInWriteAction() {
return false;
}
@NotNull
@Override
public String getFamilyName() {
return "Generate overloaded method with default parameter values";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
@@ -57,8 +58,12 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase
if (declarationScope instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)declarationScope;
final PsiClass containingClass = method.getContainingClass();
if (containingClass != null && !containingClass.isInterface()) {
return containingClass.findMethodBySignature(generateMethodPrototype(method, parameter), false) == null;
if (containingClass != null && (!containingClass.isInterface() || PsiUtil.isLanguageLevel7OrHigher(method))) {
if (containingClass.findMethodBySignature(generateMethodPrototype(method, parameter), false) != null) {
return false;
}
setText("Generate overloaded " + (method.isConstructor() ? "constructor" : "method") + " with default parameter value");
return true;
}
}
}
@@ -81,6 +86,11 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase
prototype.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false);
prototype.addBefore(emptyBody, null);
}
final PsiClass aClass = method.getContainingClass();
if (aClass != null && aClass.isInterface()) {
prototype.getModifierList().setModifierProperty(PsiModifier.DEFAULT, true);
}
for (int i = params.length - 1; i >= 0; i--) {
PsiParameter param = params[i];
final int parameterIndex = method.getParameterList().getParameterIndex(param);
@@ -98,7 +108,8 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase
final PsiMethod existingMethod = method.getContainingClass().findMethodBySignature(methodPrototype, false);
if (existingMethod != null) {
editor.getCaretModel().moveToOffset(existingMethod.getTextOffset());
HintManager.getInstance().showErrorHint(editor, "Method with the chosen signature already exist");
HintManager.getInstance().showErrorHint(editor, (existingMethod.isConstructor() ? "Constructor" : "Method") +
" with the chosen signature already exists");
return;
}
@@ -170,15 +181,9 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase
return new PsiParameter[]{PsiTreeUtil.getParentOfType(element, PsiParameter.class)};
}
@NotNull
@Override
public String getText() {
return "Generate delegated method with default parameter value";
}
@NotNull
@Override
public String getFamilyName() {
return getText();
return "Generate overloaded method with default parameter value";
}
}
@@ -189,13 +189,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
return;
}
PsiElement parent = atCaret.getParent();
if (parent instanceof PsiCodeBlock) {
final PsiCodeBlock block = (PsiCodeBlock) parent;
if (block.getStatements().length > 0 && block.getStatements()[0] == atCaret) {
atCaret = block;
}
}
else if (parent instanceof PsiForStatement) {
if (parent instanceof PsiForStatement) {
atCaret = parent;
}
@@ -28,8 +28,8 @@ import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplate
import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost;
public class ForeachPostfixTemplate extends StringBasedPostfixTemplate {
public ForeachPostfixTemplate() {
super("for", "for (T item : expr)", selectorTopmost(IS_ITERABLE_OR_ARRAY));
public ForeachPostfixTemplate(String name) {
super(name, "for (T item : expr)", selectorTopmost(IS_ITERABLE_OR_ARRAY));
}
@Override
@@ -42,7 +42,8 @@ public class JavaPostfixTemplateProvider implements PostfixTemplateProvider {
new ElseStatementPostfixTemplate(),
new ForAscendingPostfixTemplate(),
new ForDescendingPostfixTemplate(),
new ForeachPostfixTemplate(),
new ForeachPostfixTemplate("iter"),
new ForeachPostfixTemplate("for"),
new FormatPostfixTemplate(),
new IfStatementPostfixTemplate(),
new InstanceofExpressionPostfixTemplate(),
@@ -1,8 +1,7 @@
class Foo {
abstract void a();
{
a();<caret>
a();
}
}
@@ -1,8 +1,7 @@
class Foo {
abstract void a();
{
a();<caret>
a();
}
}
@@ -1,6 +1,5 @@
class Foo {
boolean a;
{
if (a) {
} else {
@@ -0,0 +1,9 @@
public class Test {
public void foo(int x) {
int a = 2<caret>
System.out.println("");
System.out.println("");
System.out.println("");
}
}
@@ -0,0 +1,9 @@
public class Test {
public void foo(int x) {
int a = 2;
System.out.println("");
System.out.println("");
System.out.println("");
}
}
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
void foo() {
foo(<caret>);
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
abstract class Test {
int foo(boolean... args) {
return foo(<caret>, args);
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
int foo() {
return foo();
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded constructor with default parameter value" "true"
class Test {
Test() {
this(<caret>);
@@ -0,0 +1,8 @@
// "Generate overloaded method with default parameter value" "true"
interface Test {
default void foo() {
foo();
}
void foo(int ii);
}
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
/**
*/
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
int foo() {
return foo(<caret>);
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
<T> int foo(boolean... args) {
return foo(<caret>, args);
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
int foo(boolean... args) {
return foo(<caret>, args);
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
void foo(int i<caret>i){
}
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
abstract class Test {
abstract int foo(int i<caret>i, boolean... args);
}
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
int foo(int i<caret>i){
//comment1
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded constructor with default parameter value" "true"
class Test {
Test(int i<caret>i){}
}
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "false"
// "Generate overloaded method with default parameter value" "false"
class Test {
void foo(){}
void foo(int i<caret>i){
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "false"
// "Generate overloaded method with default parameter value" "true"
interface Test {
void foo(int i<caret>i);
}
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
/**
* @param i
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
int foo(int i<caret>i){
return 1;
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
<T> int foo(T i<caret>i, boolean... args){
return 1;
@@ -1,4 +1,4 @@
// "Generate delegated method with default parameter value" "true"
// "Generate overloaded method with default parameter value" "true"
class Test {
int foo(int i<caret>i, boolean... args){
return 1;
@@ -1,8 +1,10 @@
Cleaning output files:
out/production/ChangeExtends/Super.class
out/production/ChangeExtends/Super2.class
End of files
Compiling files:
src/Super.java
src/Super2.java
End of files
Cleaning output files:
out/production/ChangeExtends/Client.class
@@ -13,4 +15,4 @@ Compiling files:
src/Client.java
src/Client2.java
src/Client3.java
End of files
End of files
@@ -0,0 +1,3 @@
class Super2 {
char s = 's';
}
@@ -0,0 +1,2 @@
class Client4 extends Hyper<Client4>{
}
@@ -0,0 +1,3 @@
class Super2 extends Hyper<Integer> {
char s = 's';
}
@@ -0,0 +1,16 @@
import java.util.*;
class Main {
private final Map<Integer, Map<String, String>> myScheduledUpdates = null;
void foo() {
new Runnable() {
@Override
public void run() {
<selection>myScheduledUpdates.keySet().toArray(new Object[myScheduledUpdates.keySet().size()])</selection>;
}
};
myScheduledUpdates.keySet().toArray(new Object[myScheduledUpdates.keySet().size()]);
}
}
@@ -0,0 +1,20 @@
import java.util.*;
class Main {
private final Map<Integer, Map<String, String>> myScheduledUpdates = null;
void foo() {
new Runnable() {
@Override
public void run() {
newMethod();
}
};
newMethod();
}
private Object[] newMethod() {
return myScheduledUpdates.keySet().toArray(new Object[myScheduledUpdates.keySet().size()]);
}
}
@@ -67,6 +67,8 @@ public class CompleteStatementTest extends EditorActionTestCase {
}
}
public void testNoBlockReformat() { doTest(); }
public void testCompleteCatchWithExpression() throws Exception { doTest(); }
public void testCompleteCatchBody() throws Exception { doTest(); }
@@ -28,8 +28,6 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.event.EditorEventMulticaster;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.Segment;
@@ -672,35 +670,6 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase {
assertNotNull(node);
}
public void testSmartPointersForOpenFilesAreFastened() {
PsiJavaFile file = (PsiJavaFile)myJavaFacade.findClass("AClass", GlobalSearchScope.allScope(getProject())).getContainingFile();
SmartPointerManagerImpl manager = (SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject);
VirtualFile virtualFile = file.getVirtualFile();
assertFalse(manager.areBeltsFastened(virtualFile));
FileEditor[] editors = FileEditorManager.getInstance(myProject).openFile(virtualFile, true);
assertTrue(editors.length != 0);
assertTrue(manager.areBeltsFastened(virtualFile));
FileEditorManager.getInstance(myProject).closeFile(virtualFile);
assertFalse(manager.areBeltsFastened(virtualFile));
SmartPsiElementPointer<PsiClass> pointer = manager.createSmartPsiElementPointer(file.getClasses()[0]);
assertFalse(manager.areBeltsFastened(virtualFile));
editors = FileEditorManager.getInstance(myProject).openFile(virtualFile, true);
assertTrue(editors.length != 0);
assertTrue(manager.areBeltsFastened(virtualFile));
FileEditorManager.getInstance(myProject).closeFile(virtualFile);
assertFalse(manager.areBeltsFastened(virtualFile));
assertEquals(file.getClasses()[0], pointer.getElement()); // retain pointer from gc
}
public void testLargeFileWithManyChanges() {
configureByText(PlainTextFileType.INSTANCE, StringUtil.repeat("foo foo \n", 50000));
final TextRange range = TextRange.from(10, 10);
@@ -225,6 +225,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
doDuplicatesTest();
}
public void testDuplicatesFromAnonymous() throws Exception {
doDuplicatesTest();
}
public void testCodeDuplicatesWithContinueNoReturn() throws Exception {
doDuplicatesTest();
}
@@ -79,23 +79,23 @@ public class CompilerTestUtil {
}
public static void enableExternalCompiler() {
ApplicationManagerEx.getApplicationEx().doNotSave(false);
final JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
new WriteAction() {
@Override
protected void run(@NotNull final Result result) {
ApplicationManagerEx.getApplicationEx().doNotSave(false);
JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
table.addJdk(table.getInternalJdk());
}
}.execute();
}
public static void disableExternalCompiler(final Project project) {
ApplicationManagerEx.getApplicationEx().doNotSave(true);
final JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
new WriteAction() {
@Override
protected void run(@NotNull final Result result) {
ApplicationManagerEx.getApplicationEx().doNotSave(true);
Module[] modules = ModuleManager.getInstance(project).getModules();
JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
Sdk internalJdk = table.getInternalJdk();
List<Module> modulesToRestore = new ArrayList<Module>();
for (Module module : modules) {
@@ -69,12 +69,12 @@ public class CompilerTester {
myMainOutput = new TempDirTestFixtureImpl();
myMainOutput.setUp();
CompilerTestUtil.enableExternalCompiler();
new WriteCommandAction(getProject()) {
@Override
protected void run(@NotNull Result result) throws Throwable {
//noinspection ConstantConditions
CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl());
CompilerTestUtil.enableExternalCompiler();
for (Module module : myModules) {
ModuleRootModificationUtil.setModuleSdk(module, JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk());
}
@@ -217,61 +217,21 @@ class ClassfileAnalyzer {
}
}
private final SignatureVisitor mySignatureCrawler = new SignatureVisitor(Opcodes.ASM5) {
public void visitFormalTypeParameter(String name) {
}
private final SignatureVisitor mySignatureCrawler = new BaseSignatureVisitor() {
public SignatureVisitor visitClassBound() {
return this;
return mySignatureWithGenericBoundUsageCrawler;
}
public SignatureVisitor visitInterfaceBound() {
return this;
}
public SignatureVisitor visitSuperclass() {
return this;
}
public SignatureVisitor visitInterface() {
return this;
}
public SignatureVisitor visitParameterType() {
return this;
}
public SignatureVisitor visitReturnType() {
return this;
}
public SignatureVisitor visitExceptionType() {
return this;
}
public void visitBaseType(char descriptor) {
}
public void visitTypeVariable(String name) {
}
public SignatureVisitor visitArrayType() {
return this;
}
public void visitInnerClassType(String name) {
}
public void visitTypeArgument() {
return mySignatureWithGenericBoundUsageCrawler;
}
public SignatureVisitor visitTypeArgument(char wildcard) {
return this;
}
public void visitEnd() {
return mySignatureWithGenericBoundUsageCrawler;
}
};
private final SignatureVisitor mySignatureWithGenericBoundUsageCrawler = new BaseSignatureVisitor() {
public void visitClassType(String name) {
final int className = myContext.get(name);
myUsages.add(UsageRepr.createClassUsage(myContext, className));
@@ -653,6 +613,72 @@ class ClassfileAnalyzer {
myLocalClassFlag.set(true);
}
}
private class BaseSignatureVisitor extends SignatureVisitor {
public BaseSignatureVisitor() {
super(Opcodes.ASM5);
}
public void visitFormalTypeParameter(String name) {
}
public SignatureVisitor visitClassBound() {
return this;
}
public SignatureVisitor visitInterfaceBound() {
return this;
}
public SignatureVisitor visitSuperclass() {
return this;
}
public SignatureVisitor visitInterface() {
return this;
}
public SignatureVisitor visitParameterType() {
return this;
}
public SignatureVisitor visitReturnType() {
return this;
}
public SignatureVisitor visitExceptionType() {
return this;
}
public void visitBaseType(char descriptor) {
}
public void visitTypeVariable(String name) {
}
public SignatureVisitor visitArrayType() {
return this;
}
public void visitInnerClassType(String name) {
}
public void visitTypeArgument() {
}
public SignatureVisitor visitTypeArgument(char wildcard) {
return this;
}
public void visitEnd() {
}
public void visitClassType(String name) {
final int className = myContext.get(name);
myUsages.add(UsageRepr.createClassUsage(myContext, className));
}
}
}
public Pair<ClassRepr, Set<UsageRepr.Usage>> analyze(final int fileName, final ClassReader cr) {
@@ -716,6 +716,28 @@ public class Mappings {
public abstract boolean checkResidence(final int residence);
}
public class FileFilterConstraint extends UsageConstraint {
@NotNull
private final DependentFilesFilter myFilter;
public FileFilterConstraint(@NotNull DependentFilesFilter filter) {
myFilter = filter;
}
public boolean checkResidence(int residence) {
final Collection<File> fNames = myClassToSourceFile.get(residence);
if (fNames == null || fNames.isEmpty()) {
return true;
}
for (File fName : fNames) {
if (myFilter.accept(fName)) {
return true;
}
}
return false;
}
}
public class PackageConstraint extends UsageConstraint {
public final String packageName;
@@ -1132,6 +1154,11 @@ public class Mappings {
debug("Class is annotation, skipping method analysis");
return;
}
assert myFuture != null;
assert myPresent != null;
assert myAffectedFiles != null;
Ref<ClassRepr> oldItRef = null;
for (final MethodRepr m : added) {
debug("Method: ", m.name);
@@ -1256,6 +1283,10 @@ public class Mappings {
if (removed.isEmpty()) {
return;
}
assert myFuture != null;
assert myAffectedFiles != null;
assert myCompiledFiles != null;
debug("Processing removed methods:");
for (final MethodRepr m : removed) {
debug("Method ", m.name);
@@ -1362,6 +1393,10 @@ public class Mappings {
return;
}
debug("Processing changed methods:");
assert myFuture != null;
assert myAffectedFiles != null;
for (final Pair<MethodRepr, Difference> mr : changed) {
final MethodRepr m = mr.first;
final MethodRepr.Diff d = (MethodRepr.Diff)mr.second;
@@ -1473,6 +1508,11 @@ public class Mappings {
}
debug("Processing added fields");
assert myFuture != null;
assert myPresent != null;
assert myCompiledFiles != null;
assert myAffectedFiles != null;
for (final FieldRepr f : added) {
debug("Field: ", f.name);
@@ -1535,23 +1575,23 @@ public class Mappings {
// nothing
}
else {
Util.UsageConstraint constaint;
Util.UsageConstraint constraint;
if ((ff.isProtected() && f.isPublic()) || (f.isProtected() && ff.isPublic()) || (ff.isPackageLocal() && f.isProtected())) {
constaint = myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name));
constraint = myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name));
}
else if (ff.isPublic() && ff.isPackageLocal()) {
constaint = myFuture.new NegationConstraint(myFuture.new PackageConstraint(cc.getPackageName()));
constraint = myFuture.new NegationConstraint(myFuture.new PackageConstraint(cc.getPackageName()));
}
else {
constaint =
constraint =
myFuture.new IntersectionConstraint(myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name)),
myFuture.new NegationConstraint(
myFuture.new PackageConstraint(cc.getPackageName())));
}
for (final UsageRepr.Usage usage : localUsages) {
state.myUsageConstraints.put(usage, constaint);
state.myUsageConstraints.put(usage, constraint);
}
}
@@ -1569,6 +1609,8 @@ public class Mappings {
if (removed.isEmpty()) {
return true;
}
assert myFuture != null;
debug("Processing removed fields:");
for (final FieldRepr f : removed) {
@@ -1577,6 +1619,7 @@ public class Mappings {
if (!f.isPrivate() && (f.access & DESPERATE_MASK) == DESPERATE_MASK && f.hasValue()) {
debug("Field had value and was (non-private) final static => a switch to non-incremental mode requested");
if (myConstantSearch != null) {
assert myDelayedWorks != null;
myDelayedWorks.addConstantWork(it.name, f, true, false);
}
else {
@@ -1601,6 +1644,7 @@ public class Mappings {
return true;
}
debug("Processing changed fields:");
assert myFuture != null;
for (final Pair<FieldRepr, Difference> f : changed) {
final Difference d = f.second;
@@ -1619,6 +1663,7 @@ public class Mappings {
if (harmful || valueChanged || becameLessAccessible) {
debug("Inline field changed it's access or value => a switch to non-incremental mode requested");
if (myConstantSearch != null) {
assert myDelayedWorks != null;
myDelayedWorks.addConstantWork(it.name, field, false, accessChanged);
}
else {
@@ -1687,6 +1732,10 @@ public class Mappings {
final Collection<Pair<ClassRepr, Difference>> changedClasses = state.myClassDiff.changed();
if (!changedClasses.isEmpty()) {
debug("Processing changed classes:");
assert myFuture != null;
assert myPresent != null;
final Util.FileFilterConstraint fileFilterConstraint = myFilter != null? myPresent.new FileFilterConstraint(myFilter) : null;
for (final Pair<ClassRepr, Difference> changed : changedClasses) {
final ClassRepr changedClass = changed.first;
@@ -1753,7 +1802,11 @@ public class Mappings {
@Override
public boolean execute(int className) {
debug("Affecting usages in generic type parameter bounds of class: ", className);
state.myAffectedUsages.add(UsageRepr.createClassAsGenericBoundUsage(myContext, className));
final UsageRepr.Usage usage = UsageRepr.createClassAsGenericBoundUsage(myContext, className);
state.myAffectedUsages.add(usage);
if (fileFilterConstraint != null) {
state.myUsageConstraints.put(usage, fileFilterConstraint);
}
final TIntHashSet depClasses = myClassToClassDependency.get(className);
if (depClasses != null) {
@@ -1869,6 +1922,9 @@ public class Mappings {
if (removed.isEmpty()) {
return;
}
assert myPresent != null;
assert myDelta.myChangedFiles != null;
myDelta.myChangedFiles.add(fileName);
debug("Processing removed classes:");
@@ -1896,6 +1952,9 @@ public class Mappings {
if (!myEasyMode && myFilter != null) {
// checking if this newly added class duplicates already existing one
assert myCompiledFiles != null;
assert myAffectedFiles != null;
for (ClassRepr c : addedClasses) {
if (!c.isLocal() && !c.isAnonymous() && isEmpty(c.getOuterClassName())) {
final Set<File> candidates = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
@@ -1976,6 +2035,8 @@ public class Mappings {
}
private void affectCorrespondingSourceFiles(TIntHashSet toAffect) {
assert myAffectedFiles != null;
toAffect.forEach(new TIntProcedure() {
@Override
public boolean execute(int depClass) {
@@ -1995,6 +2056,8 @@ public class Mappings {
private void calculateAffectedFiles(final DiffState state) {
debug("Checking dependent classes:");
assert myAffectedFiles != null;
assert myCompiledFiles != null;
state.myDependants.forEach(new TIntProcedure() {
@Override
@@ -2106,6 +2169,8 @@ public class Mappings {
if (myEasyMode) {
return false;
}
assert myAffectedFiles != null;
assert myDelayedWorks != null;
final Collection<String> removed = myDelta.myRemovedFiles;
if (removed != null) {
@@ -2117,6 +2182,7 @@ public class Mappings {
}
finally {
if (myFilesToCompile != null) {
assert myDelta.myChangedFiles != null;
// if some class is associated with several sources,
// some of them may not have been compiled in this round, so such files should be considered unchanged
myDelta.myChangedFiles.retainAll(myFilesToCompile);
@@ -2463,7 +2529,9 @@ public class Mappings {
}
for (final String s : staticImports) {
int i = s.length() - 1;
for (; s.charAt(i) != '.'; i--) ;
while (s.charAt(i) != '.') {
i--;
}
final String anImport = s.substring(0, i);
if (!anImport.endsWith("*")) {
allImports.add(anImport); // filter out wildcard imports
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -55,7 +55,7 @@ oromatcher.jar
picocontainer.jar
protobuf-2.5.0.jar
proxy-vole_20131209.jar
pty4j-0.4.17.jar
pty4j-0.4.19.jar
purejavacomm.jar
resolver.jar
rhino-js-1_7R4.jar
@@ -19,6 +19,7 @@ import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.components.PathMacroSubstitutor
import com.intellij.openapi.components.impl.stores.StorageData
import org.jdom.Element
import org.jetbrains.annotations.NotNull
import kotlin.properties.Delegates
abstract class BaseFileConfigurableStoreImpl(protected val pathMacroManager: PathMacroManager) : ComponentStoreImpl() {
@@ -39,7 +40,7 @@ open class ProjectStorageData : StorageData {
private var version = CURRENT_FORMAT_VERSION
constructor(rootElementName: String) : super(rootElementName) {
constructor() : super() {
}
protected constructor(storageData: ProjectStorageData) : super(storageData) {
@@ -51,11 +52,8 @@ open class ProjectStorageData : StorageData {
version = rootElement.getAttributeValue(VERSION_OPTION)?.toInt() ?: CURRENT_FORMAT_VERSION
}
override fun save(newLiveStates: Map<String, Element>): Element {
var root = super.save(newLiveStates)
if (root == null) {
root = Element(myRootElementName)
}
override fun save(newLiveStates: Map<String, Element>, rootElementName: String): Element {
val root = super.save(newLiveStates, rootElementName) ?: Element(rootElementName)
writeOptions(root)
return root
}
@@ -17,13 +17,15 @@ package com.intellij.configurationStore
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.*
import com.intellij.openapi.components.impl.stores.FileBasedStorage
import com.intellij.openapi.components.impl.stores.FileStorage
import com.intellij.openapi.components.impl.stores.StateStorageManager
import com.intellij.openapi.components.impl.stores.StorageData
import com.intellij.openapi.components.impl.stores.StreamProvider
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.impl.ProjectImpl
import com.intellij.openapi.util.Couple
import com.intellij.util.containers.ContainerUtil
import org.jdom.Element
import java.io.File
import kotlin.properties.Delegates
@@ -38,6 +40,25 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat
private val storage by Delegates.lazy { DefaultProjectStorage(File(ApplicationManager.getApplication().stateStore.getStateStorageManager().expandMacros(FILE_SPEC)), FILE_SPEC, pathMacroManager) }
private class DefaultProjectStorage(file: File, fileSpec: String, pathMacroManager: PathMacroManager) : FileBasedStorage(file, fileSpec, "defaultProject", pathMacroManager.createTrackingSubstitutor(), RoamingType.DISABLED) {
override public fun loadLocalData(): Element? {
val element = super.loadLocalData() ?: return null
try {
return element.getChild("component").getChild("defaultProject")
}
catch (e: NullPointerException) {
LOG.warn("Cannot read default project")
return null
}
}
override fun createSaveSession(storageData: StorageData) = object : FileBasedStorage.FileSaveSession(storageData, this) {
override fun saveLocally(element: Element?) {
super.saveLocally(Element("application").addContent(Element("component").setAttribute("name", "ProjectManager").addContent(element)))
}
}
}
private val storageManager = object : StateStorageManager {
override fun rename(path: String, newName: String) {
}
@@ -48,7 +69,7 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat
override fun getStateStorage(fileSpec: String, roamingType: RoamingType) = storage
override fun getCachedFileStateStorages(changed: Collection<String>, deleted: Collection<String>): Couple<Collection<FileBasedStorage>> = Couple(emptyList<FileBasedStorage>(), emptyList<FileBasedStorage>())
override fun getCachedFileStateStorages(changed: Collection<String>, deleted: Collection<String>): Couple<Collection<FileStorage>> = Couple(emptyList<FileStorage>(), emptyList<FileStorage>())
override fun startExternalization(): StateStorageManager.ExternalizationSession? {
val externalizationSession = storage.startExternalization()
@@ -29,7 +29,7 @@ class ModuleFileData : ProjectStorageData, OptionManager {
override fun isDirty() = dirty
public constructor(rootElementName: String) : super(rootElementName) {
public constructor() : super() {
options = TreeMap<String, String>()
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.StateStorage
import com.intellij.openapi.components.StateStorageOperation
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.TrackingPathMacroSubstitutor
import com.intellij.openapi.components.impl.stores.StorageData
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.impl.ModuleEx
import com.intellij.openapi.module.impl.ModuleManagerImpl
@@ -29,14 +30,14 @@ import com.intellij.util.PathUtilRt
import com.intellij.util.containers.ContainerUtil
class ModuleStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, module: Module) : StateStorageManagerImpl("module", macroSubstitutor, module) {
override fun createStorageData(fileSpec: String) = ModuleFileData(rootTagName)
override fun createStorageData(fileSpec: String) = ModuleFileData()
override fun startExternalization() = MyStateStorageManagerExternalizationSession(this)
private class MyStateStorageManagerExternalizationSession(storageManager: StateStorageManagerImpl) : StateStorageManagerImpl.StateStorageManagerExternalizationSession(storageManager) {
override fun createSaveSessions(): List<StateStorage.SaveSession> {
val storage = ContainerUtil.getFirstItem(storageManager.getCachedFileStorages(listOf(StoragePathMacros.MODULE_FILE)))
if (storage != null && storage.getStorageData().isDirty()) {
if (storage != null && (storage.getStorageData() as StorageData).isDirty()) {
// force XmlElementStorageSaveSession creation
getExternalizationSession(storage)
}
@@ -22,7 +22,7 @@ import com.intellij.openapi.components.TrackingPathMacroSubstitutor
import com.intellij.openapi.project.impl.ProjectImpl
class ProjectStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, private val project: ProjectImpl) : StateStorageManagerImpl("project", macroSubstitutor, project) {
override fun createStorageData(fileSpec: String) = ProjectStorageData(rootTagName)
override fun createStorageData(fileSpec: String) = ProjectStorageData()
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation): String? {
val workspace = project.isWorkspaceComponent(component.javaClass)
@@ -23,7 +23,6 @@ import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.invokeAndWaitIfNeed
import com.intellij.openapi.components.*
import com.intellij.openapi.components.StateStorage.SaveSession
import com.intellij.openapi.components.impl.stores.FileBasedStorage
import com.intellij.openapi.components.impl.stores.IComponentStore
import com.intellij.openapi.components.impl.stores.IProjectStore
import com.intellij.openapi.fileTypes.FileTypeManager
@@ -148,7 +147,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, pathMacroManager:
return baseDir.getName().replace(":", "")
}
else {
var temp = PathUtilRt.getFileName(getProjectFileStorage().getFilePath())
var temp = PathUtilRt.getFileName(getProjectFilePath())
val fileType = FileTypeManager.getInstance().getFileTypeByFileName(temp)
if (fileType is ProjectFileType) {
temp = temp.substring(0, temp.length() - fileType.getDefaultExtension().length() - 1)
@@ -175,16 +174,13 @@ open class ProjectStoreImpl(override val project: ProjectImpl, pathMacroManager:
override fun getProjectFile() = getProjectFileStorage().getVirtualFile()
override fun getProjectFilePath() = getProjectFileStorage().getFilePath()
override fun getProjectFilePath() = storageManager.expandMacros(StoragePathMacros.PROJECT_FILE)
private fun getProjectFileStorage() = storageManager.getStateStorage(StoragePathMacros.PROJECT_FILE, RoamingType.PER_USER) as FileBasedStorage
override fun getWorkspaceFile() = workspaceStorage?.getVirtualFile()
override fun getWorkspaceFile() = (storageManager.getStateStorage(StoragePathMacros.WORKSPACE_FILE, RoamingType.DISABLED) as FileBasedStorage?)?.getVirtualFile()
override fun getWorkspaceFilePath() = workspaceStorage?.getFilePath()
private val workspaceStorage: FileBasedStorage?
get() = storageManager.getStateStorage(StoragePathMacros.WORKSPACE_FILE, RoamingType.DISABLED) as FileBasedStorage?
override fun getWorkspaceFilePath() = storageManager.expandMacros(StoragePathMacros.WORKSPACE_FILE)
override fun loadProjectFromTemplate(defaultProject: Project) {
defaultProject.save()
@@ -46,7 +46,7 @@ import kotlin.reflect.jvm.java
/**
* If componentManager not specified, storage will not add file tracker (see VirtualFileTracker)
*/
open class StateStorageManagerImpl(protected val rootTagName: String,
open class StateStorageManagerImpl(private val rootTagName: String,
private val pathMacroSubstitutor: TrackingPathMacroSubstitutor? = null,
val componentManager: ComponentManager? = null,
private val virtualFileTracker: StorageVirtualFileTracker? = StateStorageManagerImpl.createDefaultVirtualTracker(componentManager) ) : StateStorageManager {
@@ -155,7 +155,7 @@ open class StateStorageManagerImpl(protected val rootTagName: String,
override final fun getCachedFileStateStorages(changed: MutableCollection<String>, deleted: MutableCollection<String>) = storageLock.withLock { Couple.of(getCachedFileStorages(changed), getCachedFileStorages(deleted)) }
fun getCachedFileStorages(fileSpecs: Collection<String>): Collection<FileBasedStorage> {
fun getCachedFileStorages(fileSpecs: Collection<String>): Collection<FileStorage> {
if (fileSpecs.isEmpty()) {
return emptyList()
}
@@ -185,13 +185,7 @@ open class StateStorageManagerImpl(protected val rootTagName: String,
val file = File(filePath)
if (isUseVfsListener == ThreeState.UNSURE) {
if (streamProvider != null && streamProvider!!.enabled) {
isUseVfsListener = ThreeState.NO
}
else {
isUseVfsListener = ThreeState.YES
// addVfsChangesListener(componentManager!!)
}
isUseVfsListener = ThreeState.fromBoolean(streamProvider == null || !streamProvider!!.enabled)
}
//noinspection deprecation
@@ -207,22 +201,25 @@ open class StateStorageManagerImpl(protected val rootTagName: String,
val effectiveRoamingType = if (roamingType == RoamingType.PER_USER && fileSpec == StoragePathMacros.WORKSPACE_FILE) RoamingType.DISABLED else roamingType
val storage = MyFileStorage(this, file, fileSpec, rootTagName, effectiveRoamingType, getMacroSubstitutor(fileSpec), streamProvider)
virtualFileTracker?.put(filePath.normalizePath(), storage)
if (isUseVfsListener == ThreeState.YES) {
virtualFileTracker?.put(filePath.normalizePath(), storage)
}
return storage
}
private class MyDirectoryStorage(override val storageManager: StateStorageManagerImpl, file: File, splitter: StateSplitter) : DirectoryBasedStorage(storageManager.pathMacroSubstitutor, file, splitter), StorageVirtualFileTracker.TrackedStorage
private class MyFileStorage(override val storageManager: StateStorageManagerImpl,
file: File,
fileSpec: String,
rootElementName: String,
roamingType: RoamingType? = null,
pathMacroManager: TrackingPathMacroSubstitutor? = null,
streamProvider: StreamProvider? = null) : FileBasedStorage(file, fileSpec, roamingType, pathMacroManager, rootElementName, streamProvider), StorageVirtualFileTracker.TrackedStorage {
override fun createStorageData() = storageManager.createStorageData(myFileSpec)
file: File,
fileSpec: String,
rootElementName: String,
roamingType: RoamingType,
pathMacroManager: TrackingPathMacroSubstitutor? = null,
provider: StreamProvider? = null) : FileBasedStorage(file, fileSpec, rootElementName, pathMacroManager, roamingType, provider), StorageVirtualFileTracker.TrackedStorage {
override val isUseXmlProlog: Boolean
get() = storageManager.isUseXmlProlog
override fun isUseXmlProlog() = storageManager.isUseXmlProlog
override fun createStorageData() = storageManager.createStorageData(fileSpec)
}
private fun String.normalizePath(): String {
@@ -272,7 +269,7 @@ open class StateStorageManagerImpl(protected val rootTagName: String,
protected open fun getMacroSubstitutor(fileSpec: String): TrackingPathMacroSubstitutor? = pathMacroSubstitutor
protected open fun createStorageData(fileSpec: String): StorageData = StorageData(rootTagName)
protected open fun createStorageData(fileSpec: String): StorageData = StorageData()
override final fun expandMacros(path: String): String {
// replacement can contains $ (php tests), so, this check must be performed before expand
@@ -2,7 +2,6 @@ package com.intellij.configurationStore
import com.intellij.openapi.components.StateStorage
import com.intellij.openapi.components.impl.stores.DirectoryBasedStorage
import com.intellij.openapi.components.impl.stores.FileBasedStorage
import com.intellij.openapi.components.impl.stores.StateStorageManager
import com.intellij.openapi.components.impl.stores.StorageUtil
import com.intellij.openapi.util.text.StringUtilRt
@@ -1,46 +0,0 @@
package com.intellij.configurationStore;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.components.impl.stores.FileBasedStorage;
import com.intellij.openapi.components.impl.stores.StorageData;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
public class DefaultProjectStorage extends FileBasedStorage {
public DefaultProjectStorage(@NotNull File file, @NotNull String fileSpec, PathMacroManager pathMacroManager) {
super(file, fileSpec, RoamingType.DISABLED, pathMacroManager.createTrackingSubstitutor(), "defaultProject", null);
}
@Nullable
@Override
protected Element loadLocalData() {
Element element = super.loadLocalData();
if (element == null) {
return null;
}
try {
return element.getChild("component").getChild("defaultProject");
}
catch (NullPointerException e) {
LOG.warn("Cannot read default project");
return null;
}
}
@NotNull
@Override
protected XmlElementStorageSaveSession createSaveSession(@NotNull StorageData storageData) {
return new FileSaveSession(storageData) {
@Override
protected void doSave(@Nullable Element element) throws IOException {
super.doSave(new Element("application").addContent(new Element("component").setAttribute("name", "ProjectManager").addContent(element)));
}
};
}
}
@@ -12,11 +12,6 @@ public final class DefaultStorageAnnotation implements Storage {
return "___Default___";
}
@Override
public boolean isDefault() {
return true;
}
@Override
public String file() {
return StoragePathMacros.PROJECT_FILE;
@@ -0,0 +1,143 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.configurationStore
import com.intellij.notification.Notification
import com.intellij.notification.NotificationType
import com.intellij.notification.Notifications
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.RoamingType
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.TrackingPathMacroSubstitutor
import com.intellij.openapi.components.impl.stores.*
import com.intellij.openapi.util.JDOMUtil
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.util.io.systemIndependentPath
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.LineSeparator
import org.jdom.Element
import org.jdom.JDOMException
import java.io.File
import java.io.IOException
import java.nio.ByteBuffer
import java.nio.CharBuffer
open class FileBasedStorage(private volatile var file: File,
fileSpec: String,
rootElementName: String,
pathMacroManager: TrackingPathMacroSubstitutor? = null,
roamingType: RoamingType? = null,
provider: StreamProvider? = null) : XmlElementStorage(fileSpec, rootElementName, pathMacroManager, roamingType, provider), FileStorage {
private volatile var cachedVirtualFile: VirtualFile? = null
private var lineSeparator: LineSeparator? = null
private var blockSavingTheContent = false
init {
if (ApplicationManager.getApplication().isUnitTestMode() && file.getPath().startsWith('$')) {
throw AssertionError("It seems like some macros were not expanded for path: $file")
}
}
protected open val isUseXmlProlog: Boolean = false
// we never set io file to null
override fun setFile(virtualFile: VirtualFile?, ioFileIfChanged: File?) {
cachedVirtualFile = virtualFile
if (ioFileIfChanged != null) {
file = ioFileIfChanged
}
}
override fun createSaveSession(storageData: StorageData) = FileSaveSession(storageData, this)
protected open class FileSaveSession(storageData: StorageData, storage: FileBasedStorage) : XmlElementStorage.XmlElementStorageSaveSession<FileBasedStorage>(storageData, storage) {
override fun save() {
if (!storage.blockSavingTheContent) {
super.save()
}
}
override fun saveLocally(element: Element?) {
if (storage.lineSeparator == null) {
storage.lineSeparator = if (storage.isUseXmlProlog) LineSeparator.LF else LineSeparator.getSystemLineSeparator()
}
val virtualFile = storage.getVirtualFile()
if (element == null) {
StorageUtil.deleteFile(storage.file, this, virtualFile)
storage.cachedVirtualFile = null
}
else {
storage.cachedVirtualFile = StorageUtil.writeFile(storage.file, this, virtualFile, element, if (storage.isUseXmlProlog) storage.lineSeparator!! else LineSeparator.LF, storage.isUseXmlProlog)
}
}
}
override fun getVirtualFile(): VirtualFile? {
var result = cachedVirtualFile
if (result == null) {
result = LocalFileSystem.getInstance().findFileByIoFile(file)
cachedVirtualFile = result
}
return cachedVirtualFile
}
override fun getFile() = file
override fun loadLocalData(): Element? {
blockSavingTheContent = false
try {
val file = getVirtualFile()
if (file == null || file.isDirectory() || !file.isValid()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Document was not loaded for $fileSpec file is ${if (file == null) "null" else "directory"}")
}
}
else if (file.getLength() == 0L) {
processReadException(null)
}
else {
val charBuffer = CharsetToolkit.UTF8_CHARSET.decode(ByteBuffer.wrap(file.contentsToByteArray()))
lineSeparator = StorageUtil.detectLineSeparators(charBuffer, if (isUseXmlProlog) null else LineSeparator.LF)
return JDOMUtil.loadDocument(charBuffer).detachRootElement()
}
}
catch (e: JDOMException) {
processReadException(e)
}
catch (e: IOException) {
processReadException(e)
}
return null
}
private fun processReadException(e: Exception?) {
val contentTruncated = e == null
blockSavingTheContent = !contentTruncated && (StorageUtil.isProjectOrModuleFile(fileSpec) || fileSpec == StoragePathMacros.WORKSPACE_FILE)
if (!ApplicationManager.getApplication().isUnitTestMode() && !ApplicationManager.getApplication().isHeadlessEnvironment()) {
if (e != null) {
LOG.info(e)
}
Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Load Settings", "Cannot load settings from file '$file': ${if (contentTruncated) "content truncated" else e!!.getMessage()}\n${if (blockSavingTheContent) "Please correct the file content" else "File content will be recreated"}", NotificationType.WARNING).notify(null)
}
}
override fun toString() = file.systemIndependentPath
}
@@ -0,0 +1,202 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.configurationStore
import com.intellij.openapi.components.RoamingType
import com.intellij.openapi.components.StateStorage
import com.intellij.openapi.components.TrackingPathMacroSubstitutor
import com.intellij.openapi.components.impl.stores.*
import com.intellij.openapi.util.JDOMUtil
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
import com.intellij.util.LineSeparator
import com.intellij.util.containers.ContainerUtil
import gnu.trove.THashMap
import org.jdom.Element
import org.jdom.JDOMException
import java.io.IOException
abstract class XmlElementStorage protected constructor(protected val fileSpec: String,
protected val rootElementName: String,
protected val pathMacroSubstitutor: TrackingPathMacroSubstitutor?,
roamingType: RoamingType?,
provider: StreamProvider?) : StateStorageBase<StorageData>() {
protected val roamingType: RoamingType = roamingType ?: RoamingType.PER_USER
private val provider: StreamProvider? = if (provider == null || roamingType == RoamingType.DISABLED || !provider.isApplicable(fileSpec, this.roamingType)) null else provider
protected abstract fun loadLocalData(): Element?
override fun getStateAndArchive(storageData: StorageData, component: Any, componentName: String) = storageData.getStateAndArchive(componentName)
override fun loadData(): StorageData {
val storageData = createStorageData()
val element: Element?
// we don't use local data if has stream provider
if (provider != null && provider.enabled) {
try {
element = loadDataFromProvider()
if (element != null) {
storageData.loadState(element)
}
}
catch (e: Exception) {
LOG.error(e)
element = null
}
}
else {
element = loadLocalData()
}
if (element != null) {
storageData.loadState(element)
}
return storageData
}
throws(IOException::class, JDOMException::class)
private fun loadDataFromProvider() = JDOMUtil.load(provider!!.loadContent(fileSpec, roamingType))
private fun StorageData.loadState(element: Element) {
load(element, pathMacroSubstitutor, true)
}
protected open fun createStorageData(): StorageData = StorageData()
fun setDefaultState(element: Element) {
element.setName(rootElementName)
val storageData = createStorageData()
storageData.loadState(element)
storageDataRef.set(storageData)
}
override fun startExternalization() = if (checkIsSavingDisabled()) null else createSaveSession(getStorageData())
protected abstract fun createSaveSession(storageData: StorageData): StateStorage.ExternalizationSession
override fun analyzeExternalChangesAndUpdateIfNeed(componentNames: MutableSet<String>) {
val oldData = storageDataRef.get()
val newData = getStorageData(true)
if (oldData == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("analyzeExternalChangesAndUpdateIfNeed: old data null, load new for ${toString()}")
}
componentNames.addAll(newData.getComponentNames())
}
else {
val changedComponentNames = oldData.getChangedComponentNames(newData, pathMacroSubstitutor)
if (LOG.isDebugEnabled()) {
LOG.debug("analyzeExternalChangesAndUpdateIfNeed: changedComponentNames $changedComponentNames for ${toString()}")
}
if (!ContainerUtil.isEmpty(changedComponentNames)) {
componentNames.addAll(changedComponentNames)
}
}
}
private fun setStorageData(oldStorageData: StorageData, newStorageData: StorageData?) {
if (oldStorageData !== newStorageData && storageDataRef.getAndSet(newStorageData) !== oldStorageData) {
LOG.warn("Old storage data is not equal to current, new storage data was set anyway")
}
}
abstract class XmlElementStorageSaveSession<T : XmlElementStorage>(private val originalStorageData: StorageData, protected val storage: T) : SaveSessionBase() {
private var copiedStorageData: StorageData? = null
private val newLiveStates = THashMap<String, Element>()
override fun createSaveSession() = if (storage.checkIsSavingDisabled() || (copiedStorageData == null && !originalStorageData.isDirty())) null else this
override fun setSerializedState(component: Any, componentName: String, element: Element?) {
if (copiedStorageData == null) {
copiedStorageData = StorageData.setStateAndCloneIfNeed(componentName, element, originalStorageData, newLiveStates)
}
else {
copiedStorageData!!.setState(componentName, element, newLiveStates)
}
}
override fun save() {
var storageData = copiedStorageData
if (storageData == null) {
storageData = originalStorageData
if (!storageData.isDirty()) {
LOG.warn("Copied storage data must be not null because original storage data is not dirty")
}
}
var element = storageData.save(newLiveStates, storage.rootElementName)
if (element == null || JDOMUtil.isEmpty(element)) {
element = null
}
else if (storage.pathMacroSubstitutor != null) {
try {
storage.pathMacroSubstitutor.collapsePaths(element)
}
finally {
storage.pathMacroSubstitutor.reset()
}
}
val provider = storage.provider
if (provider != null && provider.enabled) {
if (element == null) {
provider.delete(storage.fileSpec, storage.roamingType)
}
else {
// we should use standard line-separator (\n) - stream provider can share file content on any OS
val content = StorageUtil.writeToBytes(element, "\n")
provider.saveContent(storage.fileSpec, content.getInternalBuffer(), content.size(), storage.roamingType)
}
}
else {
saveLocally(element)
}
storage.setStorageData(originalStorageData, storageData)
}
throws(IOException::class)
protected abstract fun saveLocally(element: Element?)
}
public fun updatedFromStreamProvider(changedComponentNames: MutableSet<String>, deleted: Boolean) {
if (roamingType == RoamingType.DISABLED) {
// storage roaming was changed to DISABLED, but settings repository has old state
return
}
try {
val newElement = if (deleted) null else loadDataFromProvider()
val storageData = storageDataRef.get()
if (newElement == null) {
// if data was loaded, mark as changed all loaded components
if (storageData != null) {
changedComponentNames.addAll(storageData.getComponentNames())
setStorageData(storageData, null)
}
}
else if (storageData != null) {
val newStorageData = createStorageData()
newStorageData.loadState(newElement)
changedComponentNames.addAll(storageData.getChangedComponentNames(newStorageData, pathMacroSubstitutor))
setStorageData(storageData, newStorageData)
}
}
catch (e: Throwable) {
LOG.error(e)
}
}
}
@@ -9,8 +9,6 @@ import java.io.FileInputStream
import java.io.InputStream
class MockStreamProvider(private val myBaseDir: File) : StreamProvider {
override fun isApplicable(fileSpec: String, roamingType: RoamingType) = roamingType === RoamingType.PER_USER
override fun saveContent(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
FileUtil.writeToFile(File(myBaseDir, fileSpec), content, 0, size)
}
@@ -7,7 +7,6 @@ import com.intellij.openapi.application.invokeAndWaitIfNeed
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.components.RoamingType
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.impl.stores.FileBasedStorage
import com.intellij.openapi.components.impl.stores.StoreUtil
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.module.ModifiableModuleModel
@@ -13,15 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.components.impl;
package com.intellij.configurationStore;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.util.JDOMBuilder;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.testFramework.PlatformTestCase;
@@ -35,23 +33,16 @@ public abstract class ProjectStoreBaseTestCase extends PlatformTestCase {
}
protected byte[] getIprFileContent() throws UnsupportedEncodingException {
final String iprContent = JDOMUtil.writeDocument(
JDOMBuilder.document(JDOMBuilder.tag("project",
JDOMBuilder.attr("version", "4"),
JDOMBuilder.tag("component", JDOMBuilder.attr("name", "TestIprComponent"),
JDOMBuilder.tag("option", JDOMBuilder.attr("name", "VALUE"), JDOMBuilder.attr("value", "true")))
)),
"\n");
return iprContent.getBytes(CharsetToolkit.UTF8);
return ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<project version=\"4\">" +
" <component name=\"TestComponent\">" +
" <option name=\"VALUE\" value=\"true\"/>" +
" </component>" +
"</project>").getBytes(CharsetToolkit.UTF8);
}
@State(
name = "TestIprComponent",
storages = {
@Storage(file = "$PROJECT_FILE$")
}
)
public static class TestIprComponent implements PersistentStateComponent<DataBean> {
@State(name = "TestComponent", storages = @Storage(file = "$PROJECT_FILE$"))
public static class TestComponent implements PersistentStateComponent<DataBean> {
ProjectStoreBaseTestCase.DataBean myState;
@Override
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.components.impl;
package com.intellij.configurationStore;
import com.intellij.openapi.components.ComponentsPackage;
import com.intellij.openapi.project.Project;
@@ -26,7 +26,7 @@ import java.io.IOException;
public class ProjectStoreImplIdeaDirTest extends ProjectStoreBaseTestCase {
@Override
protected File getIprFile() throws IOException {
final File projectDir = FileUtil.createTempDirectory(getTestName(true), "project");
File projectDir = FileUtil.createTempDirectory(getTestName(true), "project");
File ideaDir = new File(projectDir, Project.DIRECTORY_STORE_FOLDER);
assertTrue(ideaDir.mkdir() || ideaDir.isDirectory());
File iprFile = new File(ideaDir, "misc.xml");
@@ -39,8 +39,8 @@ public class ProjectStoreImplIdeaDirTest extends ProjectStoreBaseTestCase {
public void testLoadFromDirectoryStorage() throws Exception {
((ProjectEx)myProject).setOptimiseTestLoadSpeed(false);
final TestIprComponent testIprComponent = new TestIprComponent();
ComponentsPackage.getStateStore(myProject).initComponent(testIprComponent, false);
assertNotNull(testIprComponent.myState);
TestComponent testComponent = new TestComponent();
ComponentsPackage.getStateStore(myProject).initComponent(testComponent, false);
assertNotNull(testComponent.myState);
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.components.impl;
package com.intellij.configurationStore;
import com.intellij.openapi.components.ComponentsPackage;
import com.intellij.openapi.project.ex.ProjectEx;
@@ -34,8 +34,8 @@ public class ProjectStoreImplIprFileTest extends ProjectStoreBaseTestCase {
((ProjectEx)myProject).setOptimiseTestLoadSpeed(false);
final TestIprComponent testIprComponent = new TestIprComponent();
ComponentsPackage.getStateStore(myProject).initComponent(testIprComponent, false);
assertNotNull(testIprComponent.myState);
final TestComponent testComponent = new TestComponent();
ComponentsPackage.getStateStore(myProject).initComponent(testComponent, false);
assertNotNull(testComponent.myState);
}
}
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.configurationStore
import com.intellij.openapi.Disposable
import com.intellij.openapi.components.impl.stores.StorageData
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.JDOMBuilder.attr
import com.intellij.openapi.util.JDOMBuilder.tag
import com.intellij.testFramework.LightPlatformTestCase
import junit.framework.TestCase
import org.jdom.Element
class XmlElementStorageTest : LightPlatformTestCase() {
public fun testGetStateSucceeded() {
val storage = MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo"))))
val state = storage.getState(this, "test", javaClass<Element>(), null)
TestCase.assertNotNull(state)
TestCase.assertEquals("component", state.getName())
TestCase.assertNotNull(state.getChild("foo"))
}
public fun testGetStateNotSucceeded() {
val storage = MyXmlElementStorage(tag("root"))
val state = storage.getState(this, "test", javaClass<Element>(), null)
TestCase.assertNull(state)
}
public fun testSetStateOverridesOldState() {
val storage = MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo"))))
val newState = tag("component", attr("name", "test"), tag("bar"))
val externalizationSession = storage.startExternalization()!!
externalizationSession.setState(this, "test", newState, null)
externalizationSession.createSaveSession()!!.save()
TestCase.assertNotNull(storage.mySavedElement)
TestCase.assertNotNull(storage.mySavedElement!!.getChild("component").getChild("bar"))
TestCase.assertNull(storage.mySavedElement!!.getChild("component").getChild("foo"))
}
private class MyXmlElementStorage(private val myElement: Element) : XmlElementStorage("", "root", null, null, null) {
var mySavedElement: Element? = null
override fun loadLocalData() = myElement
override fun createSaveSession(storageData: StorageData) = object : XmlElementStorage.XmlElementStorageSaveSession<MyXmlElementStorage>(storageData, this) {
override fun saveLocally(element: Element?) {
mySavedElement = element?.clone()
}
}
}
}
@@ -18,7 +18,7 @@ import java.util.LinkedList;
/**
* @author gregsh
*/
public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser<T>> implements Iterable<T>, UserDataHolder {
public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser<T>> implements UserDataHolder {
@NotNull
public static ApiEx<PsiElement> psiApi() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package com.intellij.core;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.psi.impl.DocumentCommitProcessor;
@@ -30,6 +31,9 @@ class MockDocumentCommitProcessor extends DocumentCommitProcessor {
}
@Override
public void commitAsynchronously(@NotNull Project project, @NotNull Document document, @NonNls @NotNull Object reason) {
public void commitAsynchronously(@NotNull Project project,
@NotNull Document document,
@NonNls @NotNull Object reason,
@NotNull ModalityState currentModalityState) {
}
}
@@ -1660,7 +1660,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
if (child instanceof StartMarker && ((StartMarker)child).myDoneMarker.myCollapse) {
int lastIndex = ((StartMarker)child).myDoneMarker.myLexemeIndex;
insertLeaf(child.getTokenType(), marker.myBuilder, child.myLexemeIndex, lastIndex);
insertLeaf(child.getTokenType(), marker.myBuilder, child.myLexemeIndex, lastIndex, true);
}
else {
ensureCapacity();
@@ -1710,17 +1710,25 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private int insertLeaves(int curToken, int lastIdx, PsiBuilderImpl builder) {
lastIdx = Math.min(lastIdx, builder.myLexemeCount);
while (curToken < lastIdx) {
insertLeaf(builder.myLexTypes[curToken], builder, curToken, curToken + 1);
insertLeaf(builder.myLexTypes[curToken], builder, curToken, curToken + 1, false);
curToken++;
}
return curToken;
}
private void insertLeaf(@NotNull IElementType type, @NotNull PsiBuilderImpl builder, int startLexemeIndex, int endLexemeIndex) {
private void insertLeaf(@NotNull IElementType type,
@NotNull PsiBuilderImpl builder,
int startLexemeIndex,
int endLexemeIndex,
boolean forceInsertion) {
final int start = builder.myLexStarts[startLexemeIndex];
final int end = builder.myLexStarts[endLexemeIndex];
if (start > end || start == end && !(type instanceof ILeafElementType)) return;
/** Corresponding code for heavy tree is located in {@link com.intellij.lang.impl.PsiBuilderImpl#insertLeaves}
* and is applied only to plain lexemes */
if (start > end || !forceInsertion && start == end && !(type instanceof ILeafElementType)) {
return;
}
final Token lexeme;
if (type instanceof ILightLazyParseableElementType) {
@@ -804,6 +804,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
return myText;
}
// Breaks encapsulation, yet required for current zero-latency typing implementation.
// TODO Should be removed when we implement typing without starting write actions.
@NotNull
public ImmutableText getImmutableText() {
return myText;
}
@Override
public void addDocumentListener(@NotNull DocumentListener listener) {
@@ -17,6 +17,7 @@ package com.intellij.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -51,28 +52,34 @@ public abstract class DocumentCommitProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread");
public abstract void commitSynchronously(@NotNull Document document, @NotNull Project project);
public abstract void commitAsynchronously(@NotNull final Project project, @NotNull final Document document, @NonNls @NotNull Object reason);
public abstract void commitAsynchronously(@NotNull final Project project,
@NotNull final Document document,
@NonNls @NotNull Object reason,
@NotNull ModalityState currentModalityState);
protected static class CommitTask {
@NotNull public final Document document;
@NotNull public final Project project;
@NotNull final Document document;
@NotNull final Project project;
// when queued it's not started
// when dequeued it's started
// when failed it's canceled
@NotNull public final ProgressIndicator indicator; // progress to commit this doc under.
@NotNull public final Object reason;
@NotNull final ProgressIndicator indicator; // progress to commit this doc under.
@NotNull final Object reason;
@NotNull final ModalityState myCreationModalityState;
private final CharSequence myLastCommittedText;
public boolean removed; // task marked as removed, should be ignored.
public CommitTask(@NotNull Document document,
@NotNull Project project,
@NotNull ProgressIndicator indicator,
@NotNull Object reason) {
@NotNull Object reason,
@NotNull ModalityState currentModalityState) {
this.document = document;
this.project = project;
this.indicator = indicator;
this.reason = reason;
myCreationModalityState = currentModalityState;
myLastCommittedText = PsiDocumentManager.getInstance(project).getLastCommittedText(document);
}
@@ -157,24 +157,30 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
}
@Override
public void commitAsynchronously(@NotNull final Project project, @NotNull final Document document, @NonNls @NotNull Object reason) {
queueCommit(project, document, reason);
public void commitAsynchronously(@NotNull final Project project,
@NotNull final Document document,
@NonNls @NotNull Object reason,
@NotNull ModalityState currentModalityState) {
queueCommit(project, document, reason, currentModalityState);
}
void queueCommit(@NotNull final Project project, @NotNull final Document document, @NonNls @NotNull Object reason) {
void queueCommit(@NotNull final Project project,
@NotNull final Document document,
@NonNls @NotNull Object reason,
@NotNull ModalityState currentModalityState) {
assert !isDisposed : "already disposed";
if (!project.isInitialized()) return;
PsiFile psiFile = PsiDocumentManager.getInstance(project).getCachedPsiFile(document);
if (psiFile == null) return;
doQueue(project, document, reason);
doQueue(project, document, reason, currentModalityState);
}
private void doQueue(@NotNull Project project, @NotNull Document document, @NotNull Object reason) {
private void doQueue(@NotNull Project project, @NotNull Document document, @NotNull Object reason, @NotNull ModalityState currentModalityState) {
synchronized (documentsToCommit) {
ProgressIndicator indicator = createProgressIndicator();
CommitTask newTask = new CommitTask(document, project, indicator, reason);
CommitTask newTask = new CommitTask(document, project, indicator, reason, currentModalityState);
markRemovedFromDocsToCommit(newTask);
markRemovedCurrentTask(newTask);
@@ -358,7 +364,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
if (success) {
assert !myApplication.isDispatchThread();
myApplication.invokeLater(finishRunnable, ModalityState.NON_MODAL);
myApplication.invokeLater(finishRunnable, task.myCreationModalityState);
log("Invoked later finishRunnable", task, false, finishRunnable, indicator);
}
}
@@ -379,7 +385,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
synchronized (documentsToCommit) {
if (!success && !task.removed) { // sync commit has not intervened
// reset status for queue back successfully
doQueue(project, document, "re-added on failure");
doQueue(project, document, "re-added on failure", task.myCreationModalityState);
}
currentTask = null; // do not cancel, it's being invokeLatered
}
@@ -402,7 +408,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
}
ProgressIndicator indicator = createProgressIndicator();
CommitTask task = new CommitTask(document, project, indicator, "Sync commit");
CommitTask task = new CommitTask(document, project, indicator, "Sync commit", ModalityState.any());
synchronized (documentsToCommit) {
markRemovedFromDocsToCommit(task);
markRemovedCurrentTask(task);
@@ -529,7 +535,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
}
if (!success) {
// add document back to the queue
queueCommit(project, document, "Re-added back");
queueCommit(project, document, "Re-added back", task.myCreationModalityState);
}
}
};
@@ -42,7 +42,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.impl.source.text.BlockSupportImpl;
import com.intellij.psi.text.BlockSupport;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.*;
@@ -716,7 +715,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
commitDocument(document);
}
else if (!((DocumentEx)document).isInBulkUpdate() && myPerformBackgroundCommit) {
myDocumentCommitProcessor.commitAsynchronously(myProject, document, event);
myDocumentCommitProcessor.commitAsynchronously(myProject, document, event, ApplicationManager.getApplication().getCurrentModalityState());
}
}
else {
@@ -374,6 +374,10 @@ public class PsiManagerImpl extends PsiManagerEx {
myTreeChangePreprocessors.add(preprocessor);
}
public void removeTreeChangePreprocessor(@NotNull PsiTreeChangePreprocessor preprocessor) {
myTreeChangePreprocessors.remove(preprocessor);
}
private void fireEvent(@NotNull PsiTreeChangeEventImpl event) {
boolean isRealTreeChange = event.getCode() != PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGED
&& event.getCode() != PsiTreeChangeEventImpl.PsiEventType.BEFORE_PROPERTY_CHANGE;
@@ -77,7 +77,8 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr
@Override
public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
myModificationCount.getAndIncrement();
if (event.getParent() instanceof PsiDirectory) {
if (event.getParent() instanceof PsiDirectory
|| event.getOldParent() instanceof PsiDirectory /* move events */) {
myOutOfCodeBlockModificationCount.getAndIncrement();
}
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.smartPointers;
import com.intellij.lang.LanguageUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.util.*;
import com.intellij.psi.PsiAnchor;
import com.intellij.psi.PsiElement;
@@ -110,11 +109,11 @@ class AnchorElementInfo extends SelfElementInfo {
}
@Override
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
public void fastenBelt() {
if (getStubId() != -1) {
switchToTree();
}
super.fastenBelt(offset, cachedRangeMarker);
super.fastenBelt();
}
private void switchToTree() {
@@ -15,8 +15,6 @@
*/
package com.intellij.psi.impl.smartPointers;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Segment;
@@ -29,28 +27,13 @@ import org.jetbrains.annotations.NotNull;
/**
* User: cdr
*/
public class ClsElementInfo implements SmartPointerElementInfo {
public class ClsElementInfo extends SmartPointerElementInfo {
private final PsiAnchor.StubIndexReference myStubIndexReference;
public ClsElementInfo(@NotNull PsiAnchor.StubIndexReference stubReference) {
myStubIndexReference = stubReference;
}
@Override
public Document getDocumentToSynchronize() {
return null;
}
// before change
@Override
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
}
// after change
@Override
public void unfastenBelt(int offset) {
}
@Override
public PsiElement restoreElement() {
return myStubIndexReference.retrieve();
@@ -85,11 +68,6 @@ public class ClsElementInfo implements SmartPointerElementInfo {
return myStubIndexReference.getProject();
}
@Override
public void cleanup() {
}
@Override
public PsiFile restoreFile() {
return myStubIndexReference.getFile();
@@ -16,8 +16,6 @@
package com.intellij.psi.impl.smartPointers;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Segment;
@@ -30,7 +28,7 @@ import org.jetbrains.annotations.NotNull;
/**
* User: cdr
*/
class FileElementInfo implements SmartPointerElementInfo {
class FileElementInfo extends SmartPointerElementInfo {
protected final VirtualFile myVirtualFile;
protected final Project myProject;
protected final Language myLanguage;
@@ -48,19 +46,6 @@ class FileElementInfo implements SmartPointerElementInfo {
myLanguage = lang;
}
@Override
public Document getDocumentToSynchronize() {
return null;
}
@Override
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
}
@Override
public void unfastenBelt(int offset) {
}
@Override
public PsiElement restoreElement() {
return SelfElementInfo.restoreFileFromVirtual(myVirtualFile, myProject, myLanguage);
@@ -105,8 +90,4 @@ class FileElementInfo implements SmartPointerElementInfo {
return myProject;
}
@Override
public void cleanup() {
}
}
@@ -15,8 +15,6 @@
*/
package com.intellij.psi.impl.smartPointers;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Segment;
@@ -29,7 +27,7 @@ import org.jetbrains.annotations.NotNull;
/**
* User: cdr
*/
class HardElementInfo implements SmartPointerElementInfo {
class HardElementInfo extends SmartPointerElementInfo {
@NotNull
private final PsiElement myElement;
@NotNull
@@ -40,19 +38,6 @@ class HardElementInfo implements SmartPointerElementInfo {
myProject = project;
}
@Override
public Document getDocumentToSynchronize() {
return null;
}
@Override
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
}
@Override
public void unfastenBelt(int offset) {
}
@Override
public PsiElement restoreElement() {
return myElement;
@@ -89,8 +74,4 @@ class HardElementInfo implements SmartPointerElementInfo {
return myProject;
}
@Override
public void cleanup() {
}
}
@@ -20,7 +20,6 @@ import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.lang.Language;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ProperTextRange;
@@ -39,7 +38,7 @@ import java.util.List;
/**
* User: cdr
*/
class InjectedSelfElementInfo implements SmartPointerElementInfo {
class InjectedSelfElementInfo extends SmartPointerElementInfo {
private final SmartPsiFileRange myInjectedFileRangeInHostFile;
private final Class<? extends PsiElement> anchorClass;
private final Language anchorLanguage;
@@ -193,16 +192,6 @@ class InjectedSelfElementInfo implements SmartPointerElementInfo {
return ((SmartPsiElementPointerImpl)myHostContext).getElementInfo().getDocumentToSynchronize();
}
@Override
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarkers) {
}
@Override
public void unfastenBelt(int offset) {
}
@Override
public int elementHashCode() {
return ((SmartPsiElementPointerImpl)myHostContext).getElementInfo().elementHashCode();
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.smartPointers;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.impl.FrozenDocument;
import com.intellij.openapi.editor.impl.ManualRangeMarker;
@@ -38,7 +37,7 @@ import java.util.Set;
/**
* User: cdr
*/
public class SelfElementInfo implements SmartPointerElementInfo {
public class SelfElementInfo extends SmartPointerElementInfo {
private final VirtualFile myVirtualFile;
private final Class myType;
private final Project myProject;
@@ -81,7 +80,7 @@ public class SelfElementInfo implements SmartPointerElementInfo {
// before change
@Override
public void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers) {
public void fastenBelt() {
if (myRangeMarker != null) return; // already tracks changes
if (myPsiRange == null) return; // invalid
@@ -96,11 +95,6 @@ public class SelfElementInfo implements SmartPointerElementInfo {
setRange(myPsiRange, document);
}
// after change
@Override
public void unfastenBelt(int offset) {
}
@Override
public PsiElement restoreElement() {
Segment segment = getPsiRange();
@@ -17,7 +17,6 @@
package com.intellij.psi.impl.smartPointers;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.vfs.VirtualFile;
@@ -26,27 +25,30 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
interface SmartPointerElementInfo {
abstract class SmartPointerElementInfo {
@Nullable
Document getDocumentToSynchronize();
public Document getDocumentToSynchronize() {
return null;
}
void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers);
void unfastenBelt(int offset);
public void fastenBelt() {
}
@Nullable
PsiElement restoreElement();
public abstract PsiElement restoreElement();
PsiFile restoreFile();
public abstract PsiFile restoreFile();
int elementHashCode(); // must be immutable
boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other);
public abstract int elementHashCode(); // must be immutable
public abstract boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other);
VirtualFile getVirtualFile();
public abstract VirtualFile getVirtualFile();
@Nullable
Segment getRange();
@NotNull Project getProject();
public abstract Segment getRange();
@NotNull
public abstract Project getProject();
void cleanup();
public void cleanup() {
}
}
@@ -15,15 +15,13 @@
*/
package com.intellij.psi.impl.smartPointers;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPsiElementPointer;
import org.jetbrains.annotations.Nullable;
interface SmartPointerEx<E extends PsiElement> extends SmartPsiElementPointer<E> {
void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers);
void unfastenBelt(int offset);
void fastenBelt();
@Nullable
PsiElement getCachedElement();
}
@@ -16,12 +16,9 @@
package com.intellij.psi.impl.smartPointers;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.impl.FrozenDocument;
import com.intellij.openapi.editor.impl.ManualRangeMarker;
@@ -34,7 +31,6 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDocumentManagerBase;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.reference.SoftReference;
import com.intellij.util.ArrayUtil;
@@ -65,12 +61,10 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
private final Project myProject;
private final Key<FilePointersList> POINTERS_KEY;
private final Key<Boolean> POINTERS_ARE_FASTENED_KEY;
public SmartPointerManagerImpl(Project project) {
myProject = project;
POINTERS_KEY = Key.create("SMART_POINTERS for "+project);
POINTERS_ARE_FASTENED_KEY = Key.create("SMART_POINTERS_ARE_FASTENED for "+project);
}
private static void processQueue() {
@@ -89,50 +83,22 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
}
}
public void fastenBelts(@NotNull VirtualFile file, int offset, @Nullable RangeMarker[] cachedRangeMarkers) {
public void fastenBelts(@NotNull VirtualFile file) {
ApplicationManager.getApplication().assertIsDispatchThread();
processQueue();
synchronized (lock) {
if (getAndFasten(file)) return;
FilePointersList pointers = getPointers(file);
if (pointers != null && !pointers.isEmpty()) {
for (PointerReference ref : pointers.references) {
SmartPointerEx pointer = SoftReference.dereference(ref);
if (pointer != null) {
pointer.fastenBelt(offset, cachedRangeMarkers);
pointer.fastenBelt();
}
}
}
}
}
public void unfastenBelts(@NotNull VirtualFile file, int offset) {
ApplicationManager.getApplication().assertIsDispatchThread();
processQueue();
synchronized (lock) {
if (!getAndUnfasten(file)) return;
FilePointersList pointers = getPointers(file);
if (pointers != null && !pointers.isEmpty()) {
for (PointerReference ref : pointers.references) {
SmartPointerEx pointer = SoftReference.dereference(ref);
if (pointer != null) {
pointer.unfastenBelt(offset);
}
}
}
PsiFile psiFile = ((PsiManagerEx)PsiManager.getInstance(myProject)).getFileManager().getCachedPsiFile(file);
if (psiFile != null) {
PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(myProject);
for (DocumentWindow injectedDoc : InjectedLanguageManager.getInstance(myProject).getCachedInjectedDocuments(psiFile)) {
PsiFile injectedFile = psiDocumentManager.getPsiFile(injectedDoc);
if (injectedFile == null) continue;
unfastenBelts(injectedFile.getViewProvider().getVirtualFile(), 0);
}
}
}
}
private static final Key<Reference<SmartPointerEx>> CACHED_SMART_POINTER_KEY = Key.create("CACHED_SMART_POINTER_KEY");
@Override
@NotNull
@@ -158,11 +124,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
element.putUserData(CACHED_SMART_POINTER_KEY, new SoftReference<SmartPointerEx>(pointer));
}
else {
containingFile = containingFile == null ? element.getContainingFile() : containingFile;
synchronized (lock) {
if (containingFile != null && areBeltsFastened(containingFile.getViewProvider().getVirtualFile())) {
pointer.fastenBelt(0, null);
}
if (pointer instanceof SmartPsiElementPointerImpl) {
((SmartPsiElementPointerImpl)pointer).incrementAndGetReferenceCount(1);
}
@@ -273,20 +235,6 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
}
}
private boolean getAndFasten(@NotNull VirtualFile file) {
boolean fastened = areBeltsFastened(file);
file.putUserData(POINTERS_ARE_FASTENED_KEY, Boolean.TRUE);
return fastened;
}
private boolean getAndUnfasten(@NotNull VirtualFile file) {
boolean fastened = areBeltsFastened(file);
file.putUserData(POINTERS_ARE_FASTENED_KEY, null);
return fastened;
}
boolean areBeltsFastened(@NotNull VirtualFile file) {
return file.getUserData(POINTERS_ARE_FASTENED_KEY) == Boolean.TRUE;
}
@Override
public boolean pointToTheSameElement(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2) {
return SmartPsiElementPointerImpl.pointsToTheSameElementAs(pointer1, pointer2);
@@ -20,7 +20,6 @@ import com.intellij.lang.LanguageUtil;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
@@ -178,13 +177,8 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
}
@Override
public void unfastenBelt(int offset) {
myElementInfo.unfastenBelt(offset);
}
@Override
public void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers) {
myElementInfo.fastenBelt(offset, cachedRangeMarkers);
public void fastenBelt() {
myElementInfo.fastenBelt();
}
@NotNull
@@ -56,7 +56,7 @@ public class DuplicatesIndex extends FileBasedIndexExtension<Integer, TIntArrayL
private static boolean ourEnabledOldProfiles = false;
@NonNls public static final ID<Integer, TIntArrayList> NAME = ID.create("DuplicatesIndex");
private static final int myBaseVersion = 20;
private static final int myBaseVersion = 21;
private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
@Override
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.ui;
/**
* @author Sergey.Malenkov
*/
public enum ColorBlindness {
/**
* Lacking the long-wavelength sensitive retinal cones,
* those with this condition are unable to distinguish
* between colors in the green–yellow–red section of the spectrum.
* Protanopes are more likely to confuse
* <ul>
* <li>black with many shades of red;</li>
* <li>dark brown with dark green, dark orange and dark red;</li>
* <li>some blues with some reds, purples and dark pinks;</li>
* <li>mid-greens with some oranges.</li>
* </ul>
*/
protanopia,
/**
* Lacking the medium-wavelength sensitive retinal cones,
* those with this condition are unable to distinguish
* between colors in the green–yellow–red section of the spectrum.
* Deuteranopes are more likely to confuse
* <ul>
* <li>mid-reds with mid-greens;</li>
* <li>blue-greens with grey and mid-pinks;</li>
* <li>bright greens with yellows;</li>
* <li>pale pinks with light grey;</li>
* <li>mid-reds with mid-brown</li>
* <li>light blues with lilac.</li>
* </ul>
*/
deuteranopia,
/**
* Lacking the short-wavelength sensitive retinal cones,
* those affected see short-wavelength colors (blue, indigo and a spectral violet)
* greenish and drastically dimmed, some of these colors even as black.
* Tritanopes are more likely to confuse
* <ul>
* <li>light blues with greys;</li>
* <li>dark purples with black;</li>
* <li>mid-greens with blues;</li>
* <li>oranges with reds.</li>
* </ul>
*/
tritanopia,
/**
* Total color blindness is defined as the inability to see color.
*/
achromatopsia
}
@@ -101,6 +101,7 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
public boolean ANTIALIASING_IN_EDITOR = true;
public boolean ANTIALIASING_IN_IDE = ANTIALIASING_IN_EDITOR;
public LCDRenderingScope LCD_RENDERING_SCOPE = UIUtil.isRetina() ? LCDRenderingScope.OFF : LCDRenderingScope.IDE;
public ColorBlindness COLOR_BLINDNESS;
public boolean USE_LCD_RENDERING_IN_EDITOR = true;
public boolean MOVE_MOUSE_ON_DEFAULT_BUTTON = false;
public boolean ENABLE_ALPHA_MODE = false;
@@ -19,6 +19,7 @@
*/
package com.intellij.openapi.editor.colors.impl;
import com.intellij.ide.ui.ColorBlindness;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.editor.HighlighterColors;
import com.intellij.openapi.editor.colors.*;
@@ -70,6 +71,10 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
// version influences XML format and triggers migration
private int myVersion = CURR_VERSION;
/**
* The version from the original file.
*/
private int myOriginalVersion = CURR_VERSION;
protected Map<ColorKey, Color> myColorsMap = ContainerUtilRt.newHashMap();
protected Map<TextAttributesKey, TextAttributes> myAttributesMap = ContainerUtilRt.newHashMap();
@@ -267,8 +272,9 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
}
public void readExternal(Element parentNode) {
String blindness = Registry.stringValue("color.blindness"); // TODO: get blindness
myValueReader.setAttribute(blindness);
UISettings settings = UISettings.getInstance();
ColorBlindness blindness = settings == null ? null : settings.COLOR_BLINDNESS;
myValueReader.setAttribute(blindness == null ? null : blindness.name());
if (SCHEME_ELEMENT.equals(parentNode.getName())) {
readScheme(parentNode);
}
@@ -294,6 +300,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
}
myVersion = readVersion;
myOriginalVersion = readVersion;
String isDefaultScheme = node.getAttributeValue(DEFAULT_SCHEME_ATTR);
boolean isDefault = isDefaultScheme != null && Boolean.parseBoolean(isDefaultScheme);
if (!isDefault) {
@@ -357,6 +364,33 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
}
}
/**
* The method is called for the scheme when it is fully loaded including additional text attributes from providers.
*/
public void upgradeSchemeFromPreviousVersion() {
setUndefinedAttributesAsInheritedForVersion142();
}
/**
* Defines empty attributes with fallback (inheritance) enabled for all the attributes explicitly defined in the parent scheme since
* previously undefined attributes were treated as inherited, not taken from the parent scheme.
*/
private void setUndefinedAttributesAsInheritedForVersion142() {
if (myOriginalVersion >= 142 || myParentScheme == null) return;
if (myParentScheme instanceof AbstractColorsScheme) {
for (TextAttributesKey key : ((AbstractColorsScheme)myParentScheme).myAttributesMap.keySet()) {
TextAttributes parentAttributes = ((AbstractColorsScheme)myParentScheme).getDirectlyDefinedAttributes(key);
if (key.getFallbackAttributeKey() != null &&
parentAttributes != null &&
!parentAttributes.isFallbackEnabled() &&
!myAttributesMap.containsKey(key)) {
myAttributesMap.put(key, new TextAttributes());
}
}
}
}
@Deprecated
@SuppressWarnings("unused")
public static final Map<String, Color> DEFAULT_ERROR_STRIPE_COLOR = new THashMap<String, Color>();
@@ -28,6 +28,7 @@ import com.intellij.openapi.editor.ex.PrioritizedDocumentListener;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.HighlighterClient;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.editor.impl.EditorDocumentPriorities;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter;
@@ -37,6 +38,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import com.intellij.util.text.ImmutableText;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -351,6 +353,44 @@ public class LexerEditorHighlighter implements EditorHighlighter, PrioritizedDoc
return attrs;
}
// Called to determine visual attributes of inserted character prior to starting a write action.
// TODO Should be removed when we implement typing without starting write actions.
public TextAttributes getAttributes(DocumentImpl document, int offset, char c) {
final int segmentIndex;
try {
segmentIndex = mySegments.findSegmentIndex(offset) - 2;
}
catch (IndexOutOfBoundsException ex) {
throw new IndexOutOfBoundsException(ex.getMessage() + " Lexer: " + myLexer);
}
int startIndex = Math.max(0, segmentIndex);
int data;
do {
data = mySegments.getSegmentData(startIndex);
if (isInitialState(data)|| startIndex == 0) break;
startIndex--;
}
while (true);
int startOffset = mySegments.getSegmentStart(startIndex);
ImmutableText newText = document.getImmutableText().insert(offset, Character.toString(c));
myLexer.start(newText, startOffset, newText.length(), myInitialState);
IElementType tokenType = null;
while (myLexer.getTokenType() != null) {
if (myLexer.getTokenEnd() >= offset + 1) {
tokenType = myLexer.getTokenType();
break;
}
myLexer.advance();
}
return getAttributes(tokenType);
}
protected TextAttributes convertAttributes(@NotNull TextAttributesKey[] keys) {
TextAttributes attrs = myScheme.getAttributes(HighlighterColors.TEXT);
for (TextAttributesKey key : keys) {
@@ -25,7 +25,7 @@ import javax.swing.*;
/**
* Describes a specific way of executing any possible run configuration. The three default executors provided by the IntelliJ Platform
* by default are Run, Debug and (in IntelliJ IDEA Ultimate and certain platform-based IDEs) Run with Coverage. Each executor gets its
* by default are Run, Debug and Run with Coverage. Each executor gets its
* own toolbar button, which starts the selected run configuration using this executor, and its own context menu item for starting
* a configuration using this executor.
*
@@ -17,20 +17,16 @@ package com.intellij.psi.codeStyle;
import com.intellij.application.options.IndentOptionsEditor;
import com.intellij.lang.Language;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
@@ -189,6 +185,7 @@ public abstract class LanguageCodeStyleSettingsProvider {
return null;
}
@SuppressWarnings("unused")
public static DisplayPriority getDisplayPriority(Language language) {
LanguageCodeStyleSettingsProvider langProvider = forLanguage(language);
if (langProvider == null) return DisplayPriority.LANGUAGE_SETTINGS;
-1
View File
@@ -6,7 +6,6 @@
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSources" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<orderEntry type="module" module-name="boot" />
<orderEntry type="inheritedJdk" />

Some files were not shown because too many files have changed in this diff Show More