diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java index 8e4805b06331..aa2128858353 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java @@ -85,12 +85,12 @@ public class JavaRearranger implements Rearranger, } @Override - public boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementSettingsNode current) { + public boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementMatchCondition current) { return SUPPORTED_TYPES.contains(type); } @Override - public boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementSettingsNode current) { + public boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementMatchCondition current) { if (current == null) { return SUPPORTED_MODIFIERS.contains(modifier); } @@ -98,15 +98,15 @@ public class JavaRearranger implements Rearranger, final Ref typeRef = new Ref(); current.invite(new ArrangementSettingsNodeVisitor() { @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { - if (node.getType() == ArrangementSettingType.TYPE) { - typeRef.set(node.getValue()); + public void visit(@NotNull ArrangementAtomMatchCondition setting) { + if (setting.getType() == ArrangementSettingType.TYPE) { + typeRef.set(setting.getValue()); } } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - for (ArrangementSettingsNode n : node.getOperands()) { + public void visit(@NotNull ArrangementCompositeMatchCondition setting) { + for (ArrangementMatchCondition n : setting.getOperands()) { if (typeRef.get() != null) { return; } @@ -127,39 +127,39 @@ public class JavaRearranger implements Rearranger, @NotNull @Override - public HierarchicalArrangementSettingsNode group(@NotNull ArrangementSettingsNode node) { - final Ref result = new Ref(); + public HierarchicalArrangementConditionNode group(@NotNull ArrangementMatchCondition node) { + final Ref result = new Ref(); node.invite(new ArrangementSettingsNodeVisitor() { @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { - result.set(new HierarchicalArrangementSettingsNode(node)); + public void visit(@NotNull ArrangementAtomMatchCondition setting) { + result.set(new HierarchicalArrangementConditionNode(setting)); } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - ArrangementSettingsNode typeNode = null; - for (ArrangementSettingsNode n : node.getOperands()) { - if (n instanceof ArrangementSettingsAtomNode && ((ArrangementSettingsAtomNode)n).getType() == ArrangementSettingType.TYPE) { + public void visit(@NotNull ArrangementCompositeMatchCondition setting) { + ArrangementMatchCondition typeNode = null; + for (ArrangementMatchCondition n : setting.getOperands()) { + if (n instanceof ArrangementAtomMatchCondition && ((ArrangementAtomMatchCondition)n).getType() == ArrangementSettingType.TYPE) { typeNode = n; break; } } if (typeNode == null) { - result.set(new HierarchicalArrangementSettingsNode(node)); + result.set(new HierarchicalArrangementConditionNode(setting)); } else { - HierarchicalArrangementSettingsNode parent = new HierarchicalArrangementSettingsNode(typeNode); - ArrangementSettingsCompositeNode compositeWithoutType = new ArrangementSettingsCompositeNode(node.getOperator()); - for (ArrangementSettingsNode n : node.getOperands()) { + HierarchicalArrangementConditionNode parent = new HierarchicalArrangementConditionNode(typeNode); + ArrangementCompositeMatchCondition compositeWithoutType = new ArrangementCompositeMatchCondition(setting.getOperator()); + for (ArrangementMatchCondition n : setting.getOperands()) { if (n != typeNode) { compositeWithoutType.addOperand(n); } } if (compositeWithoutType.getOperands().size() == 1) { - parent.setChild(new HierarchicalArrangementSettingsNode(compositeWithoutType.getOperands().iterator().next())); + parent.setChild(new HierarchicalArrangementConditionNode(compositeWithoutType.getOperands().iterator().next())); } else { - parent.setChild(new HierarchicalArrangementSettingsNode(compositeWithoutType)); + parent.setChild(new HierarchicalArrangementConditionNode(compositeWithoutType)); } result.set(parent); } diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java index bfb3bea37651..06a86dafe822 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java @@ -33,7 +33,7 @@ public class MethodSignatureBackedByPsiMethod extends MethodSignatureBase { super(substitutor, parameterTypes, methodTypeParameters); myIsRaw = isRaw; if (!method.isValid()) { - LOG.error("Invalid method: "+method); + LOG.error("Invalid method: "+method, new PsiInvalidElementAccessException(method)); } myMethod = method; } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java index 7b3553044867..97ed77c7da9d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java @@ -57,7 +57,9 @@ public class PsiScopesUtil { @NotNull final PsiElement entrance, @Nullable final PsiElement maxScope, @NotNull final ResolveState state) { - LOG.assertTrue(entrance.isValid(), entrance); + if (!entrance.isValid()) { + LOG.error(new PsiInvalidElementAccessException(entrance)); + } PsiElement prevParent = entrance; PsiElement scope = entrance; diff --git a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/AbstractArrangementRuleEditingModelTest.java b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/AbstractArrangementRuleEditingModelTest.java index a2b3e0940a7d..e941823eea21 100644 --- a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/AbstractArrangementRuleEditingModelTest.java +++ b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/AbstractArrangementRuleEditingModelTest.java @@ -18,16 +18,15 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.psi.codeStyle.arrangement.JavaRearranger; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; import com.intellij.ui.treeStructure.Tree; import gnu.trove.TIntObjectHashMap; import org.jetbrains.annotations.NotNull; import org.junit.Before; import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import java.util.Arrays; @@ -55,11 +54,11 @@ public abstract class AbstractArrangementRuleEditingModelTest { myGrouper = new JavaRearranger(); } - protected void configure(@NotNull ArrangementSettingsNode settingsNode) { - myBuilder.build(settingsNode, myTree, myRoot, myGrouper, myRowMappings); + protected void configure(@NotNull ArrangementMatchCondition matchCondition) { + myBuilder.build(matchCondition, myTree, myRoot, myGrouper, myRowMappings); } - protected static ArrangementSettingsAtomNode atom(@NotNull Object condition) { + protected static ArrangementAtomMatchCondition atom(@NotNull Object condition) { final ArrangementSettingType type; if (condition instanceof ArrangementEntryType) { type = ArrangementSettingType.TYPE; @@ -70,7 +69,7 @@ public abstract class AbstractArrangementRuleEditingModelTest { else { throw new IllegalArgumentException(String.format("Unexpected condition of class %s: %s", condition.getClass(), condition)); } - return new ArrangementSettingsAtomNode(type, condition); + return new ArrangementAtomMatchCondition(type, condition); } protected void checkRows(int... rows) { diff --git a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy index 2116d05eac0b..d8b6216d5edc 100644 --- a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy +++ b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy @@ -16,7 +16,7 @@ package com.intellij.application.options.codeStyle.arrangement import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition import gnu.trove.TIntIntHashMap import org.jetbrains.annotations.NotNull import org.jetbrains.annotations.Nullable @@ -351,7 +351,7 @@ public class TreeNodeBuilder extends BuilderSupport { @Override protected Object createNode(Object name) { - def result = new ArrangementTreeNode(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, name)) + def result = new ArrangementTreeNode(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, name)) currentNode?.add(result) result } diff --git a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java index 927eaccad33b..f1e338be484a 100644 --- a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java +++ b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java @@ -15,11 +15,9 @@ */ package com.intellij.application.options.codeStyle.arrangement; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import org.junit.Test; -import javax.swing.tree.DefaultMutableTreeNode; - import static com.intellij.psi.codeStyle.arrangement.ArrangementUtil.and; import static com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType.FIELD; import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.*; @@ -33,21 +31,21 @@ public class ArrangementRuleEditingModelBuilderTest extends AbstractArrangementR @Test public void mapToTheSameLayer() { - ArrangementSettingsNode settingsNode = and(atom(PUBLIC), atom(STATIC)); - myBuilder.build(settingsNode, myTree, myRoot, myGrouper, myRowMappings); + ArrangementMatchCondition matchCondition = and(atom(PUBLIC), atom(STATIC)); + myBuilder.build(matchCondition, myTree, myRoot, myGrouper, myRowMappings); checkRows(1); ArrangementRuleEditingModel model = myRowMappings.get(1); assertTrue(model.hasCondition(PUBLIC)); assertTrue(model.hasCondition(STATIC)); assertFalse(model.hasCondition(PRIVATE)); assertEquals(1, myRoot.getChildCount()); - assertEquals(settingsNode, myRoot.getFirstChild().getBackingSetting()); + assertEquals(matchCondition, myRoot.getFirstChild().getBackingSetting()); } @Test public void splitIntoTwoLayers() { - ArrangementSettingsNode settingsNode = and(atom(FIELD), atom(PUBLIC), atom(STATIC)); - myBuilder.build(settingsNode, myTree, myRoot, myGrouper, myRowMappings); + ArrangementMatchCondition matchCondition = and(atom(FIELD), atom(PUBLIC), atom(STATIC)); + myBuilder.build(matchCondition, myTree, myRoot, myGrouper, myRowMappings); checkRows(2); diff --git a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java index d1dbdfa8a935..ad21cf70d1b3 100644 --- a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java +++ b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java @@ -15,7 +15,7 @@ */ package com.intellij.application.options.codeStyle.arrangement; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import org.junit.Test; import static com.intellij.psi.codeStyle.arrangement.ArrangementUtil.and; @@ -39,9 +39,9 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode child = myRoot.getFirstChild(); assertNotNull(child); - ArrangementSettingsNode expectedSettingsNode = and(atom(PUBLIC), atom(STATIC)); - assertEquals(expectedSettingsNode, child.getBackingSetting()); - assertEquals(expectedSettingsNode, model.getSettingsNode()); + ArrangementMatchCondition expectedMatchCondition = and(atom(PUBLIC), atom(STATIC)); + assertEquals(expectedMatchCondition, child.getBackingSetting()); + assertEquals(expectedMatchCondition, model.getMatchCondition()); } @Test @@ -54,7 +54,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule model.addAndCondition(atom(FIELD)); assertEquals(2, model.getRow()); - assertEquals(and(atom(FIELD), atom(PUBLIC)), model.getSettingsNode()); + assertEquals(and(atom(FIELD), atom(PUBLIC)), model.getMatchCondition()); ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); @@ -76,7 +76,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule assertEquals(1, myRowMappings.size()); assertSame(model, myRowMappings.get(2)); - assertEquals(and(atom(FIELD), atom(PUBLIC), atom(STATIC)), model.getSettingsNode()); + assertEquals(and(atom(FIELD), atom(PUBLIC), atom(STATIC)), model.getMatchCondition()); ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); @@ -98,7 +98,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule assertEquals(1, myRowMappings.size()); assertSame(model, myRowMappings.get(2)); - assertEquals(and(atom(FIELD), atom(STATIC)), model.getSettingsNode()); + assertEquals(and(atom(FIELD), atom(STATIC)), model.getMatchCondition()); ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); @@ -119,7 +119,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule model.removeAndCondition(atom(PUBLIC)); assertEquals(1, model.getRow()); - assertEquals(atom(FIELD), model.getSettingsNode()); + assertEquals(atom(FIELD), model.getMatchCondition()); ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); @@ -143,10 +143,10 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule modelToChange.removeAndCondition(atom(PUBLIC)); assertSame(1, modelToChange.getRow()); - assertEquals(atom(FIELD), modelToChange.getSettingsNode()); + assertEquals(atom(FIELD), modelToChange.getMatchCondition()); assertSame(3, siblingModel.getRow()); - assertEquals(and(atom(FIELD), atom(STATIC)), siblingModel.getSettingsNode()); + assertEquals(and(atom(FIELD), atom(STATIC)), siblingModel.getMatchCondition()); ArrangementTreeNode atomFieldNode = myRoot.getFirstChild(); assertNotNull(atomFieldNode); @@ -177,10 +177,10 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule assertEquals(2, myRowMappings.size()); assertSame(siblingModel, myRowMappings.get(2)); - assertEquals(and(atom(FIELD), atom(PUBLIC)), siblingModel.getSettingsNode()); + assertEquals(and(atom(FIELD), atom(PUBLIC)), siblingModel.getMatchCondition()); assertSame(modelToChange, myRowMappings.get(3)); - assertEquals(atom(FIELD), modelToChange.getSettingsNode()); + assertEquals(atom(FIELD), modelToChange.getMatchCondition()); ArrangementTreeNode compositeFieldNode = myRoot.getFirstChild(); assertNotNull(compositeFieldNode); diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java index b27b7dce8d2f..85d92f5c0e5b 100644 --- a/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java +++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java @@ -125,6 +125,7 @@ public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText getEmptyText().setText(UIBundle.message("no.patterns")); } + @NotNull @Override public StatusText getEmptyText() { return myTable.getEmptyText(); diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java index 677a3b78e61f..da899e595cf9 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java @@ -1,6 +1,7 @@ package org.jetbrains.jps.model.library; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.JpsNamedElement; import org.jetbrains.jps.model.JpsReferenceableElement; @@ -32,6 +33,10 @@ public interface JpsLibrary extends JpsNamedElement, JpsReferenceableElement getType(); + @Nullable +

+ JpsTypedLibrary

asTyped(@NotNull JpsLibraryType

type); + @NotNull JpsElement getProperties(); diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryCollection.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryCollection.java index d8e828671cd1..58f82aefb127 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryCollection.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryCollection.java @@ -22,6 +22,10 @@ public interface JpsLibraryCollection { @NotNull List getLibraries(); + @NotNull +

+ Iterable> getLibraries(@NotNull JpsLibraryType

type); + void addLibrary(@NotNull JpsLibrary library); @Nullable diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java index e2bd42d1734b..6b70b0c7f86b 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java @@ -12,21 +12,15 @@ import java.util.List; public abstract class JpsNamedElementReferenceBase> extends JpsCompositeElementBase implements JpsElementReference { private static final JpsElementChildRole> PARENT_REFERENCE_ROLE = JpsElementChildRoleBase.create("parent"); - protected final JpsElementCollectionRole myCollectionRole; protected final String myElementName; - protected JpsNamedElementReferenceBase(@NotNull JpsElementCollectionRole role, - @NotNull String elementName, - @NotNull JpsElementReference parentReference) { - super(); - myCollectionRole = role; + protected JpsNamedElementReferenceBase(@NotNull String elementName, @NotNull JpsElementReference parentReference) { myElementName = elementName; myContainer.setChild(PARENT_REFERENCE_ROLE, parentReference); } protected JpsNamedElementReferenceBase(JpsNamedElementReferenceBase original) { super(original); - myCollectionRole = original.myCollectionRole; myElementName = original.myElementName; } @@ -35,7 +29,7 @@ public abstract class JpsNamedElementReferenceBase collection = parent.getContainer().getChild(myCollectionRole); + JpsElementCollectionImpl collection = getCollection(parent); if (collection == null) return null; final List elements = collection.getElements(); @@ -50,10 +44,19 @@ public abstract class JpsNamedElementReferenceBase getCollection(@NotNull JpsCompositeElement parent); + @Nullable protected abstract T resolve(S element); public JpsElementReference getParentReference() { return myContainer.getChild(PARENT_REFERENCE_ROLE); } + + @Override + public JpsElementReference asExternal(@NotNull JpsModel model) { + model.registerExternalReference(this); + return this; + } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceImpl.java index f4ac0aff9e8a..45ebab4d6129 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceImpl.java @@ -1,6 +1,7 @@ package org.jetbrains.jps.model.impl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsCompositeElement; import org.jetbrains.jps.model.JpsElementReference; import org.jetbrains.jps.model.JpsNamedElement; @@ -9,17 +10,26 @@ import org.jetbrains.jps.model.JpsNamedElement; * @author nik */ public abstract class JpsNamedElementReferenceImpl> extends JpsNamedElementReferenceBase { + protected final JpsElementCollectionRole myCollectionRole; + protected JpsNamedElementReferenceImpl(@NotNull JpsElementCollectionRole role, @NotNull String elementName, @NotNull JpsElementReference parentReference) { - super(role, elementName, parentReference); + super(elementName, parentReference); + myCollectionRole = role; } protected JpsNamedElementReferenceImpl(JpsNamedElementReferenceImpl original) { super(original); + myCollectionRole = original.myCollectionRole; } @Override protected T resolve(T element) { return element; } + + @Nullable + protected JpsElementCollectionImpl getCollection(@NotNull JpsCompositeElement parent) { + return parent.getContainer().getChild(myCollectionRole); + } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryCollectionImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryCollectionImpl.java index a0e15de8d703..473520fd7c34 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryCollectionImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryCollectionImpl.java @@ -2,8 +2,8 @@ package org.jetbrains.jps.model.library.impl; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsElement; -import org.jetbrains.jps.model.JpsElementCollection; import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties; +import org.jetbrains.jps.model.impl.JpsElementCollectionImpl; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; @@ -15,9 +15,9 @@ import java.util.List; * @author nik */ public class JpsLibraryCollectionImpl implements JpsLibraryCollection { - private final JpsElementCollection myCollection; + private final JpsElementCollectionImpl myCollection; - public JpsLibraryCollectionImpl(JpsElementCollection collection) { + public JpsLibraryCollectionImpl(JpsElementCollectionImpl collection) { myCollection = collection; } @@ -41,6 +41,12 @@ public class JpsLibraryCollectionImpl implements JpsLibraryCollection { return myCollection.getElements(); } + @NotNull + @Override + public

Iterable> getLibraries(@NotNull JpsLibraryType

type) { + return myCollection.getElementsOfType(type); + } + @Override public void addLibrary(@NotNull JpsLibrary library) { myCollection.addChild(library); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java index 8522212542f3..80eef83ec80c 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.model.library.impl; import com.intellij.openapi.util.io.FileUtilRt; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.JpsPathUtil; import org.jetbrains.jps.model.*; import org.jetbrains.jps.model.impl.JpsElementCollectionImpl; @@ -37,6 +38,13 @@ public class JpsLibraryImpl

extends JpsNamedCompositeEleme return myLibraryType; } + @Nullable + @Override + public

JpsTypedLibrary

asTyped(@NotNull JpsLibraryType

type) { + //noinspection unchecked + return myLibraryType.equals(type) ? (JpsTypedLibrary

)this : null; + } + @NotNull @Override public P getProperties() { diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsSdkReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsSdkReferenceImpl.java index c688fc1102c0..02b224eca7b1 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsSdkReferenceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsSdkReferenceImpl.java @@ -1,10 +1,11 @@ package org.jetbrains.jps.model.library.impl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsCompositeElement; import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.JpsElementReference; -import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.impl.JpsElementCollectionImpl; import org.jetbrains.jps.model.impl.JpsNamedElementReferenceBase; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsTypedLibrary; @@ -18,10 +19,9 @@ import org.jetbrains.jps.model.library.sdk.JpsSdkType; public class JpsSdkReferenceImpl

extends JpsNamedElementReferenceBase>, JpsSdkReferenceImpl

> implements JpsSdkReference

{ private final JpsSdkType

mySdkType; - public JpsSdkReferenceImpl(@NotNull String elementName, - @NotNull JpsSdkType

sdkType, + public JpsSdkReferenceImpl(@NotNull String elementName, @NotNull JpsSdkType

sdkType, @NotNull JpsElementReference parentReference) { - super(JpsLibraryRole.LIBRARIES_COLLECTION_ROLE, elementName, parentReference); + super(elementName, parentReference); mySdkType = sdkType; } @@ -37,11 +37,7 @@ public class JpsSdkReferenceImpl

extends JpsNamedElementRe @Override protected JpsTypedLibrary> resolve(JpsLibrary element) { - if (element.getType().equals(mySdkType)) { - //noinspection unchecked - return (JpsTypedLibrary>)element; - } - return null; + return element.asTyped(mySdkType); } @NotNull @@ -50,9 +46,8 @@ public class JpsSdkReferenceImpl

extends JpsNamedElementRe return new JpsSdkReferenceImpl

(this); } - @Override - public JpsSdkReferenceImpl

asExternal(@NotNull JpsModel model) { - model.registerExternalReference(this); - return this; + @Nullable + protected JpsElementCollectionImpl getCollection(@NotNull JpsCompositeElement parent) { + return parent.getContainer().getChild(JpsLibraryRole.LIBRARIES_COLLECTION_ROLE); } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java index ff9586c49318..015d0085cafd 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java @@ -1,8 +1,6 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.JpsElementReference; -import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.impl.JpsNamedElementReferenceImpl; import org.jetbrains.jps.model.module.JpsFacet; import org.jetbrains.jps.model.module.JpsFacetReference; @@ -25,10 +23,4 @@ public class JpsFacetReferenceImpl extends JpsNamedElementReferenceImpl asExternal(@NotNull JpsModel model) { - model.registerExternalReference(this); - return this; - } } diff --git a/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java b/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java index be9cd45f81f0..864a4eff35cc 100644 --- a/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java +++ b/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java @@ -16,34 +16,56 @@ package com.intellij.psi; +import com.intellij.lang.Language; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + import java.lang.ref.SoftReference; /** * @author mike */ public class PsiInvalidElementAccessException extends RuntimeException { - private final SoftReference myElementReference; // to prevent leaks, exceptions are stored in IdeaLogger + private final SoftReference myElementReference; // to prevent leaks, since exceptions are stored in IdeaLogger public PsiInvalidElementAccessException(PsiElement element) { - super(element != null ? "Element: " + element.getClass() : "Unknown psi element"); - myElementReference = new SoftReference(element); + this(element, null, null); } public PsiInvalidElementAccessException(PsiElement element, String message) { - super(message); - myElementReference = new SoftReference(element); + this(element, message, null); } public PsiInvalidElementAccessException(PsiElement element, Throwable cause) { - super(cause); - myElementReference = new SoftReference(element); + this(element, null, cause); } public PsiInvalidElementAccessException(PsiElement element, String message, Throwable cause) { - super(message, cause); + super((element != null ? "Element: " + element.getClass() + " because: " + reason(element) : "Unknown psi element") + + (message == null ? "" : "; " + message), cause); myElementReference = new SoftReference(element); } + @NonNls + @NotNull + private static String reason(@NotNull PsiElement element){ + PsiFile file = element.getContainingFile(); + if (file == null) return element.getParent() == null ? "parent is null" : "containing file is null"; + FileViewProvider provider = file.getViewProvider(); + VirtualFile vFile = provider.getVirtualFile(); + if (!vFile.isValid()) return vFile+" is invalid"; + if (!provider.isPhysical()) return "non-physical provider"; // "dummy" file + PsiManager manager = file.getManager(); + if (manager.getProject().isDisposed()) return "project is disposed"; + Language language = file.getLanguage(); + if (language != provider.getBaseLanguage()) return "File language:"+language+" != Provider base language:"+provider.getBaseLanguage(); + + FileViewProvider provider1 = manager.findViewProvider(vFile); + if (provider != provider1) return "different providers: "+provider+"("+Integer.toHexString(System.identityHashCode(provider))+"); "+provider1+"("+Integer.toHexString(System.identityHashCode(provider1))+")"; + return "psi is outdated"; + } + public PsiElement getPsiElement() { return myElementReference.get(); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index db7dd0077e14..07e43c101e5e 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -171,19 +171,12 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF @Override public boolean isValid() { - final VirtualFile vFile = getViewProvider().getVirtualFile(); + FileViewProvider provider = getViewProvider(); + final VirtualFile vFile = provider.getVirtualFile(); if (!vFile.isValid()) return false; - if (!getViewProvider().isPhysical()) return true; // "dummy" file + if (!provider.isPhysical()) return true; // "dummy" file if (myManager.getProject().isDisposed()) return false; return isPsiUpToDate(vFile); - - //FileViewProvider viewProvider = getViewProvider(); - //if (!viewProvider.isPhysical()) return true; // "dummy" file - //final VirtualFile vFile = viewProvider.getVirtualFile(); - //if (!vFile.isValid() || !isPsiUpToDate(vFile)) return false; - //PsiManager manager = getManager(); - //boolean valid = manager != null && !manager.getProject().isDisposed(); - //return valid; } protected boolean isPsiUpToDate(@NotNull VirtualFile vFile) { diff --git a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java index 17e723a776f6..3ad3ce6a427f 100644 --- a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java +++ b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java @@ -23,12 +23,14 @@ import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.process.ProcessNotCreatedException; import com.intellij.ide.util.PropertiesComponent; import com.intellij.notification.NotificationGroup; +import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.util.ObjectUtils; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -95,7 +97,8 @@ public class ExecutionUtil { @Override public void run() { ToolWindowManager.getInstance(project).notifyByBalloon(toolWindowId, MessageType.ERROR, fullMessage, null, finalListener); - ourNotificationGroup.createNotification(title, finalDescription, NotificationType.ERROR, null).notify(project); + NotificationListener notificationListener = ObjectUtils.tryCast(finalListener, NotificationListener.class); + ourNotificationGroup.createNotification(title, finalDescription, NotificationType.ERROR, notificationListener).notify(project); } }); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java index f2da39c54bf4..5db34dc05d55 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java @@ -16,15 +16,13 @@ package com.intellij.psi.codeStyle.arrangement; import com.intellij.lang.Language; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher; import com.intellij.psi.codeStyle.arrangement.match.CompositeArrangementEntryMatcher; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNodeVisitor; +import com.intellij.psi.codeStyle.arrangement.model.*; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -116,18 +114,18 @@ public class ArrangementUtil { //region Rule composition @NotNull - public static ArrangementSettingsNode and(@NotNull ArrangementSettingsNode... nodes) { - final ArrangementSettingsCompositeNode result = new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND); + public static ArrangementMatchCondition and(@NotNull ArrangementMatchCondition... nodes) { + final ArrangementCompositeMatchCondition result = new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND); final ArrangementSettingsNodeVisitor visitor = new ArrangementSettingsNodeVisitor() { @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { + public void visit(@NotNull ArrangementAtomMatchCondition node) { result.addOperand(node); } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - if (node.getOperator() == ArrangementSettingsCompositeNode.Operator.AND) { - for (ArrangementSettingsNode operand : node.getOperands()) { + public void visit(@NotNull ArrangementCompositeMatchCondition node) { + if (node.getOperator() == ArrangementCompositeMatchCondition.Operator.AND) { + for (ArrangementMatchCondition operand : node.getOperands()) { operand.invite(this); } } @@ -136,7 +134,7 @@ public class ArrangementUtil { } } }; - for (ArrangementSettingsNode node : nodes) { + for (ArrangementMatchCondition node : nodes) { node.invite(visitor); } return result; diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsAtomNode.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementAtomMatchCondition.java similarity index 75% rename from platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsAtomNode.java rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementAtomMatchCondition.java index 22a75c58888e..1a9ddf64032f 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsAtomNode.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementAtomMatchCondition.java @@ -18,19 +18,21 @@ package com.intellij.psi.codeStyle.arrangement.model; import org.jetbrains.annotations.NotNull; /** - * // TODO den add doc + * Encapsulates a single atom match condition, e.g. 'entry type is field' or 'entry has 'static' modifier' etc. + *

+ * Not thread-safe.. * * @author Denis Zhdanov * @since 8/8/12 1:17 PM */ -public class ArrangementSettingsAtomNode implements ArrangementSettingsNode { +public class ArrangementAtomMatchCondition implements ArrangementMatchCondition { @NotNull private final ArrangementSettingType myType; @NotNull private final Object myValue; private boolean myInverted; - public ArrangementSettingsAtomNode(@NotNull ArrangementSettingType type, @NotNull Object value) { + public ArrangementAtomMatchCondition(@NotNull ArrangementSettingType type, @NotNull Object value) { myType = type; myValue = value; } @@ -75,15 +77,15 @@ public class ArrangementSettingsAtomNode implements ArrangementSettingsNode { return false; } - ArrangementSettingsAtomNode node = (ArrangementSettingsAtomNode)o; + ArrangementAtomMatchCondition setting = (ArrangementAtomMatchCondition)o; - if (myInverted != node.myInverted) { + if (myInverted != setting.myInverted) { return false; } - if (myType != node.myType) { + if (myType != setting.myType) { return false; } - if (!myValue.equals(node.myValue)) { + if (!myValue.equals(setting.myValue)) { return false; } @@ -92,8 +94,8 @@ public class ArrangementSettingsAtomNode implements ArrangementSettingsNode { @NotNull @Override - public ArrangementSettingsAtomNode clone() { - ArrangementSettingsAtomNode result = new ArrangementSettingsAtomNode(myType, myValue); + public ArrangementAtomMatchCondition clone() { + ArrangementAtomMatchCondition result = new ArrangementAtomMatchCondition(myType, myValue); result.setInverted(myInverted); return result; } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsCompositeNode.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementCompositeMatchCondition.java similarity index 67% rename from platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsCompositeNode.java rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementCompositeMatchCondition.java index c557fc8141d4..db001821090f 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsCompositeNode.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementCompositeMatchCondition.java @@ -22,26 +22,28 @@ import org.jetbrains.annotations.NotNull; import java.util.Set; /** - * // TODO den add doc + * Encapsulates composite match condition, e.g. "an entry has type 'field' and modifier 'static'". + *

+ * Thread-safe. * * @author Denis Zhdanov * @since 8/8/12 1:18 PM */ -public class ArrangementSettingsCompositeNode implements ArrangementSettingsNode { +public class ArrangementCompositeMatchCondition implements ArrangementMatchCondition { - @NotNull private final Set myOperands = new HashSet(); + @NotNull private final Set myOperands = new HashSet(); @NotNull private final Operator myOperator; - public ArrangementSettingsCompositeNode(@NotNull Operator operator) { + public ArrangementCompositeMatchCondition(@NotNull Operator operator) { myOperator = operator; } @NotNull - public Set getOperands() { + public Set getOperands() { return myOperands; } - public ArrangementSettingsCompositeNode addOperand(@NotNull ArrangementSettingsNode node) { + public ArrangementCompositeMatchCondition addOperand(@NotNull ArrangementMatchCondition node) { myOperands.add(node); return this; } @@ -55,12 +57,12 @@ public class ArrangementSettingsCompositeNode implements ArrangementSettingsNode public void invite(@NotNull ArrangementSettingsNodeVisitor visitor) { visitor.visit(this); } - + @NotNull @Override - public ArrangementSettingsCompositeNode clone() { - ArrangementSettingsCompositeNode result = new ArrangementSettingsCompositeNode(myOperator); - for (ArrangementSettingsNode operand : myOperands) { + public ArrangementCompositeMatchCondition clone() { + ArrangementCompositeMatchCondition result = new ArrangementCompositeMatchCondition(myOperator); + for (ArrangementMatchCondition operand : myOperands) { result.addOperand(operand.clone()); } return result; @@ -82,12 +84,12 @@ public class ArrangementSettingsCompositeNode implements ArrangementSettingsNode return false; } - ArrangementSettingsCompositeNode node = (ArrangementSettingsCompositeNode)o; + ArrangementCompositeMatchCondition setting = (ArrangementCompositeMatchCondition)o; - if (!myOperands.equals(node.myOperands)) { + if (!myOperands.equals(setting.myOperands)) { return false; } - if (myOperator != node.myOperator) { + if (myOperator != setting.myOperator) { return false; } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsNode.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementMatchCondition.java similarity index 71% rename from platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsNode.java rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementMatchCondition.java index a8b55607966d..a36438aac3fc 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsNode.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementMatchCondition.java @@ -15,18 +15,21 @@ */ package com.intellij.psi.codeStyle.arrangement.model; +import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher; import org.jetbrains.annotations.NotNull; /** - * // TODO den add doc + * Generic data model for {@link ArrangementEntryMatcher arrangement entry matcher}. + *

+ * Implementations of this interface are not obliged to be thread-safe. * * @author Denis Zhdanov * @since 8/8/12 11:13 AM */ -public interface ArrangementSettingsNode extends Cloneable { +public interface ArrangementMatchCondition extends Cloneable { void invite(@NotNull ArrangementSettingsNodeVisitor visitor); @NotNull - ArrangementSettingsNode clone(); + ArrangementMatchCondition clone(); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsNodeVisitor.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsNodeVisitor.java index e217ea55bea6..762834594aeb 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsNodeVisitor.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementSettingsNodeVisitor.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull; */ public interface ArrangementSettingsNodeVisitor { - void visit(@NotNull ArrangementSettingsAtomNode node); + void visit(@NotNull ArrangementAtomMatchCondition setting); - void visit(@NotNull ArrangementSettingsCompositeNode node); + void visit(@NotNull ArrangementCompositeMatchCondition setting); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/HierarchicalArrangementSettingsNode.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/HierarchicalArrangementConditionNode.java similarity index 64% rename from platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/HierarchicalArrangementSettingsNode.java rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/HierarchicalArrangementConditionNode.java index e4685197ddad..be36f853ba78 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/HierarchicalArrangementSettingsNode.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/HierarchicalArrangementConditionNode.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * {@link #getCurrent() Wraps} {@link ArrangementSettingsNode} in order to allow to build {@link #getChild() hierarchy} + * {@link #getCurrent() Wraps} {@link ArrangementMatchCondition} in order to allow to build {@link #getChild() hierarchy} * from a plain sequence of them *

* Not thread-safe. @@ -27,29 +27,29 @@ import org.jetbrains.annotations.Nullable; * @author Denis Zhdanov * @since 8/8/12 1:23 PM */ -public class HierarchicalArrangementSettingsNode { +public class HierarchicalArrangementConditionNode { - @NotNull private final ArrangementSettingsNode myCurrent; - @Nullable private HierarchicalArrangementSettingsNode myChild; + @NotNull private final ArrangementMatchCondition myCurrent; + @Nullable private HierarchicalArrangementConditionNode myChild; - public HierarchicalArrangementSettingsNode(@NotNull ArrangementSettingsNode current) { + public HierarchicalArrangementConditionNode(@NotNull ArrangementMatchCondition current) { myCurrent = current; } @NotNull - public ArrangementSettingsNode getCurrent() { + public ArrangementMatchCondition getCurrent() { return myCurrent; } @Nullable - public HierarchicalArrangementSettingsNode getChild() { + public HierarchicalArrangementConditionNode getChild() { return myChild; } - public void setChild(@Nullable HierarchicalArrangementSettingsNode child) { + public void setChild(@Nullable HierarchicalArrangementConditionNode child) { myChild = child; } - + @Override public String toString() { return myCurrent.toString(); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementMatcherSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementMatcherSettings.java index 65cc7acc3f12..af393179907c 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementMatcherSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementMatcherSettings.java @@ -15,10 +15,9 @@ */ package com.intellij.psi.codeStyle.arrangement.settings; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNodeVisitor; +import com.intellij.psi.codeStyle.arrangement.model.*; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; @@ -27,7 +26,7 @@ import java.util.List; import java.util.Set; /** - * Encapsulates information about {@link ArrangementSettingsNode standard arrangement match rule settings}. + * Encapsulates information about {@link ArrangementMatchCondition standard arrangement match rule settings}. *

* Not thread-safe. * @@ -36,23 +35,23 @@ import java.util.Set; */ public class ArrangementMatcherSettings implements Cloneable { - @NotNull private final List myConditions = new ArrayList(); - @NotNull private final Set myValues = new HashSet(); - @NotNull private final ArrangementSettingsNodeVisitor myAddVisitor = new MyAddVisitor(); - @NotNull private final ArrangementSettingsNodeVisitor myRemoveVisitor = new MyRemoveVisitor(); + @NotNull private final List myConditions = new ArrayList(); + @NotNull private final Set myValues = new HashSet(); + @NotNull private final ArrangementSettingsNodeVisitor myAddVisitor = new MyAddVisitor(); + @NotNull private final ArrangementSettingsNodeVisitor myRemoveVisitor = new MyRemoveVisitor(); @NotNull - public List getConditions() { + public List getConditions() { return myConditions; } - public boolean addCondition(@NotNull ArrangementSettingsNode condition) { + public boolean addCondition(@NotNull ArrangementMatchCondition condition) { int size = myConditions.size(); condition.invite(myAddVisitor); return myConditions.size() > size; } - public boolean removeCondition(@NotNull ArrangementSettingsNode condition) { + public boolean removeCondition(@NotNull ArrangementMatchCondition condition) { int size = myConditions.size(); condition.invite(myRemoveVisitor); return myConditions.size() < size; @@ -72,14 +71,14 @@ public class ArrangementMatcherSettings implements Cloneable { private class MyAddVisitor implements ArrangementSettingsNodeVisitor { @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { - myConditions.add(node); - myValues.add(node.getValue()); + public void visit(@NotNull ArrangementAtomMatchCondition setting) { + myConditions.add(setting); + myValues.add(setting.getValue()); } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - for (ArrangementSettingsNode n : node.getOperands()) { + public void visit(@NotNull ArrangementCompositeMatchCondition setting) { + for (ArrangementMatchCondition n : setting.getOperands()) { n.invite(this); } } @@ -87,14 +86,14 @@ public class ArrangementMatcherSettings implements Cloneable { private class MyRemoveVisitor implements ArrangementSettingsNodeVisitor { @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { - myConditions.remove(node); - myValues.remove(node.getValue()); + public void visit(@NotNull ArrangementAtomMatchCondition setting) { + myConditions.remove(setting); + myValues.remove(setting.getValue()); } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - for (ArrangementSettingsNode n : node.getOperands()) { + public void visit(@NotNull ArrangementCompositeMatchCondition setting) { + for (ArrangementMatchCondition n : setting.getOperands()) { n.invite(this); } } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementSettingsGrouper.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementSettingsGrouper.java index 33c2c671c7b7..a59529c16090 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementSettingsGrouper.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementSettingsGrouper.java @@ -15,8 +15,8 @@ */ package com.intellij.psi.codeStyle.arrangement.settings; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; -import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode; import org.jetbrains.annotations.NotNull; /** @@ -39,12 +39,12 @@ public interface ArrangementSettingsGrouper { * | * ---public---static---final * - * That means that we'll return a {@link HierarchicalArrangementSettingsNode} with condition 'type: field' and + * That means that we'll return a {@link HierarchicalArrangementConditionNode} with condition 'type: field' and * a single child node with composite 'AND' condition 'modifier: public; modifier: static; modifier: final'. * * @param node settings node which conditions should be grouped * @return grouping-aware node */ @NotNull - HierarchicalArrangementSettingsNode group(@NotNull ArrangementSettingsNode node); + HierarchicalArrangementConditionNode group(@NotNull ArrangementMatchCondition node); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementStandardSettingsAware.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementStandardSettingsAware.java index e65a07257782..8ad1ef6ae44d 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementStandardSettingsAware.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementStandardSettingsAware.java @@ -17,7 +17,7 @@ package com.intellij.psi.codeStyle.arrangement.settings; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,7 +41,7 @@ public interface ArrangementStandardSettingsAware { * (null to indicate a query if given entry type is supported in general) * @return true if given entry type is supported; false otherwise */ - boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementSettingsNode current); + boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementMatchCondition current); /** * Allows to answer if given modifier can be applied for the rule specified by the given settings node. @@ -51,7 +51,7 @@ public interface ArrangementStandardSettingsAware { * (null to indicate a query if given modifier is supported in general) * @return true if given modifier is supported; false otherwise */ - boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementSettingsNode current); + boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementMatchCondition current); /** * @return collections of mutual exclusion settings. E.g. not more than one visibility modifier can be used for a single diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/DefaultArrangementSettingsGrouper.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/DefaultArrangementSettingsGrouper.java index a7aa312165e7..a838148af10e 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/DefaultArrangementSettingsGrouper.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/DefaultArrangementSettingsGrouper.java @@ -15,8 +15,8 @@ */ package com.intellij.psi.codeStyle.arrangement.settings; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; -import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode; import org.jetbrains.annotations.NotNull; /** @@ -29,8 +29,8 @@ public class DefaultArrangementSettingsGrouper implements ArrangementSettingsGro @NotNull @Override - public HierarchicalArrangementSettingsNode group(@NotNull ArrangementSettingsNode node) { + public HierarchicalArrangementConditionNode group(@NotNull ArrangementMatchCondition node) { // Don't group. - return new HierarchicalArrangementSettingsNode(node); + return new HierarchicalArrangementConditionNode(node); } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAndNodeComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAndNodeComponent.java index a2225453c11f..cf430d4b4010 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAndNodeComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAndNodeComponent.java @@ -16,9 +16,9 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNodeVisitor; import com.intellij.ui.awt.RelativePoint; import org.jetbrains.annotations.NotNull; @@ -26,13 +26,14 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** - * {@link ArrangementNodeComponent Component} for showing {@link ArrangementSettingsCompositeNode composite nodes}. + * {@link ArrangementNodeComponent Component} for showing {@link ArrangementCompositeMatchCondition composite nodes}. *

* Not thread-safe. * @@ -45,35 +46,35 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo @NotNull private final List myComponents = new ArrayList(); - @NotNull private final ArrangementSettingsCompositeNode mySettingsNode; - @Nullable private Rectangle myScreenBounds; + @NotNull private final ArrangementCompositeMatchCondition mySetting; + @Nullable private Rectangle myScreenBounds; - public ArrangementAndNodeComponent(@NotNull ArrangementSettingsCompositeNode node, + public ArrangementAndNodeComponent(@NotNull ArrangementCompositeMatchCondition setting, @NotNull ArrangementNodeComponentFactory factory, @NotNull ArrangementNodeDisplayManager manager) { - mySettingsNode = node; + mySetting = setting; setLayout(null); int x = 0; - final Map operands = new HashMap(); + final Map operands = new HashMap(); ArrangementSettingsNodeVisitor visitor = new ArrangementSettingsNodeVisitor() { @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { + public void visit(@NotNull ArrangementAtomMatchCondition node) { operands.put(node.getValue(), node); } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - operands.put(node, node); + public void visit(@NotNull ArrangementCompositeMatchCondition node) { + operands.put(node, node); } }; - for (ArrangementSettingsNode operand : node.getOperands()) { + for (ArrangementMatchCondition operand : setting.getOperands()) { operand.invite(visitor); } - + List ordered = manager.sort(operands.keySet()); for (Object key : ordered) { - ArrangementSettingsNode operand = operands.get(key); + ArrangementMatchCondition operand = operands.get(key); assert operand != null; ArrangementNodeComponent component = factory.getComponent(operand); myComponents.add(component); @@ -87,8 +88,8 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo @NotNull @Override - public ArrangementSettingsNode getSettingsNode() { - return mySettingsNode; + public ArrangementMatchCondition getMatchCondition() { + return mySetting; } @NotNull @@ -194,6 +195,30 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo } } + @Override + public Rectangle handleMouseMove(@NotNull MouseEvent event) { + Point location = event.getLocationOnScreen(); + for (ArrangementNodeComponent component : myComponents) { + Rectangle bounds = component.getScreenBounds(); + if (bounds != null && bounds.contains(location)) { + return component.handleMouseMove(event); + } + } + return null; + } + + @Override + public void handleMouseClick(@NotNull MouseEvent event) { + Point location = event.getLocationOnScreen(); + for (ArrangementNodeComponent component : myComponents) { + Rectangle bounds = component.getScreenBounds(); + if (bounds != null && bounds.contains(location)) { + component.handleMouseClick(event); + return; + } + } + } + @Override public String toString() { return String.format("(%s)", StringUtil.join(myComponents, " and ")); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAtomNodeComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAtomNodeComponent.java index 1e2b1cf43702..02cb5ec1b63f 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAtomNodeComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementAtomNodeComponent.java @@ -15,9 +15,11 @@ */ package com.intellij.application.options.codeStyle.arrangement; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; +import com.intellij.openapi.actionSystem.impl.ActionButton; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.Consumer; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -25,9 +27,12 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.awt.event.MouseEvent; /** - * // TODO den add doc + * {@link ArrangementNodeComponent} for {@link ArrangementAtomMatchCondition} representation. + *

+ * Not thread-safe. * * @author Denis Zhdanov * @since 8/8/12 10:06 AM @@ -68,7 +73,9 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent { } }; - @NotNull private final ArrangementSettingsAtomNode mySettingsNode; + @NotNull private final ArrangementAtomMatchCondition myCondition; + @Nullable private final ActionButton myCloseButton; + @Nullable private final Consumer myCloseCallback; @Nullable private Dimension mySize; @Nullable private Rectangle myScreenBounds; @@ -76,18 +83,61 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent { private boolean myEnabled = true; private boolean mySelected; private boolean myInverted; + private boolean myCloseButtonHovered; - public ArrangementAtomNodeComponent(@NotNull ArrangementNodeDisplayManager manager, @NotNull ArrangementSettingsAtomNode node) { - mySettingsNode = node; + public ArrangementAtomNodeComponent(@NotNull ArrangementNodeDisplayManager manager, + @NotNull ArrangementAtomMatchCondition condition, + @Nullable Consumer closeCallback) + { + myCondition = condition; + myCloseCallback = closeCallback; myLabel.setHorizontalAlignment(SwingConstants.CENTER); - myLabel.setText(manager.getDisplayValue(node)); - mySize = new Dimension(manager.getMaxWidth(node.getType()), myLabel.getPreferredSize().height); + myLabel.setText(manager.getDisplayValue(condition)); + + int width = manager.getMaxWidth(condition.getType()); + int height = myLabel.getPreferredSize().height; + final ArrangementRemoveConditionAction action; + if (closeCallback == null) { + myCloseButton = null; + action = null; + } + else { + action = new ArrangementRemoveConditionAction(); + + Icon buttonIcon = action.getTemplatePresentation().getIcon(); + Dimension buttonSize = new Dimension(buttonIcon.getIconWidth(), buttonIcon.getIconHeight()); + myCloseButton = new ActionButton(action, action.getTemplatePresentation().clone(), ArrangementConstants.RULE_TREE_PLACE, buttonSize) { + @Override + protected Icon getIcon() { + return myCloseButtonHovered ? action.getTemplatePresentation().getHoveredIcon() : action.getTemplatePresentation().getIcon(); + } + }; + Dimension preferredButtonSize = myCloseButton.getPreferredSize(); + width += preferredButtonSize.width; + height = Math.max(height, preferredButtonSize.height); + } + + mySize = new Dimension(width, height); GridBagConstraints constraints = new GridBag().anchor(GridBagConstraints.CENTER).insets(0, 0, 0, 0); - JPanel labelPanel = new JPanel(new GridBagLayout()); + JPanel labelPanel = new JPanel(new GridBagLayout()) { + @Override + public void paint(Graphics g) { + Rectangle buttonBounds = getCloseButtonScreenLocation(); + if (buttonBounds != null && action != null) { + Point mouseScreenLocation = MouseInfo.getPointerInfo().getLocation(); + myCloseButtonHovered = buttonBounds.contains(mouseScreenLocation); + } + super.paint(g); + } + }; myLabel.setBackground(Color.red); labelPanel.add(myLabel, constraints); + if (myCloseButton != null) { + labelPanel.add(myCloseButton, new GridBag().anchor(GridBagConstraints.EAST).insets(0, 0, 0, 0)); + } + labelPanel.setBorder(IdeBorderFactory.createEmptyBorder(PADDING)); labelPanel.setOpaque(false); @@ -113,8 +163,8 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent { @NotNull @Override - public ArrangementSettingsAtomNode getSettingsNode() { - return mySettingsNode; + public ArrangementAtomMatchCondition getMatchCondition() { + return myCondition; } @NotNull @@ -168,6 +218,38 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent { myInverted = inverted; } + @Nullable + @Override + public Rectangle handleMouseMove(@NotNull MouseEvent event) { + Rectangle buttonBounds = getCloseButtonScreenLocation(); + if (buttonBounds == null) { + return null; + } + boolean mouseOverButton = buttonBounds.contains(event.getLocationOnScreen()); + return (mouseOverButton ^ myCloseButtonHovered) ? buttonBounds : null; + } + + @Override + public void handleMouseClick(@NotNull MouseEvent event) { + Rectangle buttonBounds = getCloseButtonScreenLocation(); + if (buttonBounds != null && buttonBounds.contains(event.getLocationOnScreen()) && myCloseCallback != null) { + myCloseCallback.consume(myCondition); + } + } + + @Nullable + private Rectangle getCloseButtonScreenLocation() { + if (myCloseButton == null || myScreenBounds == null) { + return null; + } + + Rectangle buttonBounds = myCloseButton.getBounds(); + buttonBounds = SwingUtilities.convertRectangle(myCloseButton.getParent(), buttonBounds, myRenderer); + buttonBounds.x += myScreenBounds.x; + buttonBounds.y += myScreenBounds.y; + return buttonBounds; + } + @Override public String toString() { return myLabel.getText(); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java index 169957d42119..a13ae0cdad4e 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java @@ -18,9 +18,9 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.openapi.util.Pair; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; -import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementMatcherSettings; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware; import com.intellij.util.containers.Stack; @@ -58,7 +58,7 @@ public class ArrangementConfigUtil { */ @NotNull public static Map> buildAvailableOptions(@NotNull ArrangementStandardSettingsAware filter, - @Nullable ArrangementSettingsNode settings) + @Nullable ArrangementMatchCondition settings) { Map> result = new EnumMap>(ArrangementSettingType.class); processData(filter, settings, result, ArrangementSettingType.TYPE, ArrangementEntryType.values()); @@ -67,7 +67,7 @@ public class ArrangementConfigUtil { } private static void processData(@NotNull ArrangementStandardSettingsAware filter, - @Nullable ArrangementSettingsNode settings, + @Nullable ArrangementMatchCondition settings, @NotNull Map> result, @NotNull ArrangementSettingType type, @NotNull T[] values) @@ -89,7 +89,7 @@ public class ArrangementConfigUtil { public static boolean isEnabled(@NotNull Object conditionId, @NotNull ArrangementStandardSettingsAware filter, - @Nullable ArrangementSettingsNode settings) + @Nullable ArrangementMatchCondition settings) { if (conditionId instanceof ArrangementEntryType) { return filter.isEnabled((ArrangementEntryType)conditionId, settings); @@ -121,15 +121,15 @@ public class ArrangementConfigUtil { return null; } - public static int getDepth(@NotNull HierarchicalArrangementSettingsNode node) { - HierarchicalArrangementSettingsNode child = node.getChild(); + public static int getDepth(@NotNull HierarchicalArrangementConditionNode node) { + HierarchicalArrangementConditionNode child = node.getChild(); return child == null ? 1 : 1 + getDepth(child); } @NotNull - public static HierarchicalArrangementSettingsNode getLast(@NotNull HierarchicalArrangementSettingsNode node) { - HierarchicalArrangementSettingsNode result = node; - for (HierarchicalArrangementSettingsNode child = node.getChild(); child != null; child = child.getChild()) { + public static HierarchicalArrangementConditionNode getLast(@NotNull HierarchicalArrangementConditionNode node) { + HierarchicalArrangementConditionNode result = node; + for (HierarchicalArrangementConditionNode child = node.getChild(); child != null; child = child.getChild()) { result = child; } return result; @@ -175,25 +175,25 @@ public class ArrangementConfigUtil { /** * @param uiParentNode UI tree node which should hold UI nodes created for representing given settings node; * null as an indication that we want to create a standalone nodes hierarchy - * @param settingsNode settings node which should be represented at the UI tree denoted by the given UI tree node + * @param conditionNode settings node which should be represented at the UI tree denoted by the given UI tree node * @param model tree model to use for the tree modification * @return pair {@code (bottom-most leaf node created; number of rows created)} */ @NotNull public static Pair map(@Nullable ArrangementTreeNode uiParentNode, - @NotNull HierarchicalArrangementSettingsNode settingsNode, + @NotNull HierarchicalArrangementConditionNode conditionNode, @Nullable DefaultTreeModel model) { ArrangementTreeNode uiNode = null; int rowsCreated = 0; if (uiParentNode != null && uiParentNode.getChildCount() > 0) { ArrangementTreeNode child = uiParentNode.getChildAt(uiParentNode.getChildCount() - 1); - if (settingsNode.getCurrent().equals(child.getBackingSetting())) { + if (conditionNode.getCurrent().equals(child.getBackingSetting())) { uiNode = child; } } if (uiNode == null) { - uiNode = new ArrangementTreeNode(settingsNode.getCurrent()); + uiNode = new ArrangementTreeNode(conditionNode.getCurrent()); if (uiParentNode != null) { if (model == null) { uiParentNode.add(uiNode); @@ -205,9 +205,9 @@ public class ArrangementConfigUtil { rowsCreated++; } ArrangementTreeNode leaf = uiNode; - HierarchicalArrangementSettingsNode childSettingsNode = settingsNode.getChild(); - if (childSettingsNode != null) { - Pair pair = map(uiNode, childSettingsNode, model); + HierarchicalArrangementConditionNode childConditionNode = conditionNode.getChild(); + if (childConditionNode != null) { + Pair pair = map(uiNode, childConditionNode, model); leaf = pair.first; rowsCreated += pair.second; } @@ -527,13 +527,13 @@ public class ArrangementConfigUtil { } private static boolean hasEqualSetting(@NotNull ArrangementTreeNode node1, @NotNull ArrangementTreeNode node2) { - ArrangementSettingsNode setting1 = node1.getBackingSetting(); - ArrangementSettingsNode setting2 = node2.getBackingSetting(); - if (setting1 == null) { - return setting2 == null; + ArrangementMatchCondition matchCondition1 = node1.getBackingSetting(); + ArrangementMatchCondition matchCondition2 = node2.getBackingSetting(); + if (matchCondition1 == null) { + return matchCondition2 == null; } else { - return setting1.equals(setting2); + return matchCondition1.equals(matchCondition2); } } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConstants.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConstants.java index 9540b87b87ac..1f9bd64fe144 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConstants.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConstants.java @@ -25,6 +25,7 @@ public class ArrangementConstants { @NonNls public static final String ACTION_GROUP_RULE_EDITOR_CONTEXT_MENU = "Arrangement.RuleEditor.Context.Menu"; @NonNls public static final String RULE_EDITOR_PLACE = "Arrangement.RuleEditor.Place"; + @NonNls public static final String RULE_TREE_PLACE = "Arrangement.RuleTree.Place"; private ArrangementConstants() { } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatcherRuleEditor.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatcherRuleEditor.java index 2ecdd0f355a0..0c58485438e4 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatcherRuleEditor.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatcherRuleEditor.java @@ -16,8 +16,8 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.MultiRowFlowPanel; @@ -80,7 +80,7 @@ public class ArrangementMatcherRuleEditor extends JPanel { JPanel valuesPanel = new MultiRowFlowPanel(FlowLayout.LEFT, 8, 5); for (Object value : manager.sort(values)) { - ArrangementAtomNodeComponent component = new ArrangementAtomNodeComponent(manager, new ArrangementSettingsAtomNode(key, value)); + ArrangementAtomNodeComponent component = new ArrangementAtomNodeComponent(manager, new ArrangementAtomMatchCondition(key, value), null); myComponents.put(value, component); valuesPanel.add(component.getUiComponent()); } @@ -110,7 +110,7 @@ public class ArrangementMatcherRuleEditor extends JPanel { return; } - Map> available = ArrangementConfigUtil.buildAvailableOptions(myFilter, model.getSettingsNode()); + Map> available = ArrangementConfigUtil.buildAvailableOptions(myFilter, model.getMatchCondition()); for (Collection ids : available.values()) { for (Object id : ids) { ArrangementAtomNodeComponent component = myComponents.get(id); @@ -138,30 +138,30 @@ public class ArrangementMatcherRuleEditor extends JPanel { if (component == null) { return; } - ArrangementSettingsAtomNode settingsNode = component.getSettingsNode(); - boolean remove = myModel.hasCondition(settingsNode.getValue()); + ArrangementAtomMatchCondition setting = component.getMatchCondition(); + boolean remove = myModel.hasCondition(setting.getValue()); component.setSelected(!remove); repaintComponent(component); if (remove) { - myModel.removeAndCondition(settingsNode); + myModel.removeAndCondition(setting); return; } Collection> mutexes = myFilter.getMutexes(); for (Set mutex : mutexes) { - if (!mutex.contains(settingsNode.getValue())) { + if (!mutex.contains(setting.getValue())) { continue; } for (Object key : mutex) { if (myModel.hasCondition(key)) { ArrangementAtomNodeComponent componentToDeselect = myComponents.get(key); componentToDeselect.setSelected(false); - myModel.removeAndCondition(componentToDeselect.getSettingsNode()); + myModel.removeAndCondition(componentToDeselect.getMatchCondition()); repaintComponent(componentToDeselect); } } } - myModel.addAndCondition(settingsNode); + myModel.addAndCondition(setting); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponent.java index a28c4bdc837a..994ac5a5b54c 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponent.java @@ -15,13 +15,14 @@ */ package com.intellij.application.options.codeStyle.arrangement; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import com.intellij.ui.awt.RelativePoint; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.awt.event.MouseEvent; /** * // TODO den add doc @@ -32,7 +33,7 @@ import java.awt.*; public interface ArrangementNodeComponent { @NotNull - ArrangementSettingsNode getSettingsNode(); + ArrangementMatchCondition getMatchCondition(); // TODO den add doc @NotNull @@ -54,4 +55,19 @@ public interface ArrangementNodeComponent { * @param selected flag that indicates if current component should be drawn as 'selected' */ void setSelected(boolean selected); + + /** + * Instructs current component about mose move event. + *

+ * Primary intention is to allow to react on event like 'on mouse hover' etc. We can't do that by subscribing to the + * mouse events at the {@link #getUiComponent() corresponding UI control} because it's used only as a renderer and is not put + * to the containers hierarchy, hence, doesn't receive mouse events. + * + * @param event target mouse move event + * @return bounds to be repainted (in screen coordinates) if any; null otherwise + */ + @Nullable + Rectangle handleMouseMove(@NotNull MouseEvent event); + + void handleMouseClick(@NotNull MouseEvent event); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponentFactory.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponentFactory.java index 8feeb53aaf4c..c010fa1ec589 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponentFactory.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeComponentFactory.java @@ -17,6 +17,7 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.openapi.util.Ref; import com.intellij.psi.codeStyle.arrangement.model.*; +import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; /** @@ -25,25 +26,30 @@ import org.jetbrains.annotations.NotNull; */ public class ArrangementNodeComponentFactory { - @NotNull private final ArrangementNodeDisplayManager myDisplayManager; + @NotNull private final ArrangementNodeDisplayManager myDisplayManager; + private Consumer myRemoveConditionCallback; - public ArrangementNodeComponentFactory(@NotNull ArrangementNodeDisplayManager manager) { + public ArrangementNodeComponentFactory(@NotNull ArrangementNodeDisplayManager manager, + @NotNull Consumer removeConditionCallback) + { myDisplayManager = manager; + myRemoveConditionCallback = removeConditionCallback; } @NotNull - public ArrangementNodeComponent getComponent(@NotNull ArrangementSettingsNode node) { + public ArrangementNodeComponent getComponent(@NotNull ArrangementMatchCondition node) { final Ref ref = new Ref(); node.invite(new ArrangementSettingsNodeVisitor() { @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { - ref.set(new ArrangementAtomNodeComponent(myDisplayManager, node)); + public void visit(@NotNull ArrangementAtomMatchCondition setting) { + ref.set(new ArrangementAtomNodeComponent(myDisplayManager, setting, myRemoveConditionCallback)); } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - switch (node.getOperator()) { - case AND: ref.set(new ArrangementAndNodeComponent(node, ArrangementNodeComponentFactory.this, myDisplayManager)); break; + public void visit(@NotNull ArrangementCompositeMatchCondition setting) { + switch (setting.getOperator()) { + case AND: + ref.set(new ArrangementAndNodeComponent(setting, ArrangementNodeComponentFactory.this, myDisplayManager)); break; case OR: // TODO den implement } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeDisplayManager.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeDisplayManager.java index e1cc76fa682e..e8605715854f 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeDisplayManager.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementNodeDisplayManager.java @@ -18,8 +18,8 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsRepresentationAware; import gnu.trove.TObjectIntHashMap; @@ -67,8 +67,8 @@ public class ArrangementNodeDisplayManager { } @NotNull - public String getDisplayValue(@NotNull ArrangementSettingsAtomNode node) { - return getDisplayValue(node.getValue()); + public String getDisplayValue(@NotNull ArrangementAtomMatchCondition setting) { + return getDisplayValue(setting.getValue()); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRemoveConditionAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRemoveConditionAction.java new file mode 100644 index 000000000000..f1f797c2cf03 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRemoveConditionAction.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2012 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.application.options.codeStyle.arrangement; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +import javax.swing.*; + +/** + * @author Denis Zhdanov + * @since 8/23/12 11:41 AM + */ +public class ArrangementRemoveConditionAction extends AnAction { + + private static final Icon ICON = AllIcons.Actions.CloseNew; + private static final Icon HOVER_ICON = AllIcons.Actions.CloseNewHovered; + + public ArrangementRemoveConditionAction() { + getTemplatePresentation().setIcon(ICON); + getTemplatePresentation().setHoveredIcon(HOVER_ICON); + } + + @Override + public void actionPerformed(AnActionEvent e) { + // TODO den implement + System.out.println("ArrangementRemoveConditionAction.actionPerformed()"); + } +} diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java index d6b1625ab647..4b47856a9349 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java @@ -17,15 +17,13 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import org.jetbrains.annotations.NotNull; -import javax.swing.tree.TreeNode; - /** * Combines and encapsulates information about arrangement matcher rules representation (tree nodes) and - * underlying {@link ArrangementSettingsNode data model}. + * underlying {@link ArrangementMatchCondition data model}. *

* Implementations of this interface are not obliged to be thread-safe. * @@ -35,7 +33,7 @@ import javax.swing.tree.TreeNode; public interface ArrangementRuleEditingModel { @NotNull - ArrangementSettingsNode getSettingsNode(); + ArrangementMatchCondition getMatchCondition(); /** * Allows to answer if current model has a registered condition for the given key. A key is expected to be one of the standard @@ -47,7 +45,7 @@ public interface ArrangementRuleEditingModel { */ boolean hasCondition(@NotNull Object key); - void addAndCondition(@NotNull ArrangementSettingsAtomNode node); + void addAndCondition(@NotNull ArrangementAtomMatchCondition condition); - void removeAndCondition(@NotNull ArrangementSettingsNode node); + void removeAndCondition(@NotNull ArrangementMatchCondition condition); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilder.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilder.java index a695ad19294b..0a2c9b521031 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilder.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilder.java @@ -17,8 +17,8 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.openapi.util.Pair; import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; -import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementSettingsGrouper; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsRepresentationAware; import gnu.trove.TIntObjectHashMap; @@ -31,7 +31,7 @@ import javax.swing.tree.TreeNode; /** * Holds glue logic between arrangement settings and their representation - - * '{@link ArrangementSettingsNode} -> {@link ArrangementRuleEditingModel}' + * '{@link ArrangementMatchCondition} -> {@link ArrangementRuleEditingModel}' *

* Thread-safe. * @@ -45,11 +45,11 @@ public class ArrangementRuleEditingModelBuilder { *

    * 
    *
  1. - * {@link HierarchicalArrangementSettingsNode Groups} given {@link ArrangementSettingsNode settings} using - * the given {@link ArrangementSettingsGrouper#group(ArrangementSettingsNode) strategy}; + * {@link HierarchicalArrangementConditionNode Groups} given {@link ArrangementMatchCondition settings} using + * the given {@link ArrangementSettingsGrouper#group(ArrangementMatchCondition) strategy}; *
  2. *
  3. - * Build {@link DefaultMutableTreeNode tree nodes} for the {@link HierarchicalArrangementSettingsNode groiping-aware nodes} + * Build {@link DefaultMutableTreeNode tree nodes} for the {@link HierarchicalArrangementConditionNode groiping-aware nodes} * and register them within the target tree structure (denoted by the given settings root element); *
  4. *
  5. @@ -58,7 +58,7 @@ public class ArrangementRuleEditingModelBuilder { *
*
* - * @param setting target settings to process + * @param matchCondition target settings to process * @param tree UI tree which shows arrangement matcher rules * @param root UI tree settings root to use (may be not the same as the tree root) * @param grouper strategy that knows how to @@ -67,7 +67,7 @@ public class ArrangementRuleEditingModelBuilder { * @param rowMappings container to hold built {@link ArrangementRuleEditingModel editing models} (UI tree row numbers are used as keys) */ @SuppressWarnings("MethodMayBeStatic") - public void build(@NotNull ArrangementSettingsNode setting, + public void build(@NotNull ArrangementMatchCondition matchCondition, @NotNull JTree tree, @NotNull ArrangementTreeNode root, @NotNull ArrangementSettingsGrouper grouper, @@ -92,14 +92,14 @@ public class ArrangementRuleEditingModelBuilder { initialInsertRow--; } - HierarchicalArrangementSettingsNode grouped = grouper.group(setting); + HierarchicalArrangementConditionNode grouped = grouper.group(matchCondition); DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel(); Pair pair = ArrangementConfigUtil.map(root, grouped, treeModel); ArrangementTreeNode topMostNode = ArrangementConfigUtil.getLastBefore(pair.first, root); int row = initialInsertRow + pair.second - 1; ArrangementRuleEditingModelImpl model = new ArrangementRuleEditingModelImpl( treeModel, - setting, + matchCondition, topMostNode, pair.first, grouper, diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java index 82c8d8c917f8..f635804743b0 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java @@ -41,14 +41,14 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo @NotNull private final Set myListeners = new HashSet(); @NotNull private final Set myConditions = new HashSet(); - @NotNull private final DefaultTreeModel myTreeModel; - @NotNull private final ArrangementSettingsGrouper myGrouper; - private final boolean myRootVisible; + @NotNull private final DefaultTreeModel myTreeModel; + @NotNull private final ArrangementSettingsGrouper myGrouper; + private final boolean myRootVisible; - @NotNull private ArrangementTreeNode myTopMost; - @NotNull private ArrangementTreeNode myBottomMost; - @NotNull private ArrangementSettingsNode mySettingsNode; - private int myRow; + @NotNull private ArrangementTreeNode myTopMost; + @NotNull private ArrangementTreeNode myBottomMost; + @NotNull private ArrangementMatchCondition myMatchCondition; + private int myRow; /** * Creates new ArrangementRuleEditingModelImpl object. @@ -57,7 +57,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo * to generate corresponding events automatically * @param node backing settings node * @param topMost there is a possible case that a single settings node is shown in more than one visual line - * ({@link HierarchicalArrangementSettingsNode}). This argument is the top-most UI node used for the + * ({@link HierarchicalArrangementConditionNode}). This argument is the top-most UI node used for the * settings node representation * @param bottomMost bottom-most UI node used for the given settings node representation * @param grouper strategy that encapsulates information on how settings node should be displayed @@ -65,7 +65,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo * @param rootVisible determines if the root should be count during rows calculations */ public ArrangementRuleEditingModelImpl(@NotNull DefaultTreeModel model, - @NotNull ArrangementSettingsNode node, + @NotNull ArrangementMatchCondition node, @NotNull ArrangementTreeNode topMost, @NotNull ArrangementTreeNode bottomMost, @NotNull ArrangementSettingsGrouper grouper, @@ -73,7 +73,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo boolean rootVisible) { myTreeModel = model; - mySettingsNode = node; + myMatchCondition = node; myTopMost = topMost; myBottomMost = bottomMost; myGrouper = grouper; @@ -86,7 +86,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo myConditions.clear(); CONDITIONS_BUILDER.conditions = myConditions; try { - mySettingsNode.invite(CONDITIONS_BUILDER); + myMatchCondition.invite(CONDITIONS_BUILDER); } finally { CONDITIONS_BUILDER.conditions = null; @@ -95,8 +95,8 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo @NotNull @Override - public ArrangementSettingsNode getSettingsNode() { - return mySettingsNode; + public ArrangementMatchCondition getMatchCondition() { + return myMatchCondition; } public int getRow() { @@ -129,8 +129,8 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo // No refresh is necessary. return; } - ArrangementSettingsNode setting = myTopMost.getBackingSetting(); - if (setting != null && setting.equals(node.getBackingSetting())) { + ArrangementMatchCondition matchCondition = myTopMost.getBackingSetting(); + if (matchCondition != null && matchCondition.equals(node.getBackingSetting())) { myTopMost = node; return; } @@ -139,45 +139,45 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo } @Override - public void addAndCondition(@NotNull ArrangementSettingsAtomNode node) { - TIntIntHashMap rowChanges = doAddAndCondition(node); + public void addAndCondition(@NotNull ArrangementAtomMatchCondition condition) { + TIntIntHashMap rowChanges = doAddAndCondition(condition); refreshConditions(); notifyListeners(rowChanges); } @NotNull - private TIntIntHashMap doAddAndCondition(@NotNull ArrangementSettingsAtomNode node) { - ArrangementSettingsNode newNode = ArrangementUtil.and(mySettingsNode.clone(), node); - return applyNewSetting(newNode); + private TIntIntHashMap doAddAndCondition(@NotNull ArrangementAtomMatchCondition condition) { + ArrangementMatchCondition newNode = ArrangementUtil.and(myMatchCondition.clone(), condition); + return applyNewCondition(newNode); } @Override - public void removeAndCondition(@NotNull ArrangementSettingsNode node) { - TIntIntHashMap rowChanges = doRemoveAndCondition(node); + public void removeAndCondition(@NotNull ArrangementMatchCondition condition) { + TIntIntHashMap rowChanges = doRemoveAndCondition(condition); refreshConditions(); notifyListeners(rowChanges); } @NotNull - private TIntIntHashMap doRemoveAndCondition(@NotNull ArrangementSettingsNode node) { - if (!(mySettingsNode instanceof ArrangementSettingsCompositeNode)) { + private TIntIntHashMap doRemoveAndCondition(@NotNull ArrangementMatchCondition node) { + if (!(myMatchCondition instanceof ArrangementCompositeMatchCondition)) { return EMPTY_CHANGES; } - ArrangementSettingsNode newNode = mySettingsNode.clone(); - ArrangementSettingsCompositeNode composite = (ArrangementSettingsCompositeNode)newNode; + ArrangementMatchCondition newNode = myMatchCondition.clone(); + ArrangementCompositeMatchCondition composite = (ArrangementCompositeMatchCondition)newNode; composite.getOperands().remove(node); if (composite.getOperands().size() == 1) { newNode = composite.getOperands().iterator().next(); } - return applyNewSetting(newNode); + return applyNewCondition(newNode); } @NotNull - private TIntIntHashMap applyNewSetting(@NotNull ArrangementSettingsNode newNode) { - mySettingsNode = newNode; - HierarchicalArrangementSettingsNode grouped = myGrouper.group(newNode); + private TIntIntHashMap applyNewCondition(@NotNull ArrangementMatchCondition newNode) { + myMatchCondition = newNode; + HierarchicalArrangementConditionNode grouped = myGrouper.group(newNode); int newDepth = ArrangementConfigUtil.getDepth(grouped); int oldDepth = ArrangementConfigUtil.distance(myTopMost, myBottomMost); if (oldDepth == newDepth) { @@ -210,7 +210,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo @Override public String toString() { - return "model for " + mySettingsNode; + return "model for " + myMatchCondition; } private static class MyConditionsBuilder implements ArrangementSettingsNodeVisitor { @@ -218,13 +218,13 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo @NotNull Set conditions; @Override - public void visit(@NotNull ArrangementSettingsAtomNode node) { - conditions.add(node.getValue()); + public void visit(@NotNull ArrangementAtomMatchCondition setting) { + conditions.add(setting.getValue()); } @Override - public void visit(@NotNull ArrangementSettingsCompositeNode node) { - for (ArrangementSettingsNode operand : node.getOperands()) { + public void visit(@NotNull ArrangementCompositeMatchCondition setting) { + for (ArrangementMatchCondition operand : setting.getOperands()) { operand.invite(this); } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java index 29ed01a786ad..bebbc4a502b1 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java @@ -17,13 +17,13 @@ package com.intellij.application.options.codeStyle.arrangement; import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType; import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.*; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import com.intellij.psi.codeStyle.arrangement.settings.ArrangementSettingsGrouper; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.Consumer; import gnu.trove.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -67,7 +67,12 @@ public class ArrangementRuleTree { private boolean mySkipSelectionChange; public ArrangementRuleTree(@NotNull ArrangementSettingsGrouper grouper, @NotNull ArrangementNodeDisplayManager displayManager) { - myFactory = new ArrangementNodeComponentFactory(displayManager); + myFactory = new ArrangementNodeComponentFactory(displayManager, new Consumer() { + @Override + public void consume(@NotNull ArrangementAtomMatchCondition setting) { + removeConditionFromActiveModel(setting); + } + }); myRoot = new ArrangementTreeNode(null); myTreeModel = new DefaultTreeModel(myRoot); myTree = new Tree(myTreeModel) { @@ -117,6 +122,12 @@ public class ArrangementRuleTree { } } }); + myTree.addMouseMotionListener(new MouseAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + onMouseMoved(e); + } + }); myTree.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { @@ -138,28 +149,28 @@ public class ArrangementRuleTree { } }); - List rules = new ArrayList(); - rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD)) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC)) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.STATIC)) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.FINAL))); - rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD)) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE))); - rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD)) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC))); - rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD)) - .addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE))); + List rules = new ArrayList(); + rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD)) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC)) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.STATIC)) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.FINAL))); + rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD)) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE))); + rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD)) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC))); + rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD)) + .addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE))); map(myRoot, rules, grouper); expandAll(myTree, new TreePath(myRoot)); myTree.setShowsRootHandles(false); myTree.setCellRenderer(new MyCellRenderer()); } - + private void selectPreviousRule() { ArrangementTreeNode currentSelectionBottom = getCurrentSelectionBottom(); @@ -282,12 +293,12 @@ public class ArrangementRuleTree { } private void map(@NotNull ArrangementTreeNode root, - @NotNull List settings, + @NotNull List matchConditions, @NotNull ArrangementSettingsGrouper grouper) { ArrangementRuleEditingModelBuilder builder = new ArrangementRuleEditingModelBuilder(); - for (ArrangementSettingsNode setting : settings) { - builder.build(setting, myTree, root, grouper, myModels); + for (ArrangementMatchCondition matchCondition : matchConditions) { + builder.build(matchCondition, myTree, root, grouper, myModels); } myModels.forEachValue(new TObjectProcedure() { @Override @@ -330,7 +341,7 @@ public class ArrangementRuleTree { } @NotNull - private ArrangementNodeComponent getNodeComponentAt(int row, @NotNull ArrangementSettingsNode node) { + private ArrangementNodeComponent getNodeComponentAt(int row, @NotNull ArrangementMatchCondition node) { ArrangementNodeComponent result = myRenderers.get(row); if (result == null) { myRenderers.put(row, result = myFactory.getComponent(node)); @@ -338,9 +349,29 @@ public class ArrangementRuleTree { return result; } + private void removeConditionFromActiveModel(@NotNull ArrangementAtomMatchCondition condition) { + ArrangementRuleEditingModel model = getActiveModel(); + if (model != null) { + model.removeAndCondition(condition); + notifySelectionListeners(model); + } + } + + private void onMouseMoved(@NotNull MouseEvent e) { + ArrangementNodeComponent component = getNodeComponentAt(e.getLocationOnScreen()); + if (component == null) { + return; + } + Rectangle changedScreenRectangle = component.handleMouseMove(e); + if (changedScreenRectangle != null) { + repaintScreenBounds(changedScreenRectangle); + } + } + private void onMouseClicked(@NotNull MouseEvent e) { ArrangementNodeComponent component = getNodeComponentAt(e.getLocationOnScreen()); if (component != null) { + component.handleMouseClick(e); return; } // Clear selection @@ -381,12 +412,16 @@ public class ArrangementRuleTree { private void repaintComponent(@NotNull ArrangementNodeComponent component) { Rectangle bounds = component.getScreenBounds(); if (bounds != null) { - Point location = bounds.getLocation(); - SwingUtilities.convertPointFromScreen(location, myTree); - myTree.repaint(location.x, location.y, bounds.width, bounds.height); + repaintScreenBounds(bounds); } } + private void repaintScreenBounds(@NotNull Rectangle bounds) { + Point location = bounds.getLocation(); + SwingUtilities.convertPointFromScreen(location, myTree); + myTree.repaint(location.x, location.y, bounds.width, bounds.height); + } + private void notifySelectionListeners(@Nullable ArrangementRuleEditingModel model) { for (ArrangementRuleSelectionListener listener : myListeners) { if (model == null) { @@ -437,9 +472,9 @@ public class ArrangementRuleTree { myRenderers.remove(row); myTreeModel.nodeChanged(node); mySelectionModel.addSelectionPath(path); - ArrangementSettingsNode setting = node.getBackingSetting(); - if (setting != null) { - getNodeComponentAt(row, setting).setSelected(true); + ArrangementMatchCondition matchCondition = node.getBackingSetting(); + if (matchCondition != null) { + getNodeComponentAt(row, matchCondition).setSelected(true); } if (node == topMost) { break; @@ -471,7 +506,7 @@ public class ArrangementRuleTree { int row, boolean hasFocus) { - ArrangementSettingsNode node = ((ArrangementTreeNode)value).getBackingSetting(); + ArrangementMatchCondition node = ((ArrangementTreeNode)value).getBackingSetting(); if (node == null) { return EMPTY_RENDERER; } @@ -532,7 +567,7 @@ public class ArrangementRuleTree { } } - private class MyModelNodesRefresher implements TObjectProcedure { + private static class MyModelNodesRefresher implements TObjectProcedure { @Override public boolean execute(ArrangementRuleEditingModelImpl model) { model.refreshTreeNodes(); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java index 05ffd8c8e97c..4e07dd18e0dd 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java @@ -15,7 +15,7 @@ */ package com.intellij.application.options.codeStyle.arrangement; -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,31 +31,31 @@ public class ArrangementTreeNode extends DefaultMutableTreeNode { private static final int NO_ROW = -1; - @Nullable private ArrangementSettingsNode mySettings; - private int myRow; + @Nullable private ArrangementMatchCondition mySettings; + private int myRow; - public ArrangementTreeNode(@Nullable ArrangementSettingsNode settings) { + public ArrangementTreeNode(@Nullable ArrangementMatchCondition settings) { this(settings, NO_ROW); } - public ArrangementTreeNode(@Nullable ArrangementSettingsNode settings, int row) { + public ArrangementTreeNode(@Nullable ArrangementMatchCondition settings, int row) { mySettings = settings; myRow = row; } @Nullable - public ArrangementSettingsNode getBackingSetting() { + public ArrangementMatchCondition getBackingSetting() { return mySettings; } - public void setSettings(@Nullable ArrangementSettingsNode settings) { + public void setSettings(@Nullable ArrangementMatchCondition settings) { mySettings = settings; } public boolean isRowSet() { return myRow >= 0; } - + public int getRow() { return myRow; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java index 251826959233..c05717effe26 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java @@ -179,6 +179,7 @@ public class HighlightUsagesHandler extends HighlightHandlerBase { } final EditorSearchComponent header = new EditorSearchComponent(editor, project); + header.setRegexp(false); editor.setHeaderComponent(header); } diff --git a/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java b/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java index 8781caf416e3..2282bba0cb9d 100644 --- a/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java +++ b/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java @@ -74,4 +74,6 @@ public interface ModuleSettings extends ComponentManagerSettings { boolean hasModuleLibrary(String libraryName); List getOrderEntries(); + + void addFacetElement(@NotNull String facetTypeId, @NotNull String facetName, Element configuration); } diff --git a/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java b/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java index bb832d69e40f..d728978ac329 100644 --- a/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java +++ b/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java @@ -32,6 +32,7 @@ import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.serialization.JDomSerializationUtil; import org.jetbrains.jps.model.serialization.facet.JpsFacetSerializer; import java.io.File; @@ -83,6 +84,17 @@ public class ModuleSettingsImpl extends ComponentManagerSettingsImpl implements return ContainerUtil.getFirstItem(getFacetElements(facetTypeId), null); } + @Override + public void addFacetElement(@NotNull String facetTypeId, @NotNull String facetName, Element configuration) { + Element componentElement = JDomSerializationUtil.findOrCreateComponentElement(getRootElement(), FacetManagerImpl.COMPONENT_NAME); + Element facetElement = new Element(JpsFacetSerializer.FACET_TAG); + facetElement.setAttribute(JpsFacetSerializer.TYPE_ATTRIBUTE, facetTypeId); + facetElement.setAttribute(JpsFacetSerializer.NAME_ATTRIBUTE, facetName); + configuration.setName(JpsFacetSerializer.CONFIGURATION_TAG); + facetElement.addContent(configuration); + componentElement.addContent(facetElement); + } + public void setModuleType(@NotNull String moduleType) { getRootElement().setAttribute(ModuleImpl.ELEMENT_TYPE, moduleType); } diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java index 3a5151133a89..3fe09e6dbb6b 100644 --- a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java @@ -404,7 +404,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L LOG.assertTrue(editor != null); final Document document = editor.getDocument(); final int caretOffset = editor.getCaretModel().getOffset(); - if (caretOffset > -1) { + if (caretOffset > -1 && caretOffset < document.getTextLength()) { int line; try { line = document.getLineNumber(caretOffset); diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionTargetManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ExecutionTargetManagerImpl.java index bd72ec8d9ce8..fdf08f10cf6a 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutionTargetManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionTargetManagerImpl.java @@ -128,6 +128,7 @@ public class ExecutionTargetManagerImpl extends ExecutionTargetManager implement private void updateActiveTarget(@Nullable RunnerAndConfigurationSettings settings, @Nullable ExecutionTarget toSelect) { List suitable = settings == null ? Collections.singletonList(DefaultExecutionTarget.INSTANCE) : getTargetsFor(settings); + ExecutionTarget toNotify = null; synchronized (myActiveTargetLock) { if (toSelect == null) toSelect = myActiveTarget; @@ -143,18 +144,25 @@ public class ExecutionTargetManagerImpl extends ExecutionTargetManager implement } } } - doSetActiveTarget(index >= 0 ? suitable.get(index) : ContainerUtil.getFirstItem(suitable, DefaultExecutionTarget.INSTANCE)); + toNotify = + doSetActiveTarget(index >= 0 ? suitable.get(index) : ContainerUtil.getFirstItem(suitable, DefaultExecutionTarget.INSTANCE)); + } + + if (toNotify != null) { + myProject.getMessageBus().syncPublisher(TOPIC).activeTargetChanged(toNotify); } } - private void doSetActiveTarget(@NotNull ExecutionTarget newTarget) { + @Nullable + private ExecutionTarget doSetActiveTarget(@NotNull ExecutionTarget newTarget) { mySavedActiveTargetId = null; ExecutionTarget prev = myActiveTarget; myActiveTarget = newTarget; if (prev != null && !prev.equals(myActiveTarget)) { - myProject.getMessageBus().syncPublisher(TOPIC).activeTargetChanged(myActiveTarget); + return myActiveTarget; } + return null; } @NotNull diff --git a/platform/platform-api/src/com/intellij/ui/AddDeleteListPanel.java b/platform/platform-api/src/com/intellij/ui/AddDeleteListPanel.java index c82465e1bfa8..aa3c6ba38232 100644 --- a/platform/platform-api/src/com/intellij/ui/AddDeleteListPanel.java +++ b/platform/platform-api/src/com/intellij/ui/AddDeleteListPanel.java @@ -20,6 +20,7 @@ import com.intellij.CommonBundle; import com.intellij.ui.components.JBList; import com.intellij.util.ui.ComponentWithEmptyText; import com.intellij.util.ui.StatusText; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -82,6 +83,7 @@ public abstract class AddDeleteListPanel extends PanelWithButtons implements protected void customizeDecorator(ToolbarDecorator decorator) { } + @NotNull @Override public StatusText getEmptyText() { return myList.getEmptyText(); diff --git a/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java b/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java index 3bed40836387..fdf2ca71712e 100644 --- a/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java +++ b/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java @@ -19,6 +19,7 @@ import com.intellij.ui.table.JBTable; import com.intellij.util.ui.ComponentWithEmptyText; import com.intellij.util.ui.StatusText; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -102,6 +103,7 @@ public abstract class AddEditRemovePanel extends PanelWithButtons implements return myLabel; } + @NotNull @Override public StatusText getEmptyText() { return myTable.getEmptyText(); diff --git a/platform/platform-api/src/com/intellij/ui/ComponentWithExpandableItems.java b/platform/platform-api/src/com/intellij/ui/ComponentWithExpandableItems.java index ce95c4afe02c..38799d485317 100644 --- a/platform/platform-api/src/com/intellij/ui/ComponentWithExpandableItems.java +++ b/platform/platform-api/src/com/intellij/ui/ComponentWithExpandableItems.java @@ -20,4 +20,6 @@ import org.jetbrains.annotations.NotNull; public interface ComponentWithExpandableItems { @NotNull ExpandableItemsHandler getExpandableItemsHandler(); + + void setExpandableItemsEnabled(boolean enabled); } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java b/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java new file mode 100644 index 000000000000..4e6d1c5c3f41 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2012 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.ui; + +import com.intellij.util.ui.AbstractLayoutManager; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; + +public class ExpandedItemRendererComponentWrapper extends JComponent { + public ExpandedItemRendererComponentWrapper(@NotNull final Component rendererComponent) { + add(rendererComponent); + setOpaque(false); + setLayout(new AbstractLayoutManager() { + @Override + public Dimension preferredLayoutSize(Container parent) { + return rendererComponent.getPreferredSize(); + } + + @Override + public void layoutContainer(Container parent) { + Dimension size = parent.getSize(); + Insets i = parent.getInsets(); + Dimension pref = rendererComponent.getPreferredSize(); + rendererComponent.setBounds(i.left, i.top, Math.max(pref.width, size.width - i.left - i.right), size.height - i.top - i.bottom); + } + }); + } +} diff --git a/platform/platform-api/src/com/intellij/ui/OptionalChooserComponent.java b/platform/platform-api/src/com/intellij/ui/OptionalChooserComponent.java index edfa1568db42..6aa9085e8e25 100644 --- a/platform/platform-api/src/com/intellij/ui/OptionalChooserComponent.java +++ b/platform/platform-api/src/com/intellij/ui/OptionalChooserComponent.java @@ -43,6 +43,7 @@ public abstract class OptionalChooserComponent implements CheckBoxListListene reset(); } + @NotNull @Override public StatusText getEmptyText() { return myList.getEmptyText(); diff --git a/platform/platform-api/src/com/intellij/ui/PathsChooserComponent.java b/platform/platform-api/src/com/intellij/ui/PathsChooserComponent.java index 5651e1fda1dd..1ab89834457f 100644 --- a/platform/platform-api/src/com/intellij/ui/PathsChooserComponent.java +++ b/platform/platform-api/src/com/intellij/ui/PathsChooserComponent.java @@ -97,6 +97,7 @@ public class PathsChooserComponent implements ComponentWithEmptyText { reset(); } + @NotNull @Override public StatusText getEmptyText() { return myList.getEmptyText(); diff --git a/platform/platform-api/src/com/intellij/ui/components/JBList.java b/platform/platform-api/src/com/intellij/ui/components/JBList.java index 09491593543a..417a7894fe62 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBList.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBList.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ComponentWithExpandableItems; import com.intellij.ui.ExpandableItemsHandler; import com.intellij.ui.ExpandableItemsHandlerFactory; +import com.intellij.ui.ExpandedItemRendererComponentWrapper; import com.intellij.util.ArrayUtil; import com.intellij.util.NotNullFunction; import com.intellij.util.ui.AsyncProcessIcon; @@ -40,8 +41,8 @@ import java.util.Collection; * @author Konstantin Bulenkov */ public class JBList extends JList implements ComponentWithEmptyText, ComponentWithExpandableItems{ - private StatusText myEmptyText; - private ExpandableItemsHandler myExpandableItemsHandler; + @NotNull private StatusText myEmptyText; + @NotNull private ExpandableItemsHandler myExpandableItemsHandler; @Nullable private AsyncProcessIcon myBusyIcon; private boolean myBusy; @@ -172,15 +173,10 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi } }; - - if (shouldInstallItemTooltipExpander()) myExpandableItemsHandler = ExpandableItemsHandlerFactory.install(this); + myExpandableItemsHandler = ExpandableItemsHandlerFactory.install(this); + setCellRenderer(new DefaultListCellRenderer()); } - protected boolean shouldInstallItemTooltipExpander() { - return true; - } - - public boolean isEmpty() { return getItemsCount() == 0; } @@ -190,6 +186,7 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi return model == null ? 0 : model.getSize(); } + @NotNull @Override public StatusText getEmptyText() { return myEmptyText; @@ -201,6 +198,25 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi return myExpandableItemsHandler; } + @Override + public void setExpandableItemsEnabled(boolean enabled) { + myExpandableItemsHandler.setEnabled(enabled); + } + + @Override + public void setCellRenderer(final ListCellRenderer cellRenderer) { + super.setCellRenderer(new ListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + Component result = cellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (myExpandableItemsHandler != null && myExpandableItemsHandler.getExpandedItems().contains(index)) { + result = new ExpandedItemRendererComponentWrapper(result); + } + return result; + } + }); + } + public void installCellRenderer(@NotNull final NotNullFunction fun) { setCellRenderer(new DefaultListCellRenderer() { @NotNull diff --git a/platform/platform-api/src/com/intellij/ui/components/JBTextField.java b/platform/platform-api/src/com/intellij/ui/components/JBTextField.java index 197ee3687e58..80efc0fef7c5 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBTextField.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBTextField.java @@ -17,6 +17,7 @@ package com.intellij.ui.components; import com.intellij.util.ui.ComponentWithEmptyText; import com.intellij.util.ui.StatusText; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; @@ -59,6 +60,7 @@ public class JBTextField extends JTextField implements ComponentWithEmptyText { myEmptyText.clear(); } + @NotNull @Override public StatusText getEmptyText() { return myEmptyText; diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index ce3f161ef77b..da97431922a9 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -18,10 +18,7 @@ package com.intellij.ui.table; import com.intellij.Patches; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.ui.ComponentWithExpandableItems; -import com.intellij.ui.ExpandableItemsHandler; -import com.intellij.ui.ExpandableItemsHandlerFactory; -import com.intellij.ui.TableCell; +import com.intellij.ui.*; import com.intellij.ui.components.JBViewport; import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.util.ui.*; @@ -300,6 +297,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } } + @NotNull @Override public StatusText getEmptyText() { return myEmptyText; @@ -311,6 +309,11 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component return myExpandableItemsHandler; } + @Override + public void setExpandableItemsEnabled(boolean enabled) { + myExpandableItemsHandler.setEnabled(enabled); + } + public void removeNotify() { final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); //noinspection HardCodedStringLiteral @@ -460,12 +463,12 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component private static boolean isTableDecorationSupported() { return UIUtil.isUnderAlloyLookAndFeel() - || UIUtil.isUnderNativeMacLookAndFeel() - || UIUtil.isUnderDarcula() - || UIUtil.isUnderQuaquaLookAndFeel() - || UIUtil.isUnderMetalLookAndFeel() - || UIUtil.isUnderNimbusLookAndFeel() - || UIUtil.isUnderWindowsLookAndFeel(); + || UIUtil.isUnderNativeMacLookAndFeel() + || UIUtil.isUnderDarcula() + || UIUtil.isUnderQuaquaLookAndFeel() + || UIUtil.isUnderMetalLookAndFeel() + || UIUtil.isUnderNimbusLookAndFeel() + || UIUtil.isUnderWindowsLookAndFeel(); } public void disableTypeAheadInCellEditors() { @@ -474,8 +477,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { - final Component result = super.prepareRenderer(renderer, row, column); - final boolean selected = myExpandableItemsHandler.getExpandedItems().contains(new TableCell(row, column)); + Component result = super.prepareRenderer(renderer, row, column); // Fix GTK background if (UIUtil.isUnderGTKLookAndFeel()) { @@ -483,7 +485,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } if (isTableDecorationSupported() && isStriped() && result instanceof JComponent) { - final Color bg = row % 2 == 1 ? getBackground() : UIUtil.getDecoratedRowColor(); + final Color bg = row % 2 == 1 ? getBackground() : UIUtil.getDecoratedRowColor(); final JComponent c = (JComponent)result; final boolean cellSelected = isCellSelected(row, column); if (!cellSelected) { @@ -492,31 +494,13 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component for (Component child : c.getComponents()) { child.setBackground(bg); } - } + } } - if (!selected) return result; - - return new JComponent() { - { - add(result); - setOpaque(false); - setLayout(new AbstractLayoutManager() { - @Override - public Dimension preferredLayoutSize(Container parent) { - return result.getPreferredSize(); - } - - @Override - public void layoutContainer(Container parent) { - Dimension size = parent.getSize(); - Insets i = parent.getInsets(); - Dimension pref = result.getPreferredSize(); - result.setBounds(i.left, i.top, Math.max(pref.width, size.width - i.left - i.right), size.height - i.top - i.bottom); - } - }); - } - }; + if (myExpandableItemsHandler.getExpandedItems().contains(new TableCell(row, column))) { + result = new ExpandedItemRendererComponentWrapper(result); + } + return result; } private final class MyCellEditorRemover implements PropertyChangeListener { diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java index 585b492605bd..a914d546889a 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java @@ -148,6 +148,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith return false; } + @NotNull @Override public StatusText getEmptyText() { return myEmptyText; @@ -159,6 +160,11 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith return myExpandableItemsHandler; } + @Override + public void setExpandableItemsEnabled(boolean enabled) { + myExpandableItemsHandler.setEnabled(enabled); + } + @Override public Color getBackground() { return isBackgroundSet() ? super.getBackground() : UIUtil.getTreeTextBackground(); diff --git a/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java b/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java index 834e4d241bc2..1b216f2135bf 100644 --- a/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java +++ b/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java @@ -209,8 +209,8 @@ public class QueueProcessor { try { LOG.error(t); } - catch (Exception ignore) { - // should survive assertions + catch (Throwable e2) { + e2.printStackTrace(); } } } diff --git a/platform/platform-api/src/com/intellij/util/ui/ComponentWithEmptyText.java b/platform/platform-api/src/com/intellij/util/ui/ComponentWithEmptyText.java index 30c42d155695..5f53b875f92b 100644 --- a/platform/platform-api/src/com/intellij/util/ui/ComponentWithEmptyText.java +++ b/platform/platform-api/src/com/intellij/util/ui/ComponentWithEmptyText.java @@ -15,6 +15,8 @@ */ package com.intellij.util.ui; +import org.jetbrains.annotations.NotNull; + public interface ComponentWithEmptyText { - StatusText getEmptyText(); + @NotNull StatusText getEmptyText(); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java index 17db4a5694a2..5855844f779c 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java @@ -442,7 +442,8 @@ public class Switcher extends AnAction implements DumbAware { new NameFilteringListModel(files, new Function() { @Override public String fun(FileInfo info) { - return info.getFirst().getName(); + final VirtualFile file = info.getFirst(); + return file instanceof VirtualFilePathWrapper ? ((VirtualFilePathWrapper)file).getPresentablePath() : file.getName(); } }, new Condition() { @Override @@ -513,6 +514,13 @@ public class Switcher extends AnAction implements DumbAware { }).createPopup(); if (isPinnedMode()) { + new AnAction(null ,null ,null) { + @Override + public void actionPerformed(AnActionEvent e) { + changeSelection(); + } + }.registerCustomShortcutSet(CustomShortcutSet.fromString("TAB"), this, myPopup); + new AnAction(null, null, null) { @Override public void actionPerformed(AnActionEvent e) { @@ -625,11 +633,15 @@ public class Switcher extends AnAction implements DumbAware { break; } if (e.getKeyCode() == ALT_KEY) { - if (isFilesSelected()) { - goLeft(); - } else { - goRight(); - } + changeSelection(); + } + } + + private void changeSelection() { + if (isFilesSelected()) { + goLeft(); + } else { + goRight(); } } @@ -871,6 +883,15 @@ public class Switcher extends AnAction implements DumbAware { setComparator(new SpeedSearchComparator(false, true)); } + @Override + protected void processKeyEvent(KeyEvent e) { + final int keyCode = e.getKeyCode(); + if (keyCode == VK_LEFT || keyCode == VK_RIGHT) { + return; + } + super.processKeyEvent(e); + } + @Override protected int getSelectedIndex() { return isFilesSelected() @@ -905,10 +926,13 @@ public class Switcher extends AnAction implements DumbAware { @Override protected String getElementText(Object element) { - return element instanceof ToolWindow - ? ids.get(element) - : element instanceof FileInfo - ? ((FileInfo)element).getFirst().getName() : ""; + if (element instanceof ToolWindow) { + return ids.get(element); + } else if (element instanceof FileInfo) { + final VirtualFile file = ((FileInfo)element).getFirst(); + return file instanceof VirtualFilePathWrapper ? ((VirtualFilePathWrapper)file).getPresentablePath() : file.getName(); + } + return ""; } @Override diff --git a/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java b/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java index 99bde93d4ba9..08c6aaaf0050 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java +++ b/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java @@ -147,6 +147,7 @@ public class ElementsChooser extends JPanel implements ComponentWithEmptyText inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, KeyEvent.SHIFT_DOWN_MASK), "selectLastRowExtendSelection"); } + @NotNull @Override public StatusText getEmptyText() { return myTable.getEmptyText(); @@ -158,6 +159,11 @@ public class ElementsChooser extends JPanel implements ComponentWithEmptyText return myTable.getExpandableItemsHandler(); } + @Override + public void setExpandableItemsEnabled(boolean enabled) { + myTable.setExpandableItemsEnabled(enabled); + } + public void setSingleSelectionMode() { myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java index ca9103d60b1a..cdd3b27502ef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java @@ -185,11 +185,12 @@ public class CommandMerger { } private boolean affectsMultiplePhysicalDocs() { - int count = 0; + Set affectedFiles = new HashSet(); for (DocumentReference each : myAllAffectedDocuments) { VirtualFile file = each.getFile(); - if (file instanceof LightVirtualFile) continue; - if (++count > 1) return true; + if (file == null || file instanceof LightVirtualFile) continue; + affectedFiles.add(file); + if (affectedFiles.size() > 1) return true; } return false; } diff --git a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java index 534e852eeb8b..b8405b872629 100644 --- a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java +++ b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java @@ -150,7 +150,8 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen private JTextField createColorField(boolean hex) { final NumberDocument doc = new NumberDocument(hex); - final JTextField field = new JTextField(doc, "", hex ? 5:2); + final int lafFix = UIUtil.isUnderWindowsClassicLookAndFeel() || UIUtil.isUnderWindowsLookAndFeel() ? 1 : 0; + final JTextField field = new JTextField(doc, "", (hex ? 5:2) + lafFix); field.setSize(50, -1); doc.setSource(field); field.getDocument().addDocumentListener(this); diff --git a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java index 0e969a07da00..9b1da5e2d988 100644 --- a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java +++ b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java @@ -289,7 +289,7 @@ public abstract class SpeedSearchBase extends SpeedSear manageSearchPopup(null); } - private void processKeyEvent(KeyEvent e) { + protected void processKeyEvent(KeyEvent e) { if (e.isAltDown()) return; if (mySearchPopup != null) { mySearchPopup.processKeyEvent(e); diff --git a/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java b/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java index 331903f3b691..fdcb69d54a4d 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java +++ b/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java @@ -28,6 +28,7 @@ import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.table.TableView; import com.intellij.util.IconUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -166,6 +167,7 @@ public abstract class ValidatingTableEditor implements ComponentWithEmptyT } } + @NotNull @Override public StatusText getEmptyText() { return myTable.getEmptyText(); diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java index 69a25e3242ef..22895b4a31f4 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java @@ -24,6 +24,7 @@ import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.UsefulTestCase; +import com.intellij.ui.SpeedSearchComparator; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.CollectionFactory; import com.intellij.util.text.Matcher; @@ -519,4 +520,12 @@ public class NameUtilTest extends UsefulTestCase { } }).cpuBound().attempts(20).assertTiming(); } + + public void testSpeedSearchComparator() { + final SpeedSearchComparator c = new SpeedSearchComparator(false, true); + + assertTrue(c.matchingFragments("a", "Ant") != null); + assertTrue(c.matchingFragments("an", "Changes") != null); + assertTrue(c.matchingFragments("a", "Changes") != null); + } } diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index cdb316e5daf1..d6b9192bdc61 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -56,7 +56,8 @@ create.global.library=Create Glob&al library ''{0}'' create.library.dialog.title=Create Android library select.target.dialog.text=Please select Android Target default.activity.not.found.error=Default Activity not found -activity.not.launchable.error=The Intent Filter of the Activity must contain {0} action +activity.not.launchable.error=The intent-filter of the activity must contain {0} action +activity.not.declared.in.manifest=The activity ''{0}'' is not declared in AndroidManifest.xml new.typed.resource.command.name=New {0} resource file new.typed.resource.dialog.title=New {0} Resource File new.file.dialog.text=Enter a new file name diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidDependencyProcessor.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidDependencyProcessor.java index 7423d5fdf7a0..bd6140c35841 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidDependencyProcessor.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidDependencyProcessor.java @@ -50,7 +50,7 @@ public class AndroidDependencyProcessor implements DependencyProcessor { @Override public void run() { final PsiClass[] classes = - JavaPsiFacade.getInstance(project).findClasses(topLevelClassName, GlobalSearchScope.allScope(project)); + JavaPsiFacade.getInstance(project).findClasses(topLevelClassName, GlobalSearchScope.projectScope(project)); for (PsiClass aClass : classes) { final Collection references = searcher.findReferences(aClass, true); diff --git a/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReferenceBase.java b/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReferenceBase.java index c433d26cc501..82f9e42b0563 100644 --- a/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReferenceBase.java +++ b/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReferenceBase.java @@ -116,7 +116,8 @@ public class AndroidResourceReferenceBase extends PsiReferenceBase.Poly valueResources = manager.findValueResourceInfos(resType, resName, false); + final boolean attrReference = resValue.getPrefix() == '?'; + List valueResources = manager.findValueResourceInfos(resType, resName, false, attrReference); for (final ValueResourceInfo resource : valueResources) { elements.add(new LazyValueResourceElementWrapper(resource, myElement)); diff --git a/plugins/android/src/org/jetbrains/android/dom/converters/ParentStyleConverter.java b/plugins/android/src/org/jetbrains/android/dom/converters/ParentStyleConverter.java index f1ccf902c324..dd548ba9182b 100644 --- a/plugins/android/src/org/jetbrains/android/dom/converters/ParentStyleConverter.java +++ b/plugins/android/src/org/jetbrains/android/dom/converters/ParentStyleConverter.java @@ -23,5 +23,6 @@ import com.android.resources.ResourceType; public class ParentStyleConverter extends ResourceReferenceConverter { public ParentStyleConverter() { super(ResourceType.STYLE.getName(), false, false); + setAllowAttributeReferences(false); } } diff --git a/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java b/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java index 28a582648f96..7e4836bbc133 100644 --- a/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java +++ b/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java @@ -55,6 +55,7 @@ public class ResourceReferenceConverter extends ResolvingConverter()); @@ -79,6 +80,10 @@ public class ResourceReferenceConverter extends ResolvingConverter filteringSet = SYSTEM_RESOURCE_PACKAGE.equals(resourcePackage) @@ -140,7 +147,7 @@ public class ResourceReferenceConverter extends ResolvingConverter additionalConverter = getAdditionalConverter(context); if (additionalConverter != null) { @@ -159,6 +169,19 @@ public class ResourceReferenceConverter extends ResolvingConverter result) { + if (StringUtil.startsWith(value, "?attr/")) { + addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), null, result, true); + } + else if (StringUtil.startsWith(value, "?android:attr/")) { + addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), SYSTEM_RESOURCE_PACKAGE, result, true); + } + else if (StringUtil.startsWithChar(value, '?')) { + addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), null, result, false); + addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), SYSTEM_RESOURCE_PACKAGE, result, false); + } + } + @NotNull public static Set getResourceTypesInCurrentModule(@NotNull AndroidFacet facet) { final Set result = new HashSet(); @@ -205,21 +228,22 @@ public class ResourceReferenceConverter extends ResolvingConverter result, - boolean explicitResourceType) { + private static void addResourceReferenceValues(AndroidFacet facet, + char prefix, + String type, + @Nullable String resPackage, + Collection result, + boolean explicitResourceType) { final ResourceManager manager = facet.getResourceManager(resPackage); if (manager != null) { for (String name : manager.getResourceNames(type)) { - result.add(referenceTo(type, resPackage, name, explicitResourceType)); + result.add(referenceTo(prefix, type, resPackage, name, explicitResourceType)); } } } - private ResourceValue referenceTo(String type, String resPackage, String name, boolean explicitResourceType) { - return ResourceValue.referenceTo(myWithPrefix ? '@' : 0, resPackage, explicitResourceType ? type : null, name); + private static ResourceValue referenceTo(char prefix, String type, String resPackage, String name, boolean explicitResourceType) { + return ResourceValue.referenceTo(prefix, resPackage, explicitResourceType ? type : null, name); } public ResourceValue fromString(@Nullable @NonNls String s, ConvertContext context) { @@ -236,8 +260,28 @@ public class ResourceReferenceConverter extends ResolvingConverter 0; result.myPrefix = value.charAt(0); } + final int startIndex = withPrefix ? 1 : 0; int pos = value.indexOf('/'); + if (pos > 0) { - String resType = value.substring(withPrefix ? 1 : 0, pos); + String resType = value.substring(startIndex, pos); int colonIndex = resType.indexOf(':'); if (colonIndex > 0) { result.myPackage = resType.substring(0, colonIndex); @@ -117,10 +119,13 @@ public class ResourceValue { } else { int colonIndex = value.indexOf(':'); - if (colonIndex > 0) { - result.myPackage = value.substring(0, colonIndex); + if (colonIndex > startIndex) { + result.myPackage = value.substring(startIndex, colonIndex); + result.myResourceName = value.substring(colonIndex + 1); + } + else { + result.myResourceName = value.substring(startIndex); } - result.myResourceName = value.substring(colonIndex + 1); } return result; } diff --git a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java index 286402250b95..6aeaa035c096 100644 --- a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java +++ b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java @@ -433,7 +433,7 @@ public abstract class ResourceManager { public List findValueResources(@NotNull String resourceType, @NotNull String resourceName, boolean distinguishDelimitersInName) { - final List resources = findValueResourceInfos(resourceType, resourceName, distinguishDelimitersInName); + final List resources = findValueResourceInfos(resourceType, resourceName, distinguishDelimitersInName, false); final List result = new ArrayList(); for (ValueResourceInfoImpl resource : resources) { @@ -449,14 +449,14 @@ public abstract class ResourceManager { @NotNull public List findValueResourceInfos(@NotNull String resourceType, @NotNull final String resourceName, - final boolean distinguishDelimetersInName) { + final boolean distinguishDelimetersInName, + boolean searchAttrs) { final ResourceType type = ResourceType.getEnum(resourceType); - if (type == null || !AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(type)) { - // do not search for styleables and atts here because we don't want to resolve references to it + if (type == null || + !AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(type) && + (type != ResourceType.ATTR || !searchAttrs)) { return Collections.emptyList(); } - - new HashMap>(); final GlobalSearchScope scope = GlobalSearchScope.allScope(myModule.getProject()); final List result = new ArrayList(); final Set valueResourceFiles = getAllValueResourceFiles(); diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java index 67f08f294ceb..08cfe118036a 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfiguration.java @@ -26,7 +26,6 @@ import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.ui.ConsoleView; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -82,7 +81,12 @@ public class AndroidRunConfiguration extends AndroidRunConfigurationBase impleme if (!c.isInheritor(activityClass, true)) { throw new RuntimeConfigurationError(AndroidBundle.message("not.activity.subclass.error", ACTIVITY_CLASS)); } - if (!isActivityLaunchable(facet.getModule(), c)) { + + final Activity activity = AndroidDomUtil.getActivityDomElementByClass(facet.getModule(), c); + if (activity == null) { + throw new RuntimeConfigurationError(AndroidBundle.message("activity.not.declared.in.manifest", c.getName())); + } + if (!isActivityLaunchable(activity)) { throw new RuntimeConfigurationError(AndroidBundle.message("activity.not.launchable.error", AndroidUtils.LAUNCH_ACTION_NAME)); } } @@ -170,13 +174,10 @@ public class AndroidRunConfiguration extends AndroidRunConfigurationBase impleme return new MyApplicationLauncher(activityToLaunch); } - private static boolean isActivityLaunchable(@NotNull Module module, PsiClass c) { - Activity activity = AndroidDomUtil.getActivityDomElementByClass(module, c); - if (activity != null) { - for (IntentFilter filter : activity.getIntentFilters()) { - if (AndroidDomUtil.containsAction(filter, AndroidUtils.LAUNCH_ACTION_NAME)) { - return true; - } + private static boolean isActivityLaunchable(Activity activity) { + for (IntentFilter filter : activity.getIntentFilters()) { + if (AndroidDomUtil.containsAction(filter, AndroidUtils.LAUNCH_ACTION_NAME)) { + return true; } } return false; diff --git a/plugins/android/testData/dom/layout/attrReferences1.xml b/plugins/android/testData/dom/layout/attrReferences1.xml new file mode 100644 index 000000000000..ce14af0ebe83 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences1.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences2.xml b/plugins/android/testData/dom/layout/attrReferences2.xml new file mode 100644 index 000000000000..e9c8ffc159a6 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences2.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences3.xml b/plugins/android/testData/dom/layout/attrReferences3.xml new file mode 100644 index 000000000000..95e6500c6939 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences3.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences4.xml b/plugins/android/testData/dom/layout/attrReferences4.xml new file mode 100644 index 000000000000..a3fe1cf50cf6 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences4.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences4_after.xml b/plugins/android/testData/dom/layout/attrReferences4_after.xml new file mode 100644 index 000000000000..774c58738909 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences4_after.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences5.xml b/plugins/android/testData/dom/layout/attrReferences5.xml new file mode 100644 index 000000000000..6a925ca64534 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences5.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences5_after.xml b/plugins/android/testData/dom/layout/attrReferences5_after.xml new file mode 100644 index 000000000000..0316786d884f --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences5_after.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences6.xml b/plugins/android/testData/dom/layout/attrReferences6.xml new file mode 100644 index 000000000000..95e6500c6939 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences6.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences6_after.xml b/plugins/android/testData/dom/layout/attrReferences6_after.xml new file mode 100644 index 000000000000..3530dd08b0ab --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences6_after.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences7.xml b/plugins/android/testData/dom/layout/attrReferences7.xml new file mode 100644 index 000000000000..95e6500c6939 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences7.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences7_after.xml b/plugins/android/testData/dom/layout/attrReferences7_after.xml new file mode 100644 index 000000000000..eea3d0f1d05a --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences7_after.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/layout/attrReferences_attrs.xml b/plugins/android/testData/dom/layout/attrReferences_attrs.xml new file mode 100644 index 000000000000..fc184c93cb54 --- /dev/null +++ b/plugins/android/testData/dom/layout/attrReferences_attrs.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/resources/attrReferenceCompletion.xml b/plugins/android/testData/dom/resources/attrReferenceCompletion.xml new file mode 100644 index 000000000000..43c6eccb6ff9 --- /dev/null +++ b/plugins/android/testData/dom/resources/attrReferenceCompletion.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/resources/attrReferenceCompletion_after.xml b/plugins/android/testData/dom/resources/attrReferenceCompletion_after.xml new file mode 100644 index 000000000000..a788d7d477a2 --- /dev/null +++ b/plugins/android/testData/dom/resources/attrReferenceCompletion_after.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/plugins/android/testData/dom/resources/attrReferenceHighlighting.xml b/plugins/android/testData/dom/resources/attrReferenceHighlighting.xml new file mode 100644 index 000000000000..ca9b0f92de56 --- /dev/null +++ b/plugins/android/testData/dom/resources/attrReferenceHighlighting.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLayoutDomTest.java b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLayoutDomTest.java index f44592c55300..e7f8a3303517 100644 --- a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLayoutDomTest.java +++ b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLayoutDomTest.java @@ -667,6 +667,64 @@ public class AndroidLayoutDomTest extends AndroidDomTest { doTestHighlighting(); } + public void testAttrReferences1() throws Throwable { + copyFileToProject("attrReferences_attrs.xml", "res/values/attrReferences_attrs.xml"); + doTestHighlighting(); + } + + public void testAttrReferences2() throws Throwable { + doTestAttrReferenceCompletionVariants("?"); + } + + public void testAttrReferences3() throws Throwable { + doTestAttrReferenceCompletionVariants("attr"); + } + + private void doTestAttrReferenceCompletionVariants(String prefix) throws IOException { + copyFileToProject("attrReferences_attrs.xml", "res/values/attrReferences_attrs.xml"); + VirtualFile file = copyFileToProject(getTestName(true) + ".xml"); + myFixture.configureFromExistingVirtualFile(file); + myFixture.complete(CompletionType.BASIC); + final List variants = myFixture.getLookupElementStrings(); + assertNotNull(variants); + assertTrue(variants.size() > 0); + assertFalse(containElementStartingWith(variants, prefix)); + } + + public void testAttrReferences4() throws Throwable { + doTestAttrReferenceCompletion("myA\n"); + } + + public void testAttrReferences5() throws Throwable { + doTestAttrReferenceCompletion("textAppear\n"); + } + + public void testAttrReferences6() throws Throwable { + doTestAttrReferenceCompletion("myA\n"); + } + + public void testAttrReferences7() throws Throwable { + doTestAttrReferenceCompletion("android:textAppear\n"); + } + + private void doTestAttrReferenceCompletion(String textToType) throws IOException { + copyFileToProject("attrReferences_attrs.xml", "res/values/attrReferences_attrs.xml"); + VirtualFile file = copyFileToProject(getTestName(true) + ".xml"); + myFixture.configureFromExistingVirtualFile(file); + myFixture.complete(CompletionType.BASIC); + myFixture.type(textToType); + myFixture.checkResultByFile(testFolder + '/' + getTestName(true) + "_after.xml"); + } + + private static boolean containElementStartingWith(List elements, String prefix) { + for (String element : elements) { + if (element.startsWith(prefix)) { + return true; + } + } + return false; + } + private void doCreateFileResourceFromUsage(VirtualFile virtualFile) { myFixture.configureFromExistingVirtualFile(virtualFile); final List infos = myFixture.doHighlighting(); diff --git a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java index 662ba9615541..9c0d0a54d0a7 100644 --- a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java +++ b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidValueResourcesTest.java @@ -317,6 +317,14 @@ public class AndroidValueResourcesTest extends AndroidDomTest { myFixture.checkResultByFile("res/values/bools.xml", testFolder + '/' + getTestName(true) + "_bools_after.xml", true); } + public void testAttrReferenceCompletion() throws Throwable { + doTestCompletion(); + } + + public void testAttrReferenceHighlighting() throws Throwable { + doTestHighlighting(); + } + private void doCreateValueResourceFromUsage(VirtualFile virtualFile) { myFixture.configureFromExistingVirtualFile(virtualFile); final List infos = myFixture.doHighlighting(); diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java b/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java index ce05f99e3bbf..4eccfd72c924 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java @@ -20,14 +20,19 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; -import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packageDependencies.DependencyValidationManager; import com.intellij.psi.PsiFile; @@ -87,9 +92,13 @@ public class CopyrightManager extends AbstractProjectComponent implements JDOMEx public void projectOpened() { if (myProject != null) { - FileEditorManagerListener listener = new FileEditorManagerAdapter() { - public void fileOpened(FileEditorManager fileEditorManager, VirtualFile virtualFile) { - if (virtualFile.isWritable() && NewFileTracker.getInstance().contains(virtualFile)) { + final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); + DocumentListener listener = new DocumentAdapter() { + @Override + public void documentChanged(DocumentEvent e) { + final Document document = e.getDocument(); + final VirtualFile virtualFile = fileDocumentManager.getFile(document); + if (virtualFile != null && NewFileTracker.getInstance().contains(virtualFile)) { NewFileTracker.getInstance().remove(virtualFile); if (FileTypeUtil.getInstance().isSupportedFile(virtualFile)) { final Module module = ProjectRootManager.getInstance(myProject).getFileIndex().getModuleForFile(virtualFile); @@ -100,7 +109,7 @@ public class CopyrightManager extends AbstractProjectComponent implements JDOMEx public void run() { if (myProject.isDisposed()) return; if (file.isValid() && file.isWritable()) { - final CopyrightProfile opts = getInstance(myProject).getCopyrightOptions(file); + final CopyrightProfile opts = getCopyrightOptions(file); if (opts != null) { new UpdateCopyrightProcessor(myProject, module, file).run(); } @@ -113,8 +122,10 @@ public class CopyrightManager extends AbstractProjectComponent implements JDOMEx } } }; - - FileEditorManager.getInstance(myProject).addFileEditorManagerListener(listener, myProject); + final EditorFactory factory = EditorFactory.getInstance(); + if (factory != null) { + factory.getEventMulticaster().addDocumentListener(listener, myProject); + } } } diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java index 166bbaba3c5b..eb71a4d6cec5 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java @@ -787,7 +787,7 @@ public abstract class DomInvocationHandler