From e9c5e896fc0804f03e2a716cccb99c83784d370e Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 8 Aug 2014 20:14:24 +0200 Subject: [PATCH 1/6] SSR: remove visitDocTagValue() method, doc tag value matching is handled in visitDocTag() --- .../impl/matcher/JavaMatchingVisitor.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java index 0ea857b16362..418bc06d3b9e 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java @@ -90,19 +90,6 @@ public class JavaMatchingVisitor extends JavaElementVisitor { } } - @Override - public void visitDocTagValue(final PsiDocTagValue value) { - final PsiDocTagValue value2 = (PsiDocTagValue)myMatchingVisitor.getElement(); - final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(value); - - if (isTypedVar) { - myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(value, value2)); - } - else { - myMatchingVisitor.setResult(value.textMatches(value2)); - } - } - private static boolean isNotInstanceModifier(final PsiModifierList list2) { return list2.hasModifierProperty(PsiModifier.STATIC) || list2.hasModifierProperty(PsiModifier.ABSTRACT); From 02d221d5eebc9a7b0f3f8b2b19b33d232e2e9212 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 9 Aug 2014 17:05:35 +0200 Subject: [PATCH 2/6] EA-59253 (NPE: JavaCompilingVisitor.visitComment) --- .../impl/matcher/compiler/JavaCompilingVisitor.java | 10 +++++----- .../structuralsearch/StructuralSearchTest.java | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java index 271f1c468b0b..18c252d28111 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java @@ -1,20 +1,17 @@ package com.intellij.structuralsearch.impl.matcher.compiler; +import com.intellij.dupLocator.iterators.NodeIterator; import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.search.*; import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.structuralsearch.MatchOptions; -import com.intellij.structuralsearch.MatchVariableConstraint; -import com.intellij.structuralsearch.SSRBundle; -import com.intellij.structuralsearch.UnsupportedPatternException; +import com.intellij.structuralsearch.*; import com.intellij.structuralsearch.impl.matcher.CompiledPattern; import com.intellij.structuralsearch.impl.matcher.JavaCompiledPattern; import com.intellij.structuralsearch.impl.matcher.filters.*; import com.intellij.structuralsearch.impl.matcher.handlers.*; import com.intellij.structuralsearch.impl.matcher.iterators.DocValuesIterator; -import com.intellij.dupLocator.iterators.NodeIterator; import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate; import com.intellij.structuralsearch.impl.matcher.strategies.*; import org.jetbrains.annotations.NonNls; @@ -84,6 +81,9 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor { ); SubstitutionHandler handler = (SubstitutionHandler)myCompilingVisitor.getContext().getPattern().getHandler(str); + if (handler == null) { + throw new MalformedPatternException(); + } if (handler.getPredicate() != null) { ((RegExpPredicate)handler.getPredicate()).setMultiline(true); diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java index da479a70f93c..f6f3d58ba384 100644 --- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java @@ -2943,4 +2943,13 @@ public class StructuralSearchTest extends StructuralSearchTestCase { String pattern3 = "'_a::'_b"; assertEquals("should find all method references", 3, findMatchesCount(source, pattern3)); } + + public void testNoUnexpectedException() { + String source = "{}"; + + String pattern1 = "/*$A$a*/"; + try { + findMatchesCount(source, pattern1); + } catch (MalformedPatternException ignore) {} + } } From e7c68117ca3991d3af5b51cf8a63fda857c78227 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Sat, 9 Aug 2014 19:03:39 +0400 Subject: [PATCH 3/6] IDEA-128336 / 2 / Too many "Project" icons --- .../options/newEditor/OptionsTree.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java index e0ab24815ece..e1e52340440b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java @@ -23,6 +23,7 @@ import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.options.OptionsBundle; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.ex.ConfigurableWrapper; +import com.intellij.openapi.options.ex.NodeConfigurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; @@ -404,8 +405,25 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl myTextLabel.setBorder(new EmptyBorder(1,2,1,0)); } - Project project = getConfigurableProject(base); - if (project != null && Registry.is("ide.file.settings.order.new")) { + Project project = null; + if (base != null && Registry.is("ide.file.settings.order.new")) { + SimpleNode parent = base.getParent(); + if (parent == myRoot) { + project = getConfigurableProject(base); // show icon for top-level nodes + if (base.getConfigurable() instanceof NodeConfigurable) { // special case for custom subgroups (build.tools) + Configurable[] configurables = ((NodeConfigurable)base.getConfigurable()).getConfigurables(); + if (configurables != null) { // assume that all configurables have the same project + project = getConfigurableProject(configurables[0]); + } + } + } + else if (parent instanceof Base && ((Base)parent).getConfigurable() instanceof NodeConfigurable) { + if (((Base)base.getParent()).getConfigurable() instanceof NodeConfigurable) { + project = getConfigurableProject(base); // special case for custom subgroups + } + } + } + if (project != null) { myProjectIcon.setBackground(selected ? getSelectionBackground() : getBackground()); myProjectIcon.setIcon(selected ? AllIcons.General.ProjectConfigurableSelected : AllIcons.General.ProjectConfigurable); myProjectIcon.setVisible(true); From 701c4e22af62d574fd8a25f4c4b2228eec71db31 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Sat, 9 Aug 2014 19:36:22 +0400 Subject: [PATCH 4/6] IDEA-128336 / 3.1 / move group headers to the left --- .../src/com/intellij/openapi/options/newEditor/OptionsTree.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java index e1e52340440b..ce80606a794f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java @@ -313,6 +313,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl myProjectIcon.setOpaque(true); content.add(myProjectIcon, BorderLayout.EAST); myRendererComponent.add(content, BorderLayout.CENTER); + mySeparatorComponent.setCaptionCentered(false); } public Component getTreeCellRendererComponent(final JTree tree, From 3a497fb174761428f65f4282e4e41cb0dacacf75 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Sat, 9 Aug 2014 21:55:57 +0400 Subject: [PATCH 5/6] IDEA-128336 / 4.2 / glue the group header to the top of the list --- .../options/newEditor/OptionsTree.java | 64 +++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java index ce80606a794f..7ae180a8b0f2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java @@ -117,10 +117,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl } }); - final JScrollPane scrolls = ScrollPaneFactory.createScrollPane(myTree); - scrolls.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - - add(scrolls, BorderLayout.CENTER); + add(new StickySeparator(myTree), BorderLayout.CENTER); mySelection = new MergingUpdateQueue("OptionsTree", 150, false, this, this, this).setRestartTimerOnAdd(true); myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { @@ -922,4 +919,63 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl } return getConfigurableProject(node.getParent()); } + + private static final class StickySeparator extends JComponent { + private final SimpleTree myTree; + private final JScrollPane myScroller; + private final SeparatorWithText mySeparator; + + public StickySeparator(SimpleTree tree) { + myTree = tree; + myScroller = ScrollPaneFactory.createScrollPane(myTree); + myScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + mySeparator = new SeparatorWithText(); + mySeparator.setCaptionCentered(false); + //mySeparator.setVisible(true); + add(myScroller); + mySeparator.setOpaque(true); + } + + @Override + public void doLayout() { + myScroller.setBounds(0, 0, getWidth(), getHeight()); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + + if (Registry.is("ide.file.settings.order.new")) { + String name = null; + int offset = 2 * mySeparator.getFont().getSize(); + TreePath path = myTree.getClosestPathForLocation(-myTree.getX(), -myTree.getY() + offset); + SimpleNode node = myTree.getNodeFor(path); + if (node instanceof FilteringTreeStructure.FilteringNode) { + Object delegate = ((FilteringTreeStructure.FilteringNode)node).getDelegate(); + if (delegate instanceof EditorNode) { + EditorNode editor = (EditorNode)delegate; + ConfigurableGroup group = editor.getGroup(); + if (group != null) { + name = group.getDisplayName(); + } + } + } + if (name != null) { + mySeparator.setCaption(name); + + Rectangle bounds = myScroller.getViewport().getBounds(); + int height = mySeparator.getPreferredSize().height; + if (bounds.height > height) { + bounds.height = height; + } + g.setColor(myTree.getBackground()); + g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); + g.setColor(myTree.getForeground()); + g.drawLine(0, bounds.height, bounds.width, bounds.height); + mySeparator.setBounds(bounds); + mySeparator.paint(g); + } + } + } + } } From 91ceaf67b16417fdc4b8fe4d03682f8b8d25897d Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Sun, 10 Aug 2014 01:42:24 +0400 Subject: [PATCH 6/6] Injection: cleanup & minimize Shred usages --- .../codeInsight/intention/impl/QuickEditHandler.java | 3 +-- .../impl/source/tree/injected/InjectedFileViewProvider.java | 2 +- .../psi/impl/source/tree/injected/InjectedLanguageUtil.java | 4 ++-- .../impl/source/tree/injected/MultiHostRegistrarImpl.java | 2 +- .../com/intellij/psi/impl/source/tree/injected/Place.java | 6 ++++++ .../intellij/psi/impl/source/tree/injected/ShredImpl.java | 3 ++- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java index 99db51cc1e59..dc4bc435b0a1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java @@ -55,7 +55,6 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.resolve.FileContextUtil; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.impl.source.tree.injected.Place; -import com.intellij.psi.impl.source.tree.injected.ShredImpl; import com.intellij.psi.util.PsiUtilCore; import com.intellij.testFramework.LightVirtualFile; import com.intellij.ui.awt.RelativePoint; @@ -133,7 +132,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { // suppress possible errors as in injected mode myNewFile.putUserData(InjectedLanguageUtil.FRANKENSTEIN_INJECTION, injectedFile.getUserData(InjectedLanguageUtil.FRANKENSTEIN_INJECTION)); - myNewFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, ((ShredImpl)firstShred).getSmartPointer()); + myNewFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, shreds.getHostPointer()); myNewDocument = PsiDocumentManager.getInstance(project).getDocument(myNewFile); assert myNewDocument != null; EditorActionManager.getInstance().setReadonlyFragmentModificationHandler(myNewDocument, new MyQuietHandler()); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java index f4a6d576e6b8..58a9463b755d 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java @@ -61,7 +61,7 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme @NotNull Language language) { super(psiManager, (VirtualFile)virtualFile, true, language); myDocumentWindow = documentWindow; - myProject = documentWindow.getShreds().get(0).getHost().getProject(); + myProject = documentWindow.getShreds().getHostPointer().getProject(); } @Override diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java index 512eb52c4fbf..f7c3bef10231 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java @@ -596,12 +596,12 @@ public class InjectedLanguageUtil { shreds = getShreds(((VirtualFileWindow)virtualFile).getDocumentWindow()); } } - return shreds != null ? shreds.get(0).getHost() : null; + return shreds != null ? shreds.getHostPointer().getElement() : null; } @Nullable public static PsiLanguageInjectionHost findInjectionHost(@Nullable VirtualFile virtualFile) { return virtualFile instanceof VirtualFileWindow ? - getShreds(((VirtualFileWindow)virtualFile).getDocumentWindow()).get(0).getHost() : null; + getShreds(((VirtualFileWindow)virtualFile).getDocumentWindow()).getHostPointer().getElement() : null; } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java index 183af7374072..e520eea741be 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java @@ -389,7 +389,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT "\nLeaf texts concatenated:'"+ patcher.catLeafs +"';" + "\nFile root: "+parsedNode+ "\nLanguage: "+parsedNode.getPsi().getLanguage()+ - "\nHost file: "+ shreds.get(0).getHost().getContainingFile().getVirtualFile() + "\nHost file: "+ shreds.getHostPointer().getVirtualFile() ; DebugUtil.startPsiModification("injection leaf patching"); try { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/Place.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/Place.java index afaf499b9bb9..f6be385077c2 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/Place.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/Place.java @@ -17,6 +17,7 @@ package com.intellij.psi.impl.source.tree.injected; import com.intellij.psi.PsiLanguageInjectionHost; +import com.intellij.psi.SmartPsiElementPointer; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; @@ -30,6 +31,11 @@ public class Place extends SmartList { super(shreds); } + @NotNull + public SmartPsiElementPointer getHostPointer() { + return ((ShredImpl)get(0)).getSmartPointer(); + } + public boolean isValid() { for (PsiLanguageInjectionHost.Shred shred : this) { if (!shred.isValid()) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/ShredImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/ShredImpl.java index 827f1dcd4119..5c60a1c2254f 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/ShredImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/ShredImpl.java @@ -23,7 +23,7 @@ import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ShredImpl implements PsiLanguageInjectionHost.Shred { +class ShredImpl implements PsiLanguageInjectionHost.Shred { private final RangeMarker relevantRangeInHost; private final SmartPsiElementPointer hostElementPointer; private final TextRange range; // range in (decoded) PSI @@ -45,6 +45,7 @@ public class ShredImpl implements PsiLanguageInjectionHost.Shred { assert relevantRangeInHost.isValid(); } + @NotNull public SmartPsiElementPointer getSmartPointer() { return hostElementPointer; }