From 35f31ea77d0d8cb3bb21a310fa839f03a0331d66 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Fri, 26 Aug 2011 10:43:26 +0400 Subject: [PATCH] IDEA-67218 enum default constructors don't support maps --- .../plugins/groovy/GroovyBundle.properties | 3 ++- .../groovy/annotator/GroovyAnnotator.java | 17 +++++++++++++++++ .../GroovyAssignabilityCheckInspection.java | 11 +++++++---- .../plugins/groovy/lang/psi/util/PsiUtil.java | 3 ++- .../groovy/lang/GroovyHighlightingTest.java | 4 ++++ .../EnumConstantConstructors.groovy | 11 +++++++++++ 6 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 plugins/groovy/testdata/highlighting/EnumConstantConstructors.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index e2ce9d7a72fc..6477b4dbe7f3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -353,4 +353,5 @@ no.super.method.found=No super methods found wrong.package.name=Package name ''{0}'' does not corresponding to the file path ''{1}'' cannot.assign.string.to.enum.0=Cannot assign string to enum ''{0}'' cannot.find.enum.constant.0.in.enum.1=Cannot find enum constant ''{0}'' in enum ''{1}'' -recursive.constructor.invocation=Recursive constructor invocation \ No newline at end of file +recursive.constructor.invocation=Recursive constructor invocation +the.usage.of.a.map.entry.expression.to.initialize.an.enum.is.currently.not.supported=The usage of a map entry expression to initialize an Enum is currently not supported \ 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 706c123a585f..63696f24949f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -87,6 +87,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; @@ -389,6 +390,22 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { checkRecursiveConstructors(holder, constructors); } + @Override + public void visitEnumConstant(GrEnumConstant enumConstant) { + super.visitEnumConstant(enumConstant); + final GrArgumentList argumentList = enumConstant.getArgumentList(); + + if (argumentList!=null && argumentList.getNamedArguments().length > 0 && argumentList.getExpressionArguments().length == 0) { + final PsiMethod constructor = enumConstant.resolveConstructor(); + if (constructor != null) { + if (!PsiUtil.isConstructorHasRequiredParameters(constructor)) { + myHolder.createErrorAnnotation(argumentList, GroovyBundle.message("the.usage.of.a.map.entry.expression.to.initialize.an.enum.is.currently.not.supported")); + } + } + + } + } + private static void checkRecursiveConstructors(AnnotationHolder holder, PsiMethod[] constructors) { Map nodes = new HashMap(constructors.length); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java index 8b017885263d..acd154787ea4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java @@ -45,10 +45,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrBuilderMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; @@ -333,6 +330,12 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { checkMethodCall(applicationStatement); } + @Override + public void visitEnumConstant(GrEnumConstant enumConstant) { + super.visitEnumConstant(enumConstant); + checkConstructorCall(enumConstant, enumConstant); + } + private void checkNamedArgumentsType(GrCall call) { GrNamedArgument[] namedArguments = PsiUtil.getFirstMapNamedArguments(call); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index 2e1b15b7a1f9..137df6c933ce 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -200,7 +200,8 @@ public class PsiUtil { } @Nullable public static PsiType[] getArgumentTypes(PsiElement place, boolean nullAsBottom, @Nullable GrExpression stopAt) { - PsiElement parent = place.getParent(); + PsiElement parent = place instanceof GrEnumConstant ? place : place.getParent(); + if (parent instanceof GrCall) { GrCall call = (GrCall)parent; GrNamedArgument[] namedArgs = call.getNamedArguments(); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index c23081783191..82d520402f89 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -460,4 +460,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testRecursiveConstructors() { doTest(); } + + public void testEnumConstantConstructors() { + doTest(new GroovyAssignabilityCheckInspection()); + } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/EnumConstantConstructors.groovy b/plugins/groovy/testdata/highlighting/EnumConstantConstructors.groovy new file mode 100644 index 000000000000..97926dd7b96f --- /dev/null +++ b/plugins/groovy/testdata/highlighting/EnumConstantConstructors.groovy @@ -0,0 +1,11 @@ +enum E { + a, + b(), + c(a:2), + d(1), + e(1, 2), + f(1, 2){} + + def E(int x){} + def E(){} +} \ No newline at end of file