From f40be3d3e0986c14ef6e3766d48dbe1dbd143108 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 15 Apr 2013 18:55:32 +0400 Subject: [PATCH] IDEA-105292 IDEA 12.1.1 doesn't allow abstract methods in groovy enums (new feature in groovy 2.1.3) --- .../groovy/annotator/GroovyAnnotator.java | 7 +++-- .../modifiers/GrModifierListImpl.java | 27 +++++++++++++++++-- .../convertToJava/ClassGenerator.java | 3 +-- .../convertToJava/ModifierListGenerator.java | 7 ++--- 4 files changed, 33 insertions(+), 11 deletions(-) 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 0adea8580c64..f507b0ceaab7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -1324,8 +1324,7 @@ public class GroovyAnnotator extends GroovyElementVisitor { } Map errors = ContainerUtil.newHashMap(); - CustomAnnotationChecker.checkAnnotationArguments(errors, anno, annotation.getClassReference(), annotationArgumentList.getAttributes(), - true); + CustomAnnotationChecker.checkAnnotationArguments(errors, anno, annotation.getClassReference(), annotationArgumentList.getAttributes(), true); for (Map.Entry entry : errors.entrySet()) { myHolder.createErrorAnnotation(entry.getKey(), entry.getValue()); } @@ -1590,7 +1589,7 @@ public class GroovyAnnotator extends GroovyElementVisitor { PsiModifierList typeDefModifiersList = containingTypeDef.getModifierList(); LOG.assertTrue(typeDefModifiersList != null, "modifiers list must be not null"); - if (!typeDefModifiersList.hasExplicitModifier(ABSTRACT) && isMethodAbstract) { + if (!typeDefModifiersList.hasModifierProperty(ABSTRACT) && isMethodAbstract) { final Annotation annotation = holder.createErrorAnnotation(modifiersList, GroovyBundle.message("only.abstract.class.can.have.abstract.method")); registerMakeAbstractMethodNotAbstractFix(annotation, method, true); @@ -1653,7 +1652,7 @@ public class GroovyAnnotator extends GroovyElementVisitor { } } - if (modifiersList.hasModifierProperty(ABSTRACT) && modifiersList.hasModifierProperty(FINAL)) { + if (!typeDefinition.isEnum() && modifiersList.hasModifierProperty(ABSTRACT) && modifiersList.hasModifierProperty(FINAL)) { final Annotation annotation = holder.createErrorAnnotation(modifiersList, GroovyBundle.message("illegal.combination.of.modifiers.abstract.and.final")); annotation.registerFix(new GrModifierFix(typeDefinition, modifiersList, FINAL, false, false)); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java index 9eff368b816b..44d9c76b165f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java @@ -30,6 +30,7 @@ import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; @@ -38,11 +39,14 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition; import org.jetbrains.plugins.groovy.lang.psi.impl.GrStubElementBase; import org.jetbrains.plugins.groovy.lang.psi.stubs.GrModifierListStub; @@ -203,12 +207,31 @@ public class GrModifierListImpl extends GrStubElementBase im } if (owner instanceof GrTypeDefinition) { + final GrTypeDefinition clazz = (GrTypeDefinition)owner; + if (modifier.equals(GrModifier.STATIC)) { - final PsiClass containingClass = ((GrTypeDefinition)owner).getContainingClass(); + final PsiClass containingClass = clazz.getContainingClass(); return containingClass != null && containingClass.isInterface(); } if (modifier.equals(GrModifier.ABSTRACT)) { - return ((GrTypeDefinition)owner).isInterface(); + if (clazz.isInterface()) return true; + if (clazz.isEnum() && + GroovyConfigUtils.getInstance().isVersionAtLeast(modifierList, GroovyConfigUtils.GROOVY2_0)) { + for (GrMethod method : clazz.getCodeMethods()) { + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return true; + } + } + } + if (modifier.equals(GrModifier.FINAL)) { + if (clazz.isEnum()) { + final GrField[] fields = clazz.getFields(); + for (GrField field : fields) { + if (field instanceof GrEnumConstant && ((GrEnumConstant)field).getInitializingClass() != null) { + return false; + } + } + return true; + } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java index adaaa3ff3a9f..431520a74c4f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java @@ -71,8 +71,7 @@ public class ClassGenerator { boolean isAnnotationType = typeDefinition.isAnnotationType(); boolean isInterface = typeDefinition.isInterface(); - ModifierListGenerator.writeClassModifiers(text, typeDefinition.getModifierList(), typeDefinition.isInterface(), toplevel, - classItemGenerator.generateAnnotations()); + ModifierListGenerator.writeClassModifiers(text, typeDefinition.getModifierList(), typeDefinition.isInterface(), typeDefinition.isEnum(), toplevel, classItemGenerator.generateAnnotations()); if (isAnnotationType) { text.append('@'); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java index 3f7872c97da3..41e7d2bb436a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -108,6 +108,7 @@ public class ModifierListGenerator { public static void writeClassModifiers(StringBuilder text, @Nullable PsiModifierList modifierList, boolean isInterface, + boolean isEnum, boolean toplevel, boolean generateAnnotations) { if (modifierList == null) { @@ -117,11 +118,11 @@ public class ModifierListGenerator { List allowedModifiers = new ArrayList(); allowedModifiers.add(PsiModifier.PUBLIC); - allowedModifiers.add(PsiModifier.FINAL); + if (!isEnum) allowedModifiers.add(PsiModifier.FINAL); if (!toplevel) { allowedModifiers.addAll(Arrays.asList(PsiModifier.PROTECTED, PsiModifier.PRIVATE, PsiModifier.STATIC)); } - if (!isInterface) { + if (!isInterface && !isEnum) { allowedModifiers.add(PsiModifier.ABSTRACT); }