diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 7aee00157951..ea12ceb3ed2d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -334,4 +334,6 @@ top.level.class.maynot.have.protected.modifier=Top level class may not have 'pro property.missing=propertyMissing attribute.name.expected=Attribute name expected java.style.for.each.statement.requires.a.type.declaration=Java-style for-each statement requires a type declaration -enums.may.not.have.extends.clause=Enums may not have 'extends' clause \ No newline at end of file +enums.may.not.have.extends.clause=Enums may not have 'extends' clause +super.cannot.be.used.in.static.context='super' cannot be used in static context +qualified.0.is.allowed.only.in.nested.or.inner.classes=Qualified {0} is allowed only in nested/inner classes \ No newline at end of file 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 a0c9e87c6bbf..c44b855edace 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -1032,6 +1032,13 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { @Override public void visitSuperExpression(GrSuperReferenceExpression superExpression) { + final GrReferenceExpression qualifier = superExpression.getQualifier(); + if (qualifier == null) { + final GrMember container = PsiTreeUtil.getParentOfType(superExpression, GrMethod.class, GrClassInitializer.class); + if (container != null && container.hasModifierProperty(STATIC)) { + myHolder.createErrorAnnotation(superExpression, GroovyBundle.message("super.cannot.be.used.in.static.context")); + } + } checkThisOrSuperReferenceExpression(superExpression, myHolder); } @@ -1409,23 +1416,15 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { return PsiTreeUtil.getParentOfType(statement, GrLoopStatement.class, true, GrClosableBlock.class, GrMember.class, GroovyFile.class); } - private static void checkThisOrSuperReferenceExpression(GrExpression expression, AnnotationHolder holder) { - if (GroovyConfigUtils.getInstance().isVersionAtLeast(expression, GroovyConfigUtils.GROOVY1_8)) return; - - final GrReferenceExpression qualifier = expression instanceof GrThisReferenceExpression - ? ((GrThisReferenceExpression)expression).getQualifier() - : ((GrSuperReferenceExpression)expression).getQualifier(); - if (qualifier == null) { - if (expression instanceof GrSuperReferenceExpression) { //'this' refers to java.lang.Class in static context - final GrMethod method = PsiTreeUtil.getParentOfType(expression, GrMethod.class); - if (method != null && method.hasModifierProperty(STATIC)) { - Annotation annotation = - holder.createInfoAnnotation(expression, GroovyBundle.message("cannot.reference.nonstatic", expression.getText())); - annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS); - } + private static void checkThisOrSuperReferenceExpression(GrThisSuperReferenceExpression expression, AnnotationHolder holder) { + final GrReferenceExpression qualifier = expression.getQualifier(); + if (qualifier != null) { + GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(expression, GrTypeDefinition.class, true, GroovyFile.class); + if (containingClass == null || containingClass.getContainingClass() == null && !containingClass.isAnonymous()) { + holder.createErrorAnnotation(expression, GroovyBundle.message("qualified.0.is.allowed.only.in.nested.or.inner.classes", expression.getReferenceName())); + return; } - } - else { + final PsiElement resolved = qualifier.resolve(); if (resolved instanceof PsiClass) { if (PsiTreeUtil.isAncestor(resolved, expression, true)) { @@ -1442,7 +1441,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } } else { - holder.createErrorAnnotation(qualifier, GroovyBundle.message("unknown.class", qualifier.getText())); + holder.createErrorAnnotation(qualifier, GroovyBundle.message("cannot.resolve", qualifier.getText())); } } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/Groovy16HighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/Groovy16HighlightingTest.java deleted file mode 100644 index fa40b8c5134a..000000000000 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/Groovy16HighlightingTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2000-2009 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 org.jetbrains.plugins.groovy.lang; - -import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection; -import org.jetbrains.plugins.groovy.util.TestUtils; - -/** - * @author peter - */ -@SuppressWarnings({"JUnitTestClassNamingConvention"}) -public class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase { - private static final DefaultLightProjectDescriptor DESCRIPTOR_1_6 = new DefaultLightProjectDescriptor() { - @Override - public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); - final VirtualFile groovyJar = - JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_6LibraryName() + "!/"); - modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); - modifiableModel.commit(); - } - }; - - @Override - protected String getBasePath() { - return TestUtils.getTestDataPath() + "highlighting/"; - } - - @NotNull - @Override - protected LightProjectDescriptor getProjectDescriptor() { - return DESCRIPTOR_1_6; - } - - private void doTest(LocalInspectionTool... tools) { - myFixture.enableInspections(tools); - myFixture.testHighlighting(true, false, false, getTestName(false) + ".groovy"); - } - - public void testInnerEnum() throws Exception {doTest();} - public void testSuperWithNotEnclosingClass() throws Throwable {doTest();} - public void testThisWithWrongQualifier() throws Throwable {doTest();} - - public void testImplicitEnumCoercion1_6() { - doTest(new GroovyAssignabilityCheckInspection()); - } - - public void testSlashyStrings() {doTest();} - public void testDiamonds() {doTest();} -} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy new file mode 100644 index 000000000000..40abb4b9a486 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2009 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 org.jetbrains.plugins.groovy.lang.highlighting +import com.intellij.codeInspection.LocalInspectionTool +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection +import org.jetbrains.plugins.groovy.util.TestUtils +/** + * @author peter + */ +@SuppressWarnings(["JUnitTestClassNamingConvention"]) +public class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase { + @NotNull + final LightProjectDescriptor projectDescriptor = new DefaultLightProjectDescriptor() { + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + final Library.ModifiableModel modifiableModel = model.moduleLibraryTable.createLibrary("GROOVY").modifiableModel + final VirtualFile groovyJar = JarFileSystem.instance.refreshAndFindFileByPath("$TestUtils.mockGroovy1_6LibraryName!/") + modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES) + modifiableModel.commit() + } + } + + final String basePath = TestUtils.testDataPath + "highlighting/" + + private void doTest(LocalInspectionTool... tools) { + myFixture.enableInspections(tools) + myFixture.testHighlighting(true, false, false, getTestName(false) + ".groovy") + } + + public void testInnerEnum() { doTest() } + + public void testSuperWithNotEnclosingClass() { doTest() } + + public void testThisWithWrongQualifier() { doTest() } + + public void testImplicitEnumCoercion1_6() { doTest(new GroovyAssignabilityCheckInspection()) } + + public void testSlashyStrings() { doTest() } + + public void testDiamonds() { doTest() } +} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy index 90cecfa9decf..93a3fc1801b9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy @@ -14,6 +14,7 @@ * limitations under the License. */ package org.jetbrains.plugins.groovy.lang.highlighting + import com.intellij.testFramework.IdeaTestUtil import com.siyeh.ig.junit.JUnitAbstractTestClassNamingConventionInspection import com.siyeh.ig.junit.JUnitTestClassNamingConventionInspection @@ -21,18 +22,7 @@ import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilit import org.jetbrains.plugins.groovy.codeInspection.confusing.GrUnusedIncDecInspection import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection -//import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection -//import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyResultOfAssignmentUsedInspection -//import org.jetbrains.plugins.groovy.codeInspection.bugs.* -//import org.jetbrains.plugins.groovy.codeInspection.confusing.* -//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection -//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection -//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryReturnInspection -//import org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMethodInspection -//import org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection -//import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection -//import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection -//import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection + /** * @author peter */ diff --git a/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy b/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy index 275f3a1a0f73..7663247ad903 100644 --- a/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy +++ b/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy @@ -1,5 +1,5 @@ class X{ def foo() { - String.super.toString() + String.super.toString() } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy b/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy index a23fafece73a..04e89b5c7d6e 100644 --- a/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy +++ b/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy @@ -1,6 +1,6 @@ class X{ def foo(){ X x=new X(); - x.this.foo(); + x.this.foo(); } } \ No newline at end of file