diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java index 0ba0b63b8b7d..09fe465fab21 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java @@ -139,6 +139,10 @@ public class GrAccessorMethodImpl extends LightMethodBuilder implements GrAccess @Override public boolean hasModifierProperty(@NotNull String name) { - return PsiModifier.ABSTRACT.equals(name) && GrTraitUtil.isTrait(getContainingClass()) || super.hasModifierProperty(name); + if (GrTraitUtil.isTrait(getContainingClass())) { + if (PsiModifier.ABSTRACT.equals(name)) return true; + if (PsiModifier.FINAL.equals(name)) return false; + } + return super.hasModifierProperty(name); } } 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 fc66683d19f2..ab7adcba2f72 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 @@ -120,7 +120,7 @@ class B implements A { ''' } - void 'test traits have only abstract methods'() { + void 'test traits have only abstract and non-final methods'() { def file = myFixture.addFileToProject('T.groovy', '''\ trait T { def foo @@ -132,6 +132,7 @@ trait T { def definition = file.classes[0] as GrTypeDefinition for (method in definition.methods) { assert method.hasModifierProperty(GrModifier.ABSTRACT) + assert !method.hasModifierProperty(GrModifier.FINAL) } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/overriding/GroovyOverrideImplementTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/overriding/GroovyOverrideImplementTest.groovy index 8a9907be53e0..21aea5ba36ed 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/overriding/GroovyOverrideImplementTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/overriding/GroovyOverrideImplementTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -215,6 +215,38 @@ class Test extends Base { fix.invoke(myFixture.project, myFixture.editor, myFixture.file) } + void 'test abstract final trait properties'() { + myFixture.addFileToProject('T.groovy', '''\ +trait T { + abstract foo + abstract final bar +} +''') + myFixture.configureByText('classes.groovy', '''\ +class A implements T { +} +''') + myFixture.launchAction myFixture.findSingleIntention('Implement methods') + myFixture.checkResult('''\ +class A implements T { + @Override + Object getFoo() { + return null + } + + @Override + void setFoo(Object foo) { + + } + + @Override + Object getBar() { + return null + } +} +''') + } + private def generateImplementation(PsiMethod method) { WriteCommandAction.runWriteCommandAction project, { GrTypeDefinition clazz = (myFixture.file as PsiClassOwner).classes[0] as GrTypeDefinition