From 9839c49076d6489f75f0238348c8f7b913a8fadf Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 13 Mar 2012 15:03:07 +0400 Subject: [PATCH 1/5] no testdata methods in goto symbol --- .../src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java b/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java index 3d4542930f6f..82ad5be28079 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java @@ -22,6 +22,7 @@ import com.intellij.psi.impl.java.stubs.index.JavaFieldNameIndex; import com.intellij.psi.impl.java.stubs.index.JavaMethodNameIndex; import com.intellij.psi.impl.java.stubs.index.JavaShortClassNameIndex; import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys; +import com.intellij.psi.impl.search.JavaSourceFilterScope; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; @@ -112,7 +113,7 @@ class PsiShortNamesCacheImpl extends PsiShortNamesCache { @Override @NotNull public PsiMethod[] getMethodsByName(@NotNull String name, @NotNull final GlobalSearchScope scope) { - Collection methods = StubIndex.getInstance().get(JavaStubIndexKeys.METHODS, name, myManager.getProject(), scope); + Collection methods = StubIndex.getInstance().get(JavaStubIndexKeys.METHODS, name, myManager.getProject(), new JavaSourceFilterScope(scope)); if (methods.isEmpty()) return PsiMethod.EMPTY_ARRAY; List list = filterMembers(methods, scope); From 6321cc5cf78eff774044a562f65672720fc62224 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 13 Mar 2012 15:36:53 +0400 Subject: [PATCH 2/5] textAttributesKey in expected highlighting data --- .../codeInsight/daemon/impl/HighlightInfo.java | 2 +- .../testFramework/ExpectedHighlightingData.java | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java index 7daea7c48c43..06d2cd4e5641 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java @@ -72,7 +72,7 @@ public class HighlightInfo implements Segment { } @Nullable - public TextAttributes getTextAttributes(final PsiElement element, + public TextAttributes getTextAttributes(@Nullable final PsiElement element, @Nullable final EditorColorsScheme editorColorsScheme) { if (forcedTextAttributes != null) { return forcedTextAttributes; diff --git a/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java b/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java index d69dec3cefdc..44024054e76d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java +++ b/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java @@ -30,6 +30,7 @@ import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.editor.markup.TextAttributes; @@ -238,6 +239,7 @@ public class ExpectedHighlightingData { "(?:\\s+effectcolor=\"([0-9xa-f]+)\")?" + "(?:\\s+effecttype=\"([A-Z]+)\")?" + "(?:\\s+fonttype=\"([0-9]+)\")?" + + "(?:\\s+textAttributesKey=\"((?:[^\"]|\\\\\"|\\\\\\\\\"|\\\\\\[|\\\\\\])*)\")?" + "(/)?>"; final Matcher matcher = Pattern.compile(openingTagRx).matcher(text); @@ -261,6 +263,7 @@ public class ExpectedHighlightingData { final String effectColor = matcher.group(groupIdx++); final String effectType = matcher.group(groupIdx++); final String fontType = matcher.group(groupIdx++); + final String attrKey = matcher.group(groupIdx++); final boolean closed = matcher.group(groupIdx) != null; if (descr == null) { @@ -319,7 +322,8 @@ public class ExpectedHighlightingData { final ExpectedHighlightingSet expectedHighlightingSet = highlightingTypes.get(marker); if (expectedHighlightingSet.enabled) { - final HighlightInfo highlightInfo = new HighlightInfo(forcedAttributes, type, rangeStart, textOffset.get(), descr, descr, + TextAttributesKey forcedTextAttributesKey = attrKey == null ? null : TextAttributesKey.createTextAttributesKey(attrKey); + final HighlightInfo highlightInfo = new HighlightInfo(forcedAttributes, forcedTextAttributesKey, type, rangeStart, textOffset.get(), descr, descr, expectedHighlightingSet.severity, expectedHighlightingSet.endOfLine, null, false); expectedHighlightingSet.infos.add(highlightInfo); @@ -551,13 +555,13 @@ public class ExpectedHighlightingData { if (expectedInfo == info) return true; return info.getSeverity() == expectedInfo.getSeverity() && - info.startOffset /*+ (info.isAfterEndOfLine ? 1 : 0)*/ == expectedInfo.startOffset && + info.startOffset == expectedInfo.startOffset && info.endOffset == expectedInfo.endOffset && info.isAfterEndOfLine == expectedInfo.isAfterEndOfLine && (expectedInfo.type == WHATEVER || expectedInfo.type.equals(info.type)) && (Comparing.strEqual(ANY_TEXT, expectedInfo.description) || Comparing.strEqual(info.description, expectedInfo.description)) && (expectedInfo.forcedTextAttributes == null || expectedInfo.getTextAttributes(null, null).equals(info.getTextAttributes(null, null))) - && (expectedInfo.forcedTextAttributesKey == null || expectedInfo.getTextAttributes(null, null).equals(info.getTextAttributes(null, null))) + && (expectedInfo.forcedTextAttributesKey == null || expectedInfo.forcedTextAttributesKey.equals(info.forcedTextAttributesKey)) ; } } From ba21e36367362000d92f7230ecfb8c3d82d2a0c4 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 13 Mar 2012 15:38:34 +0400 Subject: [PATCH 3/5] highglight methods/vars/parameters, reassigned or not, in groovy (IDEA-82573) --- .../groovy/annotator/GroovyAnnotator.java | 41 +++++++++++++++++++ .../highlighter/DefaultHighlighter.java | 12 ++++++ .../groovy/lang/GroovyHighlightingTest.groovy | 4 ++ .../ReassignedHighlighting.groovy | 13 ++++++ 4 files changed, 70 insertions(+) create mode 100644 plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 214564712db7..ca36b1793390 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -40,6 +40,10 @@ import com.intellij.pom.PomTarget; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.search.searches.SuperMethodsSearch; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.MethodSignature; @@ -189,6 +193,10 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { if (resolved instanceof PsiMember) { highlightMemberResolved(myHolder, referenceExpression, ((PsiMember)resolved)); } + else if (resolved instanceof GrVariable) { + highlightVariable((GrVariable)resolved, getElementToHighlight(referenceExpression)); + } + /*if (!resolveResult.isAccessible()) { String message = GroovyBundle.message("cannot.access", referenceExpression.getReferenceName()); final Annotation annotation = myHolder.createWarningAnnotation(getElementToHighlight(referenceExpression), message); @@ -262,6 +270,33 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } } + private void highlightVariable(GrVariable variable, PsiElement toHighlight) { + Annotation annotation = myHolder.createInfoAnnotation(toHighlight, null); + boolean reassigned = isReassigned(variable); + if (variable instanceof GrParameter) { + annotation + .setTextAttributes(reassigned ? DefaultHighlighter.REASSIGNED_PARAMETER : DefaultHighlighter.PARAMETER); + } else { + annotation + .setTextAttributes(reassigned ? DefaultHighlighter.REASSIGNED_LOCAL_VARIABLE : DefaultHighlighter.LOCAL_VARIABLE); + } + } + + private static boolean isReassigned(GrVariable var) { + PsiMethod method = PsiTreeUtil.getParentOfType(var, PsiMethod.class); + boolean hasAssignment = var.getInitializerGroovy() != null || var instanceof GrParameter; + SearchScope scope = method == null ? GlobalSearchScope.projectScope(var.getProject()) : new LocalSearchScope(method); + for (PsiReference reference : ReferencesSearch.search(var, scope).findAll()) { + if (reference instanceof GrReferenceExpression && PsiUtil.isLValue((GrReferenceExpression)reference)) { + if (hasAssignment) { + return true; + } + hasAssignment = true; + } + } + return false; + } + public static boolean shouldHighlightAsUnresolved(@NotNull GrReferenceExpression referenceExpression) { PsiElement refNameElement = referenceExpression.getReferenceNameElement(); if (refNameElement != null && referenceExpression.getQualifier() == null) { @@ -485,6 +520,10 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { @Override public void visitMethod(GrMethod method) { + if (!method.isConstructor()) { + myHolder.createInfoAnnotation(method.getNameIdentifierGroovy(), null).setTextAttributes(DefaultHighlighter.METHOD_DECLARATION); + } + checkMethodDefinitionModifiers(myHolder, method); checkMethodWithTypeParamsShouldHaveReturnType(myHolder, method); checkInnerMethod(myHolder, method); @@ -576,6 +615,8 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { checkName(variable); if (variable instanceof GrMember) { highlightMember(myHolder, ((GrMember)variable)); + } else { + highlightVariable(variable, variable.getNameIdentifierGroovy()); } PsiNamedElement duplicate = ResolveUtil diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java index 4fe8253617cd..01b3c3dde025 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java @@ -94,6 +94,18 @@ public class DefaultHighlighter { public static TextAttributesKey ANNOTATION = TextAttributesKey.createTextAttributesKey(ANNOTATION_ID, HighlightInfoType.ANNOTATION_NAME.getAttributesKey().getDefaultAttributes()); + public static TextAttributesKey LOCAL_VARIABLE = TextAttributesKey.createTextAttributesKey("Groovy var", + HighlightInfoType.LOCAL_VARIABLE.getAttributesKey().getDefaultAttributes()); + public static TextAttributesKey REASSIGNED_LOCAL_VARIABLE = TextAttributesKey.createTextAttributesKey("Groovy reassigned var", + HighlightInfoType.REASSIGNED_LOCAL_VARIABLE.getAttributesKey().getDefaultAttributes()); + public static TextAttributesKey PARAMETER = TextAttributesKey.createTextAttributesKey("Groovy parameter", + HighlightInfoType.PARAMETER.getAttributesKey().getDefaultAttributes()); + public static TextAttributesKey REASSIGNED_PARAMETER = TextAttributesKey.createTextAttributesKey("Groovy reassigned parameter", + HighlightInfoType.REASSIGNED_PARAMETER.getAttributesKey().getDefaultAttributes()); + + public static TextAttributesKey METHOD_DECLARATION = TextAttributesKey.createTextAttributesKey("Groovy method declaration", + HighlightInfoType.METHOD_DECLARATION.getAttributesKey().getDefaultAttributes()); + public static TextAttributesKey INSTANCE_FIELD = TextAttributesKey.createTextAttributesKey(INSTANCE_FIELD_ID, HighlightInfoType.INSTANCE_FIELD.getAttributesKey().getDefaultAttributes()); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy index 1f884636fffc..49566e1a1486 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy @@ -691,4 +691,8 @@ public class CorrectImplementor implements ActionListener { ''') myFixture.testHighlighting(true, false, false) } + + public void testReassignedHighlighting() { + myFixture.testHighlighting(true, true, true, getTestName(false) + ".groovy"); + } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy b/plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy new file mode 100644 index 000000000000..206ee8a22749 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy @@ -0,0 +1,13 @@ +def method(int param1, int param2) { + int var1 = 0 + int var2 = 1 + if (param1 == 1) { + param2 = var2 = 2 + } + println var1 + + var2 + + param1 + + param2 +} + +method(239, 42) \ No newline at end of file From c59b3ebbe28dd850c3629c9d6fab1bdf928a0fbf Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 13 Mar 2012 16:01:01 +0400 Subject: [PATCH 4/5] ui for IDEA-82573 Extend color scheme features for Groovy sources --- .../highlighter/GroovyColorsAndFontsPage.java | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java index bd6bbb63d9ab..19a5b080e094 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java @@ -67,10 +67,15 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { new AttributesDescriptor("Unresolved reference access", DefaultHighlighter.UNRESOLVED_ACCESS), new AttributesDescriptor("List/map to object conversion", DefaultHighlighter.LITERAL_CONVERSION), new AttributesDescriptor("Annotation", DefaultHighlighter.ANNOTATION), + new AttributesDescriptor("Local variable", DefaultHighlighter.LOCAL_VARIABLE), + new AttributesDescriptor("Reassigned local variable", DefaultHighlighter.REASSIGNED_LOCAL_VARIABLE), + new AttributesDescriptor("Parameter", DefaultHighlighter.PARAMETER), + new AttributesDescriptor("Reassigned parameter", DefaultHighlighter.REASSIGNED_PARAMETER), new AttributesDescriptor("Static field", DefaultHighlighter.STATIC_FIELD), new AttributesDescriptor("Instance field", DefaultHighlighter.INSTANCE_FIELD), new AttributesDescriptor("Instance method call", DefaultHighlighter.METHOD_CALL), new AttributesDescriptor("Static method call", DefaultHighlighter.STATIC_METHOD_ACCESS), + new AttributesDescriptor("Method declaration", DefaultHighlighter.METHOD_DECLARATION), new AttributesDescriptor("Class reference", DefaultHighlighter.CLASS_REFERENCE), new AttributesDescriptor("Map key accessed as a property", DefaultHighlighter.MAP_KEY), new AttributesDescriptor("Instance property reference", DefaultHighlighter.INSTANCE_PROPERTY_REFERENCE), @@ -103,10 +108,11 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { " def property\n" + "//This is a line comment\n" + "/* This is a block comment */\n" + - " static def foo(int i) {\n" + - " Map map = [key:1, b:2]\n" + + " static def foo(int i, int j) {\n" + + " Map map = [key:1, b:2]\n" + + " j++\n" + " print map.key\n" + - " return [i, i, property]\n" + + " return [i, property]\n" + " }\n" + " static def panel = new JPanel()\n" + "}\n" + @@ -114,8 +120,9 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { "Demo.panel.size = " + "Demo.foo(\"123${456}789\".toInteger()) \n" + "'JetBrains'.matches(/Jw+Bw+/) \n" + - "def x=1 + unresolved\n" + - "def f1 = []\n" + + "def x=1 + unresolved\n" + + "def f1 = []\n" + + "f1 = [2]\n" + "File f=['path']\n" + "print new Demo().property\n" + "print '\\n \\x'" @@ -140,6 +147,11 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { map.put("staticprop", DefaultHighlighter.STATIC_PROPERTY_REFERENCE); map.put("validescape", DefaultHighlighter.VALID_STRING_ESCAPE); map.put("invalidescape", DefaultHighlighter.INVALID_STRING_ESCAPE); + map.put("local", DefaultHighlighter.LOCAL_VARIABLE); + map.put("reLocal", DefaultHighlighter.REASSIGNED_LOCAL_VARIABLE); + map.put("param", DefaultHighlighter.PARAMETER); + map.put("reParam", DefaultHighlighter.REASSIGNED_PARAMETER); + map.put("method", DefaultHighlighter.METHOD_DECLARATION); return map; } } From a1b9defdb54609b1392aae7a1e179f1380295f11 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 13 Mar 2012 16:05:58 +0400 Subject: [PATCH 5/5] postfix operation is a reassignment (IDEA-82573) --- .../jetbrains/plugins/groovy/annotator/GroovyAnnotator.java | 4 +++- .../testdata/highlighting/ReassignedHighlighting.groovy | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index ca36b1793390..841070ed0cad 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -287,7 +287,9 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { boolean hasAssignment = var.getInitializerGroovy() != null || var instanceof GrParameter; SearchScope scope = method == null ? GlobalSearchScope.projectScope(var.getProject()) : new LocalSearchScope(method); for (PsiReference reference : ReferencesSearch.search(var, scope).findAll()) { - if (reference instanceof GrReferenceExpression && PsiUtil.isLValue((GrReferenceExpression)reference)) { + if (reference instanceof GrReferenceExpression && + (PsiUtil.isLValue((GrReferenceExpression)reference) || + ((GrReferenceExpression)reference).getParent() instanceof GrPostfixExpression)) { if (hasAssignment) { return true; } diff --git a/plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy b/plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy index 206ee8a22749..22ba7339ab32 100644 --- a/plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy +++ b/plugins/groovy/testdata/highlighting/ReassignedHighlighting.groovy @@ -1,8 +1,10 @@ def method(int param1, int param2) { int var1 = 0 int var2 = 1 + int var3 = 1 if (param1 == 1) { param2 = var2 = 2 + var3++ } println var1 + var2 +