From 2b3d3c87c4143e1cb971ac35fefbfba8b0e06b2e Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Mon, 10 Oct 2016 16:42:51 +0300 Subject: [PATCH] [groovy] do not allow modifier 'static' on toplevel classes (IDEA-162294) --- .../org/jetbrains/plugins/groovy/GroovyBundle.properties | 1 + .../plugins/groovy/annotator/GroovyAnnotator.java | 6 ++++++ .../src/org/jetbrains/plugins/groovy/annotator/util.kt | 6 ++++++ .../lang/highlighting/Groovy16HighlightingTest.groovy | 9 +++++++++ .../lang/highlighting/Groovy23HighlightingTest.groovy | 9 ++++++++- 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 5ab741f0a97a..a7a6c19fc75e 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -180,6 +180,7 @@ illegal.combination.of.modifiers=Illegal combination of modifiers illegal.combination.of.modifiers.abstract.and.final=Illegal combination of modifiers 'abstract' and 'final' modifier.volatile.not.allowed.here=Modifier 'volatile' not allowed here modifier.transient.not.allowed.here=Modifier 'transient' not allowed here +modifier.0.not.allowed=Modifier ''{0}'' not allowed here intarface.cannot.have.modifier.final=Interface cannot have modifier 'final' script.method.cannot.have.modifier.abstract=Script method cannot have modifier 'abstract' script.cannot.have.modifier.native=Script cannot have modifier 'native' diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 208ef178f185..10b5d9b2470b 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -1906,6 +1906,12 @@ public class GroovyAnnotator extends GroovyElementVisitor { if (typeDefinition.isInterface()) { checkModifierIsNotAllowed(modifiersList, PsiModifier.FINAL, GroovyBundle.message("intarface.cannot.have.modifier.final"), holder); } + + if (GroovyConfigUtils.getInstance().isVersionAtLeast(typeDefinition, GroovyConfigUtils.GROOVY1_8)) { + if (typeDefinition.getContainingClass() == null && !(typeDefinition instanceof GrTraitTypeDefinition)) { + checkModifierIsNotAllowed(modifiersList, PsiModifier.STATIC, holder); + } + } } private static void checkDuplicateModifiers(AnnotationHolder holder, @NotNull GrModifierList list, PsiMember member) { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/util.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/util.kt index 8031181f7273..2fee48dd15fc 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/util.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/util.kt @@ -38,6 +38,12 @@ internal fun checkVariableModifiers(holder: AnnotationHolder, variableDeclaratio } } +internal fun checkModifierIsNotAllowed(modifierList: GrModifierList, + @GrModifierConstant modifier: String, + holder: AnnotationHolder) { + checkModifierIsNotAllowed(modifierList, modifier, GroovyBundle.message("modifier.0.not.allowed", modifier), holder) +} + internal fun checkModifierIsNotAllowed(modifierList: GrModifierList, @GrModifierConstant modifier: String, message: String?, 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 index 040fe30417b5..999fc43b9d15 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy @@ -62,4 +62,13 @@ class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase { void testSlashyStrings() { doTest() } void testDiamonds() { doTest() } + + void 'test static modifier on toplevel definition is allowed'() { + myFixture.with { + configureByText '_.groovy', '''\ +static class A {} +static interface A {} +''' + } + } } \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy23HighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy23HighlightingTest.groovy index 4aec6bc461b1..8226aabf53d6 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy23HighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy23HighlightingTest.groovy @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.lang.highlighting import com.intellij.codeInsight.generation.OverrideImplementExploreUtil import com.intellij.codeInspection.InspectionProfileEntry -import com.intellij.psi.PsiElement import com.intellij.psi.util.PsiTreeUtil import com.intellij.testFramework.LightProjectDescriptor import org.jetbrains.annotations.NotNull @@ -270,5 +269,13 @@ class A { } } + void 'test static modifier on toplevel definition (not trait) is not allowed'() { + testHighlighting '''\ +static class A {} +static interface I {} +static trait T {} +''' + } + final InspectionProfileEntry[] customInspections = [new GroovyAssignabilityCheckInspection(), new GrUnresolvedAccessInspection()] }