From a29951851d1b20e58d84f5fd0bef7fc04261c6ee Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Sun, 6 May 2012 13:32:13 +0400 Subject: [PATCH] IDEA-68175 multi-signature closure types --- .../groovy/annotator/GroovyAnnotator.java | 2 +- .../GroovyAssignabilityCheckInspection.java | 2 +- .../gpp/GppClosureParameterTypeProvider.java | 2 +- .../gpp/GppExpectedTypesContributor.java | 2 +- .../plugins/groovy/gpp/GppTypeConverter.java | 6 +- .../ConvertClosureToMethodIntention.java | 8 +- .../ConvertMapToClassIntention.java | 2 +- .../ConvertParameterToMapEntryIntention.java | 4 +- .../GroovyParameterInfoHandler.java | 144 ++++----- .../lang/psi/GroovyPsiElementFactory.java | 2 +- .../GrClosureSignature.java | 11 +- .../psi/api/signatures/GrMultiSignature.java | 49 +++ .../GrRecursiveSignatureVisitor.java} | 27 +- .../lang/psi/api/signatures/GrSignature.java | 33 ++ .../api/signatures/GrSignatureVisitor.java | 31 ++ .../controlFlow/impl/ArgumentInstruction.java | 6 +- .../GroovyExpectedTypesProvider.java | 2 +- .../groovy/lang/psi/impl/GrClosureType.java | 55 +++- .../psi/impl/GroovyPsiElementFactoryImpl.java | 6 +- .../GrClosureSignatureImpl.java | 70 +++- .../GrClosureSignatureUtil.java | 302 +++++++++++++----- .../impl/signatures/GrMultiSignatureImpl.java | 73 +++++ .../GrAssignmentExpressionImpl.java | 10 +- .../expressions/GrBinaryExpressionImpl.java | 11 +- .../GrReferenceExpressionImpl.java | 5 +- .../statements/expressions/TypesUtil.java | 24 +- .../arithmetic/GrUnaryExpressionImpl.java | 2 +- .../DefaultCallExpressionTypeCalculator.java | 13 +- .../expressions/path/GrIndexPropertyImpl.java | 16 +- .../types/GrCurriedClosureSignatureImpl.java | 88 ----- .../plugins/groovy/lang/psi/util/PsiUtil.java | 32 +- .../groovy/lang/resolve/ResolveUtil.java | 11 +- .../processors/MethodResolverProcessor.java | 4 +- .../processors/SubstitutorComputer.java | 4 +- .../GrChangeSignatureUsageProcessor.java | 2 +- .../GrMethodCallUsageInfo.java | 4 +- .../changeSignature/GrMethodConflictUtil.java | 55 ++-- .../AnonymousFromMapGenerator.java | 6 +- .../convertToJava/ArgumentListGenerator.java | 4 +- .../convertToJava/ClassItemGeneratorImpl.java | 4 +- .../convertToJava/CodeBlockGenerator.java | 2 +- .../convertToJava/ExpressionGenerator.java | 4 +- .../convertToJava/TypeProvider.java | 4 +- .../GrIntroduceClosureParameterProcessor.java | 4 +- .../GroovyIntroduceParameterUtil.java | 4 +- ...troduceParameterMethodUsagesProcessor.java | 4 +- .../java2groovy/OldReferencesResolver.java | 4 +- .../groovy/lang/GroovyHighlightingTest.groovy | 36 +++ .../codeBlock/memberPointer.java | 2 +- 49 files changed, 797 insertions(+), 401 deletions(-) rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/{types => signatures}/GrClosureSignature.java (77%) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrMultiSignature.java rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/{types/GrCurriedClosureSignature.java => signatures/GrRecursiveSignatureVisitor.java} (57%) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignature.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignatureVisitor.java rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/{types => signatures}/GrClosureSignatureImpl.java (66%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/{types => signatures}/GrClosureSignatureUtil.java (71%) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrMultiSignatureImpl.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCurriedClosureSignatureImpl.java 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 e635bfcee048..98358c2d2891 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -103,9 +103,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.*; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner; import org.jetbrains.plugins.groovy.lang.psi.impl.TypeInferenceHelper; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; 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 50ee318dea07..d12ed7428ad5 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 @@ -54,8 +54,8 @@ 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; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java index 24bf499e5247..6b9f4a2d19cc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppClosureParameterTypeProvider.java @@ -17,7 +17,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.AbstractClosureParameterEnhancer; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppExpectedTypesContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppExpectedTypesContributor.java index 67dd997c81db..0cf26664818f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppExpectedTypesContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppExpectedTypesContributor.java @@ -15,7 +15,7 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesPr import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SubtypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.ArrayList; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java index b5265a1d8613..a3f84e14109c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java @@ -9,12 +9,12 @@ import org.jetbrains.plugins.groovy.findUsages.LiteralConstructorReference; import org.jetbrains.plugins.groovy.lang.psi.GrTypeConverter; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; /** * @author peter @@ -85,7 +85,7 @@ public class GppTypeConverter extends GrTypeConverter { } public static boolean isClosureOverride(PsiType[] methodParameters, GrClosureType closureType, GroovyPsiElement context) { - final GrClosureSignature signature = closureType.getSignature(); + final GrSignature signature = closureType.getSignature(); if (methodParameters != null && GrClosureSignatureUtil.isSignatureApplicable(signature, methodParameters, context)) { return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java index 3cf7aadd7c52..fb034d3db774 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertClosureToMethodIntention.java @@ -39,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; @@ -47,9 +48,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.Collection; @@ -123,8 +123,8 @@ public class ConvertClosureToMethodIntention extends Intention { LOG.assertTrue(initializer != null); final PsiType type = initializer.getType(); LOG.assertTrue(type instanceof GrClosureType); - final GrClosureSignature signature = ((GrClosureType)type).getSignature(); - final List signatures = GrClosureSignatureUtil.generateAllMethodSignaturesByClosureSignature(fieldName, signature); + final GrSignature signature = ((GrClosureType)type).getSignature(); + final List signatures = GrClosureSignatureUtil.generateAllMethodSignaturesBySignature(fieldName, signature); for (MethodSignature s : signatures) { final PsiMethod method = MethodSignatureUtil.findMethodBySignature(containingClass, s, true); if (method != null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMapToClassIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMapToClassIntention.java index dfe33a2b2a5d..edf478bde9ac 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMapToClassIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertMapToClassIntention.java @@ -58,8 +58,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere 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.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.List; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java index 90d37f6729c6..29f8709945e9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/parameterToEntry/ConvertParameterToMapEntryIntention.java @@ -47,6 +47,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; @@ -60,10 +61,9 @@ 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.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.members.GrMethodImpl; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.refactoring.GroovyValidationUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java index a211f82bf3ad..52c0adea52fa 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java @@ -20,13 +20,11 @@ import com.intellij.codeInsight.completion.JavaCompletionUtil; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.parameterInfo.*; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.HashSet; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; @@ -35,6 +33,8 @@ import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; @@ -42,7 +42,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod; @@ -131,32 +130,25 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc } @SuppressWarnings("unchecked") - public void showParameterInfo(@NotNull GroovyPsiElement place, CreateParameterInfoContext context) { + public void showParameterInfo(@NotNull GroovyPsiElement place, @NotNull CreateParameterInfoContext context) { GroovyResolveResult[] variants = ResolveUtil.getCallVariants(place); final List elementToShow = new ArrayList(); final PsiElement parent = place.getParent(); if (parent instanceof GrMethodCall) { - final Condition methodsOrClosures = new Condition() { - public boolean value(GroovyResolveResult result) { - final PsiElement element = result.getElement(); - return element instanceof PsiMethod && !result.isInvokedOnProperty() || - element instanceof GrVariable && ((GrVariable)element).getTypeGroovy() instanceof GrClosureType; - } - }; final GrExpression invoked = ((GrMethodCall)parent).getInvokedExpression(); if (isPropertyOrVariableInvoked(invoked)) { final PsiType type = invoked.getType(); if (type instanceof GrClosureType) { - elementToShow.add(type); + addSignatureVariant(elementToShow, (GrClosureType)type); } else if (type != null) { - final GroovyResolveResult[] calls = ResolveUtil.getMethodCandidates(type, "call", place, PsiUtil.getArgumentTypes(place, true)); - elementToShow.addAll(ContainerUtil.findAll(calls, methodsOrClosures)); + addMethodAndClosureVariants(elementToShow, + ResolveUtil.getMethodCandidates(type, "call", place, PsiUtil.getArgumentTypes(place, true))); } } else { - elementToShow.addAll(ContainerUtil.findAll(variants, methodsOrClosures)); + addMethodAndClosureVariants(elementToShow, variants); } } else { @@ -168,6 +160,30 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc context.showHint(place, place.getTextRange().getStartOffset(), this); } + private static void addMethodAndClosureVariants(@NotNull List elementToShow, @NotNull GroovyResolveResult[] variants) { + for (GroovyResolveResult variant : variants) { + final PsiElement element = variant.getElement(); + if (element instanceof PsiMethod) { + elementToShow.add(variant); + } + else if (element instanceof GrVariable) { + final PsiType type = ((GrVariable)element).getTypeGroovy(); + if (type instanceof GrClosureType) { + addSignatureVariant(elementToShow, (GrClosureType)type); + } + } + } + } + + private static void addSignatureVariant(@NotNull final List elementToShow, @NotNull GrClosureType type) { + type.getSignature().accept(new GrRecursiveSignatureVisitor() { + @Override + public void visitClosureSignature(GrClosureSignature signature) { + elementToShow.add(signature); + } + }); + } + private static void filterOutReflectedMethods(List toShow) { Set methods = new HashSet(); @@ -230,25 +246,21 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc } argTypes = PsiUtil.getArgumentTypes(place, false); } - else if (namedElement instanceof GrVariable) { - final PsiType type = ((GrVariable)namedElement).getTypeGroovy(); - if (type instanceof GrClosureType) { - argTypes = PsiUtil.getArgumentTypes(place, false); - parameterTypes = ((GrClosureType)type).getClosureParameterTypes(); - } - } if (argTypes == null) continue; } - else if (objects[i] instanceof GrClosureType) { - final GrClosureType type = (GrClosureType)objects[i]; + else if (objects[i] instanceof GrClosureSignature) { + final GrClosureSignature signature = (GrClosureSignature)objects[i]; argTypes = PsiUtil.getArgumentTypes(place, false); - parameterTypes = type.getClosureParameterTypes(); + parameterTypes = new PsiType[signature.getParameterCount()]; + int j = 0; + for (GrClosureParameter parameter : signature.getParameters()) { + parameterTypes[j++] = parameter.getType(); + } } else { continue Outer; } - assert parameterTypes != null; assert argTypes != null; if (parameterTypes.length <= currIndex) { @@ -360,8 +372,8 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc return; } } - else if (o instanceof GrClosureType) { - if (!((GrClosureType)o).isValid()) { + else if (o instanceof GrClosureSignature) { + if (!((GrClosureSignature)o).isValid()) { context.setUIComponentEnabled(false); return; } @@ -374,6 +386,8 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc int highlightStartOffset = -1; int highlightEndOffset = -1; + final int currentParameter = context.getCurrentParameterIndex(); + StringBuilder buffer = new StringBuilder(); @@ -393,8 +407,6 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc buffer.append('('); } - final int currentParameter = context.getCurrentParameterIndex(); - final PsiParameter[] params = method.getParameterList().getParameters(); int numParams = params.length; @@ -415,10 +427,7 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc } if (context.isUIComponentEnabled() && - (j == currentParameter || - (j == numParams - 1 && param.isVarArgs() && currentParameter >= numParams) - ) - ) { + (j == currentParameter || (j == numParams - 1 && param.isVarArgs() && currentParameter >= numParams))) { highlightStartOffset = startOffset; highlightEndOffset = endOffset; } @@ -434,23 +443,37 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc } else if (element instanceof PsiClass) { buffer.append("no parameters"); } - else if (element instanceof GrVariable) { - final PsiElement parent = context.getParameterOwner().getParent(); - if (parent == null || !parent.isValid()) { - context.setUIComponentEnabled(false); - return; - } - final PsiType type; - if (parent instanceof GrMethodCallExpression) { - type = ((GrMethodCallExpression)parent).getInvokedExpression().getType(); + else if (element instanceof GrClosureSignature) { + GrClosureParameter[] parameters = ((GrClosureSignature)element).getParameters(); + if (parameters.length > 0) { + for (int i = 0; i < parameters.length; i++) { + if (i > 0) buffer.append(", "); + + int startOffset = buffer.length(); + final PsiType psiType = parameters[i].getType(); + if (psiType == null) { + buffer.append("def"); + } + else { + buffer.append(psiType.getPresentableText()); + } + int endOffset = buffer.length(); + + if (context.isUIComponentEnabled() && + (i == currentParameter || (i == parameters.length - 1 && ((GrClosureSignature)element).isVarargs() && currentParameter >= parameters.length))) { + highlightStartOffset = startOffset; + highlightEndOffset = endOffset; + } + + final GrExpression initializer = parameters[i].getDefaultInitializer(); + if (initializer != null) { + buffer.append(" = ").append(initializer.getText()); + } + } } else { - type = ((GrVariable)element).getTypeGroovy(); + buffer.append("no parameters"); } - generateForClosureType(buffer, type); - } - else if (element instanceof GrClosureType) { - generateForClosureType(buffer, (GrClosureType)element); } final boolean isDeprecated = o instanceof PsiDocCommentOwner && ((PsiDocCommentOwner) o).isDeprecated(); @@ -466,31 +489,6 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc ); } - private static void generateForClosureType(StringBuilder buffer, PsiType type) { - if (type instanceof GrClosureType) { - GrClosureParameter[] parameters = ((GrClosureType)type).getSignature().getParameters(); - if (parameters.length > 0) { - for (int i = 0; i < parameters.length; i++) { - if (i > 0) buffer.append(", "); - final PsiType psiType = parameters[i].getType(); - if (psiType == null) { - buffer.append("def"); - } - else { - buffer.append(psiType.getPresentableText()); - } - final GrExpression initializer = parameters[i].getDefaultInitializer(); - if (initializer != null) { - buffer.append(" = ").append(initializer.getText()); - } - } - } - else { - buffer.append("no parameters"); - } - } - } - private static void appendParameterText(PsiParameter param, PsiSubstitutor substitutor, StringBuilder buffer) { if (param instanceof GrParameter) { GrParameter grParam = (GrParameter)param; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java index 6a26d225c4af..062670670b06 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java @@ -29,6 +29,7 @@ import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTag; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; @@ -45,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEn import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrClosureSignature.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrClosureSignature.java similarity index 77% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrClosureSignature.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrClosureSignature.java index d5f4938cfaae..ae788315d46b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrClosureSignature.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrClosureSignature.java @@ -13,17 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.psi.api.types; +package org.jetbrains.plugins.groovy.lang.psi.api.signatures; import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; /** * @author Maxim.Medvedev */ -public interface GrClosureSignature { +public interface GrClosureSignature extends GrSignature { + @NotNull PsiSubstitutor getSubstitutor(); @NotNull @@ -36,8 +38,7 @@ public interface GrClosureSignature { @Nullable PsiType getReturnType(); - @Nullable - GrCurriedClosureSignature curry(PsiType[] args, int position); + GrClosureSignature[] EMPTY_ARRAY = new GrClosureSignature[0]; - boolean isValid(); + boolean isCurried(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrMultiSignature.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrMultiSignature.java new file mode 100644 index 000000000000..8d59457ea7ed --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrMultiSignature.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2012 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.psi.api.signatures; + +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; + +/** + * @author Max Medvedev + */ +public interface GrMultiSignature extends GrSignature { + GrClosureSignature[] getAllSignatures(); + + GrMultiSignature EMPTY_SIGNATURE = new GrMultiSignature() { + @Override + public GrClosureSignature[] getAllSignatures() { + return GrClosureSignature.EMPTY_ARRAY; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) { + return this; + } + + @Override + public void accept(GrSignatureVisitor visitor) { + visitor.visitMultiSignature(this); + } + }; +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrCurriedClosureSignature.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrRecursiveSignatureVisitor.java similarity index 57% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrCurriedClosureSignature.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrRecursiveSignatureVisitor.java index 8f156d5461a1..27fcc896c444 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/types/GrCurriedClosureSignature.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrRecursiveSignatureVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -13,23 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.psi.api.types; - -import com.intellij.psi.PsiType; +package org.jetbrains.plugins.groovy.lang.psi.api.signatures; /** - * @author Maxim.Medvedev + * @author Max Medvedev */ -public interface GrCurriedClosureSignature extends GrClosureSignature{ - - PsiType[] getCurriedArgs(); - - /** - * - * @return position or -1 if position is right - */ - int getCurriedPosition(); - - GrClosureSignature getOriginalSignature(); +public abstract class GrRecursiveSignatureVisitor extends GrSignatureVisitor { + @Override + public void visitMultiSignature(GrMultiSignature signature) { + super.visitMultiSignature(signature); + for (GrClosureSignature s : signature.getAllSignatures()) { + s.accept(this); + } + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignature.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignature.java new file mode 100644 index 000000000000..d168f7d8a4de --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignature.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2012 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.psi.api.signatures; + +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; + +/** + * @author Max Medvedev + */ +public interface GrSignature { + boolean isValid(); + + @Nullable + GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context); + + void accept(GrSignatureVisitor visitor); +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignatureVisitor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignatureVisitor.java new file mode 100644 index 000000000000..8a0aa5a69dd8 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/signatures/GrSignatureVisitor.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2012 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.psi.api.signatures; + +/** +* @author Max Medvedev +*/ +public abstract class GrSignatureVisitor { + public void visitClosureSignature(GrClosureSignature signature){ + visitSignature(signature); + } + + public void visitSignature(GrSignature signature){} + + public void visitMultiSignature(GrMultiSignature signature){ + visitSignature(signature); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java index 9f3d4f24510c..c2d189dbe67c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java @@ -22,18 +22,18 @@ import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.MixinTypeInstruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; -import static org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil.createSignature; +import static org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil.createSignature; /** * @author Max Medvedev diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java index 378711746fb0..50b5bac05291 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java @@ -42,8 +42,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java index 7c00c765a3a3..8a67dba0fb39 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java @@ -23,24 +23,29 @@ import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; +import java.util.ArrayList; +import java.util.List; + /** * @author ven */ public class GrClosureType extends GrLiteralClassType { - private final @NotNull GrClosureSignature mySignature; + private final @NotNull GrSignature mySignature; private PsiType[] myTypeArgs = null; private GrClosureType(LanguageLevel languageLevel, GlobalSearchScope scope, JavaPsiFacade facade, - @NotNull GrClosureSignature closureSignature, + @NotNull GrSignature closureSignature, boolean shouldInferTypeParameters) { super(languageLevel, scope, facade); mySignature = closureSignature; @@ -67,7 +72,8 @@ public class GrClosureType extends GrLiteralClassType { if (myTypeArgs == null) { final PsiClass psiClass = resolve(); if (psiClass != null && psiClass.getTypeParameters().length == 1) { - myTypeArgs = new PsiType[]{TypesUtil.boxPrimitiveType(mySignature.getReturnType(), getPsiManager(), getResolveScope(), true)}; + final PsiType type = GrClosureSignatureUtil.getReturnType(mySignature); + myTypeArgs = new PsiType[]{TypesUtil.boxPrimitiveType(type, getPsiManager(), getResolveScope(), true)}; } else { myTypeArgs = PsiType.EMPTY_ARRAY; @@ -76,6 +82,8 @@ public class GrClosureType extends GrLiteralClassType { return myTypeArgs; } + + @NotNull @Override protected String getJavaClassName() { @@ -108,7 +116,7 @@ public class GrClosureType extends GrLiteralClassType { return super.equals(obj); } - public boolean isAssignableFrom(@NotNull PsiType type) { + /*public boolean isAssignableFrom(@NotNull PsiType type) { if (type instanceof GrClosureType) { GrClosureType other = (GrClosureType)type; GrClosureSignature otherSignature = other.mySignature; @@ -137,7 +145,7 @@ public class GrClosureType extends GrLiteralClassType { return true; } return super.isAssignableFrom(type); - } + }*/ public boolean equalsToText(@NonNls String text) { return text.equals(GroovyCommonClassNames.GROOVY_LANG_CLOSURE); @@ -150,6 +158,25 @@ public class GrClosureType extends GrLiteralClassType { return result; } + public static GrClosureType create(GroovyResolveResult[] results, GroovyPsiElement context) { + List signatures = new ArrayList(); + for (GroovyResolveResult result : results) { + if (result.getElement() instanceof PsiMethod) { + signatures.add(GrClosureSignatureUtil.createSignature((PsiMethod)result.getElement(), result.getSubstitutor())); + } + } + + final GlobalSearchScope resolveScope = context.getResolveScope(); + final JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject()); + if (signatures.size() == 1) { + return create(signatures.get(0), resolveScope, facade, LanguageLevel.JDK_1_5, true); + } + else { + return create(GrClosureSignatureUtil.createMultiSignature(signatures.toArray(new GrClosureSignature[signatures.size()])), + resolveScope, facade, LanguageLevel.JDK_1_5, true); + } + } + public static GrClosureType create(@NotNull GrClosableBlock closure, boolean shouldInferTypeParameters) { final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(closure); final GlobalSearchScope resolveScope = closure.getResolveScope(); @@ -172,7 +199,7 @@ public class GrClosureType extends GrLiteralClassType { return create(GrClosureSignatureUtil.createSignature(parameters, returnType), scope, facade, languageLevel, true); } - public static GrClosureType create(@NotNull GrClosureSignature signature, + public static GrClosureType create(@NotNull GrSignature signature, GlobalSearchScope scope, JavaPsiFacade facade, LanguageLevel languageLevel, @@ -181,8 +208,8 @@ public class GrClosureType extends GrLiteralClassType { } @Nullable - public PsiType curry(PsiType[] args, int position) { - final GrClosureSignature newSignature = mySignature.curry(args, position); + public PsiType curry(PsiType[] args, int position, GroovyPsiElement context) { + final GrSignature newSignature = mySignature.curry(args, position, context); if (newSignature == null) return null; final GrClosureType result = create(newSignature, myScope, myFacade, myLanguageLevel, true); result.myTypeArgs = this.myTypeArgs; @@ -190,16 +217,16 @@ public class GrClosureType extends GrLiteralClassType { } @NotNull - public GrClosureSignature getSignature() { + public GrSignature getSignature() { return mySignature; } - public PsiType[] getClosureParameterTypes() { + /*public PsiType[] getClosureParameterTypes() { final GrClosureParameter[] parameters = mySignature.getParameters(); final PsiType[] types = new PsiType[parameters.length]; for (int i = 0; i < types.length; i++) { types[i] = parameters[i].getType(); } return types; - } + }*/ } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 59d7e7738fc2..dabda0feaf5e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -40,6 +40,7 @@ import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.*; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; @@ -55,7 +56,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMe import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition; -import org.jetbrains.plugins.groovy.lang.psi.api.types.*; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClassTypeElement; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureImpl.java similarity index 66% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureImpl.java index 798dc40970ee..7a8bff57d84b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureImpl.java @@ -13,22 +13,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.psi.impl.types; +package org.jetbrains.plugins.groovy.lang.psi.impl.signatures; import com.intellij.openapi.util.Comparing; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrMultiSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignatureVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCurriedClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureParameterImpl; + +import java.util.ArrayList; +import java.util.List; /** * @author Maxim.Medvedev */ public class GrClosureSignatureImpl implements GrClosureSignature { private final boolean myIsVarargs; + private final boolean myCurried; @Nullable private final PsiType myReturnType; @NotNull private final GrClosureParameter[] myParameters; @NotNull private final PsiSubstitutor mySubstitutor; @@ -47,20 +55,21 @@ public class GrClosureSignatureImpl implements GrClosureSignature { myIsVarargs = false; } mySubstitutor = substitutor; + myCurried = false; } public GrClosureSignatureImpl(PsiParameter[] parameters, @Nullable PsiType returnType) { this(parameters, returnType, PsiSubstitutor.EMPTY); } - GrClosureSignatureImpl(@NotNull GrClosureParameter[] params, @Nullable PsiType returnType, boolean isVarArgs) { + GrClosureSignatureImpl(@NotNull GrClosureParameter[] params, @Nullable PsiType returnType, boolean isVarArgs, boolean isCurried) { myParameters = params; myReturnType = returnType; myIsVarargs = isVarArgs; + myCurried = isCurried; mySubstitutor = PsiSubstitutor.EMPTY; } - public boolean isVarargs() { return myIsVarargs; } @@ -89,8 +98,44 @@ public class GrClosureSignatureImpl implements GrClosureSignature { } @Nullable - public GrCurriedClosureSignature curry(PsiType[] args, int position) { - return new GrCurriedClosureSignatureImpl(this, args, position); + public GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) { + GrClosureParameter[] params = myParameters; + + List newParams = new ArrayList(params.length); + List opts = new ArrayList(params.length); + List optInds = new ArrayList(params.length); + + if (position == -1) { + position = params.length - args.length; + } + + if (position < 0 || position >= params.length) return GrMultiSignature.EMPTY_SIGNATURE; + + for (int i = 0; i < params.length; i++) { + if (params[i].isOptional()) { + opts.add(params[i]); + optInds.add(i); + } + else { + newParams.add(params[i]); + } + } + + final PsiType rtype = getReturnType(); + final ArrayList result = new ArrayList(); + GrClosureSignatureUtil.checkAndAddSignature(result, args, position, newParams, rtype, context); + + for (int i = 0; i < opts.size(); i++) { + newParams.add(optInds.get(i), opts.get(i)); + GrClosureSignatureUtil.checkAndAddSignature(result, args, position, newParams, rtype, context); + } + + if (result.size() == 1) { + return result.get(0); + } + else { + return new GrMultiSignatureImpl(result.toArray(new GrClosureSignature[result.size()])); + } } public boolean isValid() { @@ -110,6 +155,10 @@ public class GrClosureSignatureImpl implements GrClosureSignature { return super.equals(obj); } + public boolean isCurried() { + return myCurried; + } + @Nullable public static GrClosureSignature getLeastUpperBound(@NotNull GrClosureSignature signature1, @NotNull GrClosureSignature signature2, @@ -131,10 +180,15 @@ public class GrClosureSignatureImpl implements GrClosureSignature { returnType = TypesUtil.getLeastUpperBound(s1type, s2type, manager); } boolean isVarArgs = signature1.isVarargs() && signature2.isVarargs(); - return new GrClosureSignatureImpl(params, returnType, isVarArgs); + return new GrClosureSignatureImpl(params, returnType, isVarArgs, false); } return null; //todo } + + @Override + public void accept(GrSignatureVisitor visitor) { + visitor.visitClosureSignature(this); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureUtil.java similarity index 71% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureUtil.java index 6ac06fe349e9..b2d1341f3b6c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureUtil.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.psi.impl.types; +package org.jetbrains.plugins.groovy.lang.psi.impl.signatures; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Trinity; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.InheritanceUtil; @@ -30,6 +31,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrMultiSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; @@ -39,12 +44,11 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExp import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCurriedClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureParameterImpl; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.*; @@ -57,13 +61,24 @@ public class GrClosureSignatureUtil { private GrClosureSignatureUtil() { } + public static GrMultiSignature createMultiSignature(GrClosureSignature[] signatures) { + return new GrMultiSignatureImpl(signatures); + } @Nullable public static GrClosureSignature createSignature(GrCall call) { if (call instanceof GrMethodCall) { final GrExpression invokedExpression = ((GrMethodCall)call).getInvokedExpression(); final PsiType type = invokedExpression.getType(); - if (type instanceof GrClosureType) return ((GrClosureType)type).getSignature(); + if (type instanceof GrClosureType) { + final GrSignature signature = ((GrClosureType)type).getSignature(); + final Trinity[], ApplicabilityResult> trinity = + getApplicableSignature(signature, PsiUtil.getArgumentTypes(invokedExpression, true), call); + if (trinity != null) { + return trinity.first; + } + return null; + } } final GroovyResolveResult resolveResult = call.advancedResolve(); @@ -105,7 +120,7 @@ public class GrClosureSignatureUtil { public static GrClosureSignature removeParam(final GrClosureSignature signature, int i) { final GrClosureParameter[] newParams = ArrayUtil.remove(signature.getParameters(), i); - return new GrClosureSignatureImpl(newParams, null, newParams.length > 0 && signature.isVarargs()) { + return new GrClosureSignatureImpl(newParams, null, newParams.length > 0 && signature.isVarargs(), false) { @Override public PsiType getReturnType() { return signature.getReturnType(); @@ -127,7 +142,7 @@ public class GrClosureSignatureUtil { closureParams[i] = new GrClosureParameterImpl(type, GrClosureParameterImpl.isParameterOptional(param), GrClosureParameterImpl.getDefaultInitializer(param)); } - return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams)) { + return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams), false) { @Override public PsiType getReturnType() { return PsiUtil.getSmartReturnType(method); @@ -149,7 +164,7 @@ public class GrClosureSignatureUtil { closureParams[i] = new GrClosureParameterImpl(type, GrClosureParameterImpl.isParameterOptional(param), GrClosureParameterImpl.getDefaultInitializer(param)); } - return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams)) { + return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams), false) { @Override public PsiType getReturnType() { return closure.getReturnType(); @@ -167,26 +182,131 @@ public class GrClosureSignatureUtil { return new GrClosureSignatureImpl(parameters, returnType); } - public static boolean isSignatureApplicable(@NotNull GrClosureSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) { + + @Nullable + public static PsiType getReturnType(@NotNull final GrSignature signature, @NotNull GrMethodCall expr) { + return getReturnType(signature, PsiUtil.getArgumentTypes(expr.getInvokedExpression(), true), expr); + } + + @Nullable + public static PsiType getReturnType(@NotNull final GrSignature signature, @Nullable PsiType[] args, @NotNull GroovyPsiElement context) { + if (signature instanceof GrClosureSignature) return ((GrClosureSignature)signature).getReturnType(); + + if (args == null) { + return TypesUtil.getLeastUpperBoundNullable(new Iterable() { + + @Override + public Iterator iterator() { + return new Iterator() { + private final Iterator it = Arrays.asList(((GrMultiSignature)signature).getAllSignatures()).iterator(); + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public PsiType next() { + return it.next().getReturnType(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }, context.getManager()); + } + + final List[], ApplicabilityResult>> results = + getSignatureApplicabilities(signature, args, context); + + if (results.size() == 1) return results.get(0).first.getReturnType(); + + return TypesUtil.getLeastUpperBoundNullable(new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + private final Iterator[], ApplicabilityResult>> myIterator = results.iterator(); + + @Override + public boolean hasNext() { + return myIterator.hasNext(); + } + + @Override + public PsiType next() { + return myIterator.next().first.getReturnType(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }, context.getManager()); + } + + public static boolean isSignatureApplicable(@NotNull GrSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) { return isSignatureApplicableConcrete(signature, args, context) != ApplicabilityResult.inapplicable; } - public static ApplicabilityResult isSignatureApplicableConcrete(@NotNull GrClosureSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) { - ArgInfo[] map = mapArgTypesToParameters(signature, args, context, false); - if (map != null) return isSignatureApplicableInner(map, signature); + public static ApplicabilityResult isSignatureApplicableConcrete(@NotNull GrSignature signature, @NotNull final PsiType[] args, @NotNull final GroovyPsiElement context) { + final List[], ApplicabilityResult>> results = + getSignatureApplicabilities(signature, args, context); - // check for the case foo([1, 2, 3]) if foo(int, int, int) - if (args.length == 1 && PsiUtil.isInMethodCallContext(context)) { - final GrClosureParameter[] parameters = signature.getParameters(); - if (parameters.length == 1 && parameters[0].getType() instanceof PsiArrayType) return ApplicabilityResult.inapplicable; - PsiType arg = args[0]; - if (arg instanceof GrTupleType) { - args = ((GrTupleType)arg).getComponentTypes(); - map = mapArgTypesToParameters(signature, args, context, false); - if (map != null) return isSignatureApplicableInner(map, signature); + if (results.isEmpty()) return ApplicabilityResult.inapplicable; + else if (results.size()==1) return results.get(0).third; + else return ApplicabilityResult.ambiguous; + } + + @Nullable + public static Trinity[], ApplicabilityResult> getApplicableSignature(@NotNull GrSignature signature, + @Nullable final PsiType[] args, + @NotNull final GroovyPsiElement context) { + if (args == null) return null; + final List[], ApplicabilityResult>> results = getSignatureApplicabilities(signature, args, context); + + if (results.size() == 1) return results.get(0); + else return null; + } + + private static List[], ApplicabilityResult>> getSignatureApplicabilities(@NotNull GrSignature signature, + @NotNull final PsiType[] args, + @NotNull final GroovyPsiElement context) { + final List[], ApplicabilityResult>> results = + new ArrayList[], ApplicabilityResult>>(); + signature.accept(new GrRecursiveSignatureVisitor() { + @Override + public void visitClosureSignature(GrClosureSignature signature) { + ArgInfo[] map = mapArgTypesToParameters(signature, args, context, false); + if (map != null) { + results.add(new Trinity[], ApplicabilityResult>(signature, map, isSignatureApplicableInner(map, signature))); + return; + } + + // check for the case foo([1, 2, 3]) if foo(int, int, int) + if (args.length == 1 && PsiUtil.isInMethodCallContext(context)) { + final GrClosureParameter[] parameters = signature.getParameters(); + if (parameters.length == 1 && parameters[0].getType() instanceof PsiArrayType) { + return; + } + PsiType arg = args[0]; + if (arg instanceof GrTupleType) { + PsiType[] _args = ((GrTupleType)arg).getComponentTypes(); + map = mapArgTypesToParameters(signature, _args, context, false); + if (map != null) { + results.add(new Trinity[], ApplicabilityResult>(signature, map, + isSignatureApplicableInner(map, + signature))); + } + } + } } - } - return ApplicabilityResult.inapplicable; + }); + return results; } private static ApplicabilityResult isSignatureApplicableInner(@NotNull ArgInfo[] infos, @NotNull GrClosureSignature signature) { @@ -206,10 +326,10 @@ public class GrClosureSignatureUtil { } public enum ApplicabilityResult { - applicable, inapplicable, canBeApplicable; + applicable, inapplicable, canBeApplicable, ambiguous; public static boolean isApplicable(ApplicabilityResult r) { - return r != inapplicable; + return r != inapplicable && r!= ambiguous; } } @@ -240,61 +360,12 @@ public class GrClosureSignatureUtil { }; } - @Nullable - private static ArgWrapper[] getActualArgs(@NotNull GrCurriedClosureSignature signature, - @NotNull Arg[] args, - @NotNull Function typeComputer) { - List> actual = new ArrayList>(signature.getParameterCount()); - for (Arg arg : args) { - actual.add(new ArgWrapper(typeComputer.fun(arg), arg)); - } - GrCurriedClosureSignature curried = signature; - while (true) { - final PsiType[] curriedArgs = curried.getCurriedArgs(); - int curriedPosition = curried.getCurriedPosition(); - if (curriedPosition == -1) curriedPosition = actual.size(); - if (curriedPosition > actual.size()) return null; - - for (int i = 0; i < curriedArgs.length; i++, curriedPosition++) { - actual.add(curriedPosition, new ArgWrapper(curriedArgs[i], null)); - } - if (!(curried.getOriginalSignature() instanceof GrCurriedClosureSignature)) break; - curried = (GrCurriedClosureSignature)curried.getOriginalSignature(); - } - return actual.toArray(new ArgWrapper[args.length]); - } - - public static GrClosureSignature getOriginalSignature(GrClosureSignature signature) { - if (signature instanceof GrCurriedClosureSignature) { - return getOriginalSignature(((GrCurriedClosureSignature)signature).getOriginalSignature()); - } - return signature; - } - @Nullable private static ArgInfo[] mapParametersToArguments(@NotNull GrClosureSignature signature, @NotNull Arg[] args, @NotNull Function typeComputer, @NotNull GroovyPsiElement context, boolean partial) { - if (signature instanceof GrCurriedClosureSignature) { - final ArgWrapper[] actualArgs = getActualArgs((GrCurriedClosureSignature)signature, args, typeComputer); - if (actualArgs == null) return null; - final ArgInfo>[] argInfos = - mapParametersToArguments(getOriginalSignature(signature), actualArgs, GrClosureSignatureUtil.ARG_WRAPPER_COMPUTER(), context, partial); - if (argInfos == null) return null; - - final ArgInfo[] result = new ArgInfo[argInfos.length]; - for (int i = 0; i < argInfos.length; i++) { - ArgInfo> info = argInfos[i]; - List list = new ArrayList(); - for (ArgWrapper arg : info.args) { - if (arg.arg != null) list.add(arg.arg); - } - result[i] = new ArgInfo(list, info.isMultiArg); - } - return result; - } if (checkForOnlyMapParam(signature, args.length)) return ArgInfo.empty_array(); GrClosureParameter[] params = signature.getParameters(); if (args.length > params.length && !signature.isVarargs()) return null; @@ -313,7 +384,7 @@ public class GrClosureSignatureUtil { } private static boolean checkForOnlyMapParam(@NotNull GrClosureSignature signature, final int argCount) { - if (argCount > 0) return false; + if (argCount > 0 || signature.isCurried()) return false; final GrClosureParameter[] parameters = signature.getParameters(); if (parameters.length != 1) return false; final PsiType type = parameters[0].getType(); @@ -352,6 +423,33 @@ public class GrClosureSignatureUtil { return TypesUtil.isAssignableByMethodCallConversion(paramType, argType, context); } + public static void checkAndAddSignature(List list, + PsiType[] args, + int position, + List params, + PsiType returnType, + @NotNull GroovyPsiElement context) { + final int last = position + args.length; + if (last > params.size()) return; + + for (int i = position; i < last; i++) { + final GrClosureParameter p = params.get(i); + final PsiType type = p.getType(); + if (!isAssignableByConversion(type, args[i - position], context)) return; + } + GrClosureParameter[] _p = new GrClosureParameter[params.size() - args.length]; + int j = 0; + for (int i = 0; i < position; i++) { + _p[j++] = params.get(i); + } + for (int i = position + args.length; i < params.size(); i++) { + _p[j++] = params.get(i); + } + + list.add(new GrClosureSignatureImpl(_p, returnType, _p.length > 0 && _p[_p.length - 1].getType() instanceof PsiArrayType, true)); + } + + @Nullable public static GrClosureSignature createSignature(GroovyResolveResult resolveResult) { final PsiElement resolved = resolveResult.getElement(); @@ -626,7 +724,9 @@ public class GrClosureSignatureUtil { String name = method.getName(); PsiTypeParameter[] typeParameters = method.getTypeParameters(); - return generateAllMethodSignaturesByClosureSignature(name, signature, typeParameters, substitutor); + final ArrayList result = new ArrayList(); + generateAllMethodSignaturesByClosureSignature(name, signature, typeParameters, substitutor, result); + return result; } public static MultiMap findMethodSignatures(PsiMethod[] methods) { @@ -646,10 +746,11 @@ public class GrClosureSignatureUtil { return MethodSignatureUtil.createMethodSignature(name, paramTypes.toArray(new PsiType[paramTypes.size()]), typeParameters, substitutor); } - public static List generateAllMethodSignaturesByClosureSignature(@NotNull String name, - @NotNull GrClosureSignature signature, - @NotNull PsiTypeParameter[] typeParameters, - @NotNull PsiSubstitutor substitutor) { + public static void generateAllMethodSignaturesByClosureSignature(@NotNull String name, + @NotNull GrClosureSignature signature, + @NotNull PsiTypeParameter[] typeParameters, + @NotNull PsiSubstitutor substitutor, + List result) { GrClosureParameter[] params = signature.getParameters(); ArrayList newParams = new ArrayList(params.length); @@ -666,18 +767,24 @@ public class GrClosureSignatureUtil { } } - List result = new ArrayList(opts.size() + 1); result.add(generateSignature(name, newParams, typeParameters, substitutor)); for (int i = 0; i < opts.size(); i++) { newParams.add(optInds.get(i), opts.get(i).getType()); result.add(generateSignature(name, newParams, typeParameters, substitutor)); } - return result; } - public static List generateAllMethodSignaturesByClosureSignature(@NotNull String name, - @NotNull GrClosureSignature signature) { - return generateAllMethodSignaturesByClosureSignature(name, signature, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); + public static List generateAllMethodSignaturesBySignature(@NotNull final String name, + @NotNull final GrSignature signature) { + + final ArrayList result = new ArrayList(); + signature.accept(new GrRecursiveSignatureVisitor() { + @Override + public void visitClosureSignature(GrClosureSignature signature) { + generateAllMethodSignaturesByClosureSignature(name, signature, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, result); + } + }); + return result; } @Nullable @@ -713,4 +820,31 @@ public class GrClosureSignatureUtil { } } + + /** + * + * @param signature + * @return return type or null if there is some different return types + */ + @Nullable + public static PsiType getReturnType(GrSignature signature) { + if (signature instanceof GrClosureSignature) { + return ((GrClosureSignature)signature).getReturnType(); + } + else if (signature instanceof GrMultiSignature) { + final GrClosureSignature[] signatures = ((GrMultiSignature)signature).getAllSignatures(); + if (signatures.length == 0) return null; + final PsiType type = signatures[0].getReturnType(); + if (type == null) return null; + String firstType = type.getCanonicalText(); + for (int i = 1; i < signatures.length; i++) { + final PsiType _type = signatures[i].getReturnType(); + if (_type == null) return null; + if (!firstType.equals(_type.getCanonicalText())) return null; + } + return type; + } + + return null; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrMultiSignatureImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrMultiSignatureImpl.java new file mode 100644 index 000000000000..c944410b1d09 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrMultiSignatureImpl.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2012 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.psi.impl.signatures; + +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrMultiSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignatureVisitor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Max Medvedev + */ +public class GrMultiSignatureImpl implements GrMultiSignature { + private final GrClosureSignature[] mySignatures; + + public GrMultiSignatureImpl(GrClosureSignature[] signatures) { + mySignatures = signatures; + } + + @Override + public GrClosureSignature[] getAllSignatures() { + return mySignatures; + } + + @Override + public boolean isValid() { + for (GrClosureSignature signature : mySignatures) { + if (!signature.isValid()) return false; + } + return true; + } + + @Override + public GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) { + List newClosures = new ArrayList(); + + for (GrClosureSignature old : mySignatures) { + final GrSignature curried = old.curry(args, position, context); + if (curried instanceof GrClosureSignature) { + newClosures.add((GrClosureSignature)curried); + } + else if (curried instanceof GrMultiSignature) { + newClosures.addAll(Arrays.asList(((GrMultiSignature)curried).getAllSignatures())); + } + } + return new GrMultiSignatureImpl(newClosures.toArray(new GrClosureSignature[newClosures.size()])); + } + + @Override + public void accept(GrSignatureVisitor visitor) { + visitor.visitMultiSignature(this); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java index a9ccd80d2aa4..d2a3174ee9c1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrAssignmentExpressionImpl.java @@ -62,7 +62,7 @@ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAs PsiType returnType = null; final PsiManager manager = assignment.getManager(); for (GroovyResolveResult result : results) { - final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(result, assignment); + final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(result, assignment, new PsiType[]{getRValueType(assignment)}); returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager); } return returnType; @@ -218,12 +218,16 @@ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAs } if (lType == null) return GroovyResolveResult.EMPTY_ARRAY; - final GrExpression rightOperand = assignmentExpression.getRValue(); - PsiType rType = rightOperand == null ? null : rightOperand.getType(); + PsiType rType = getRValueType(assignmentExpression); final IElementType operatorToken = TokenSets.ASSIGNMENTS_TO_OPERATORS.get(opType); return TypesUtil.getOverloadedOperatorCandidates(lType, operatorToken, assignmentExpression, new PsiType[]{rType}); } }; + @Nullable + private static PsiType getRValueType(GrAssignmentExpressionImpl assignmentExpression) { + final GrExpression rightOperand = assignmentExpression.getRValue(); + return rightOperand == null ? null : rightOperand.getType(); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java index 4b0b2b6eade3..16845d51944e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrBinaryExpressionImpl.java @@ -51,12 +51,17 @@ public abstract class GrBinaryExpressionImpl extends GrExpressionImpl implements final PsiType lType = binary.getLeftOperand().getType(); if (lType == null) return GroovyResolveResult.EMPTY_ARRAY; - final GrExpression rightOperand = binary.getRightOperand(); - PsiType rType = rightOperand == null ? null : rightOperand.getType(); + PsiType rType = getRightType(binary); return TypesUtil.getOverloadedOperatorCandidates(lType, opType, binary, new PsiType[]{rType}); } }; + @Nullable + private static PsiType getRightType(GrBinaryExpressionImpl binary) { + final GrExpression rightOperand = binary.getRightOperand(); + return rightOperand == null ? null : rightOperand.getType(); + } + private static final Function TYPE_CALCULATOR = new Function() { @Nullable @Override @@ -68,7 +73,7 @@ public abstract class GrBinaryExpressionImpl extends GrExpressionImpl implements } final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(binary.multiResolve(false)); - final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult, binary); + final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult, binary, new PsiType[]{getRightType(binary)}); return TypesUtil.boxPrimitiveType(substituted, binary.getManager(), binary.getResolveScope()); } }; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 58debb4af35a..10833924d997 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -487,10 +487,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl[], GrClosureSignatureUtil.ApplicabilityResult> + resultTrinity = types != null ? GrClosureSignatureUtil.getApplicableSignature(signature, types, call) : null; + _signature = resultTrinity != null ? resultTrinity.first : null; + } + if (_signature != null) { + return isRawType(_signature.getReturnType(), TypesUtil.composeSubstitutors(_signature.getSubstitutor(), result.getSubstitutor())); + } + return false; + } + public static boolean isRawFieldAccess(GrReferenceExpression ref) { PsiElement element = null; final GroovyResolveResult[] resolveResults = ref.multiResolve(false); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index 9a33033470aa..4b7bb036470b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -37,6 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; @@ -51,11 +52,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousC import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; @@ -679,12 +679,12 @@ public class ResolveUtil { private static boolean isApplicableClosureType(PsiType type, PsiType[] argTypes, GroovyPsiElement place) { if (!(type instanceof GrClosureType)) return false; - final GrClosureSignature signature = ((GrClosureType)type).getSignature(); + final GrSignature signature = ((GrClosureType)type).getSignature(); return GrClosureSignatureUtil.isSignatureApplicable(signature, argTypes, place); } @Nullable - public static PsiType extractReturnTypeFromCandidate(GroovyResolveResult candidate, GrExpression expression) { + public static PsiType extractReturnTypeFromCandidate(GroovyResolveResult candidate, GrExpression expression, @Nullable PsiType[] args) { final PsiElement element = candidate.getElement(); if (element instanceof PsiMethod && !candidate.isInvokedOnProperty()) { return TypesUtil.substituteBoxAndNormalizeType(getSmartReturnType((PsiMethod)element), candidate.getSubstitutor(), expression); @@ -701,7 +701,8 @@ public class ResolveUtil { return null; } if (type instanceof GrClosureType) { - PsiType returnType = ((GrClosureType)type).getSignature().getReturnType(); + final GrSignature signature = ((GrClosureType)type).getSignature(); + PsiType returnType = GrClosureSignatureUtil.getReturnType(signature, args, expression); return TypesUtil.substituteBoxAndNormalizeType(returnType, candidate.getSubstitutor(), expression); } return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java index 4ff599650d90..9231fea405f6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java @@ -27,12 +27,12 @@ import org.jetbrains.plugins.groovy.gpp.GppClosureParameterTypeProvider; import org.jetbrains.plugins.groovy.gpp.GppTypeConverter; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/SubstitutorComputer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/SubstitutorComputer.java index 5f4d43f9fde4..309dba929d46 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/SubstitutorComputer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/SubstitutorComputer.java @@ -26,6 +26,7 @@ import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; @@ -37,9 +38,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini 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.types.GrClosureParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java index c70000f893b0..480fe28df873 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java @@ -68,8 +68,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini 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.types.GrTypeElement; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java index 1095ec3fe0ce..d810d2970b08 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodCallUsageInfo.java @@ -27,11 +27,11 @@ import com.intellij.refactoring.changeSignature.PossiblyIncorrectUsage; import com.intellij.usageView.UsageInfo; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; /** diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodConflictUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodConflictUtil.java index 28deeeb2f766..e2a868a9cb6e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodConflictUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrMethodConflictUtil.java @@ -20,14 +20,15 @@ import com.intellij.psi.util.MethodSignature; import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil; -import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; @@ -45,18 +46,18 @@ public class GrMethodConflictUtil { GrMethod refactoredMethod, final MultiMap conflicts, boolean excludeJavaConflicts) { List prototypeSignatures = GrClosureSignatureUtil.generateAllSignaturesForMethod(prototype, PsiSubstitutor.EMPTY); - checkForClosurePropertySignatrureOverload(clazz, prototype, refactoredMethod, conflicts, prototypeSignatures); + checkForClosurePropertySignatureOverload(clazz, prototype, refactoredMethod, conflicts, prototypeSignatures); checkForMethodSignatureOverload(clazz, prototype, refactoredMethod, conflicts, excludeJavaConflicts, prototypeSignatures); checkForAccessorOverloading(clazz, prototype, conflicts); } - private static void checkForClosurePropertySignatrureOverload(PsiClass clazz, - GrMethod prototype, - GrMethod refactoredMethod, - MultiMap conflicts, - List prototypeSignatures) { - final boolean isStatic = prototype.hasModifierProperty(GrModifier.STATIC); + private static void checkForClosurePropertySignatureOverload(PsiClass clazz, + GrMethod prototype, + final GrMethod refactoredMethod, + final MultiMap conflicts, + final List prototypeSignatures) { + final boolean isStatic = prototype.hasModifierProperty(PsiModifier.STATIC); final String name = prototype.getName(); if (!GroovyPropertyUtils.isProperty(clazz, name, isStatic)) return; @@ -74,20 +75,26 @@ public class GrMethodConflictUtil { } if (!(returnType instanceof GrClosureType)) return; - final GrClosureSignature signature = ((GrClosureType)returnType).getSignature(); - - NextSignature: - for (MethodSignature prototypeSignature : prototypeSignatures) { - final GrClosureParameter[] params = signature.getParameters(); - final PsiType[] types = prototypeSignature.getParameterTypes(); - if (types.length != params.length) continue; - for (int i = 0; i < types.length; i++) { - if (!TypesUtil.isAssignableByMethodCallConversion(types[i], params[i].getType(), refactoredMethod.getParameterList())) { - continue NextSignature; + final GrSignature signature = ((GrClosureType)returnType).getSignature(); + signature.accept(new GrRecursiveSignatureVisitor() { + @Override + public void visitClosureSignature(GrClosureSignature signature) { + NextSignature: + for (MethodSignature prototypeSignature : prototypeSignatures) { + final GrClosureParameter[] params = signature.getParameters(); + final PsiType[] types = prototypeSignature.getParameterTypes(); + if (types.length != params.length) continue; + for (int i = 0; i < types.length; i++) { + if (!TypesUtil.isAssignableByMethodCallConversion(types[i], params[i].getType(), refactoredMethod.getParameterList())) { + continue NextSignature; + } + } + conflicts.putValue(getter, GroovyRefactoringBundle.message("refactored.method.will.cover.closure.property", name, RefactoringUIUtil.getDescription(getter.getContainingClass(), false))); } } - conflicts.putValue(getter, GroovyRefactoringBundle.message("refactored.method.will.cover.closure.property", name, RefactoringUIUtil.getDescription(getter.getContainingClass(), false))); - } + }); + + } private static void checkForMethodSignatureOverload(PsiClass clazz, @@ -121,13 +128,13 @@ public class GrMethodConflictUtil { if (GroovyPropertyUtils.isSimplePropertySetter(prototype)) { String propertyName = GroovyPropertyUtils.getPropertyNameBySetter(prototype); PsiMethod setter = - GroovyPropertyUtils.findPropertySetter(clazz, propertyName, prototype.hasModifierProperty(GrModifier.STATIC), false); + GroovyPropertyUtils.findPropertySetter(clazz, propertyName, prototype.hasModifierProperty(PsiModifier.STATIC), false); if (setter instanceof GrAccessorMethod) { conflicts.putValue(setter, GroovyRefactoringBundle.message("replace.setter.for.property", propertyName)); } } else if (GroovyPropertyUtils.isSimplePropertyGetter(prototype)) { - boolean isStatic = prototype.hasModifierProperty(GrModifier.STATIC); + boolean isStatic = prototype.hasModifierProperty(PsiModifier.STATIC); String propertyName = GroovyPropertyUtils.getPropertyNameByGetter(prototype); PsiMethod getter = GroovyPropertyUtils.findPropertyGetter(clazz, propertyName, isStatic, false); if (getter instanceof GrAccessorMethod) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java index 9314c88f6eb9..fbef953e578a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java @@ -18,22 +18,22 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava; import com.intellij.psi.*; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.jetbrains.plugins.groovy.refactoring.convertToJava.ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT; import static org.jetbrains.plugins.groovy.refactoring.convertToJava.GenerationUtil.writeType; +import static org.jetbrains.plugins.groovy.refactoring.convertToJava.ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT; /** * @author Maxim.Medvedev diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ArgumentListGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ArgumentListGenerator.java index 125ff6181ac9..32a160ac9383 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ArgumentListGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ArgumentListGenerator.java @@ -24,13 +24,13 @@ import com.intellij.psi.PsiType; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import java.util.Arrays; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java index 0a38ae15b271..c54d192ffb42 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java @@ -30,6 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrDefaultAnnotationValue; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; @@ -41,9 +42,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumConstantInitializer; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import java.util.*; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java index ac0a3b8ced4b..d4de2c42e577 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java @@ -49,8 +49,8 @@ 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.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import java.util.Collection; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java index 9882c18c253d..8395cd1ca36c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java @@ -32,6 +32,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; 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; @@ -48,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrArrayTypeElement; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; @@ -58,9 +58,9 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java index e25b52f8ef63..6eb60ebe0146 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java @@ -23,6 +23,7 @@ import com.intellij.util.containers.HashMap; import gnu.trove.TIntArrayList; import gnu.trove.TIntProcedure; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; @@ -30,10 +31,9 @@ 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.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.Map; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java index 4a639e00077d..c9eed0db83e8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java @@ -49,6 +49,7 @@ import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; @@ -59,11 +60,10 @@ 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.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java index 5878254aa972..f51b18c34ffd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java @@ -41,6 +41,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; @@ -55,8 +56,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisRe import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java index 58956c089553..10cf41aeee85 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java @@ -39,6 +39,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; @@ -51,8 +52,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM 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.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GroovyIntroduceParameterUtil; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/OldReferencesResolver.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/OldReferencesResolver.java index eb0d89729d9a..fa72d5ae8e5c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/OldReferencesResolver.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/OldReferencesResolver.java @@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; @@ -38,8 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; -import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy index 2717c28ed5e4..40b5b5007a4b 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.groovy @@ -888,4 +888,40 @@ Date d = a.cl() myFixture.enableInspections(inspections) myFixture.testHighlighting(true, false, true) } + + void testMethodRefs1() { + myFixture.configureByText('_.groovy', '''\ +class A { + int foo(){2} + + Date foo(int x) {null} +} + +def foo = new A().&foo + +int i = foo() +int i2 = foo(2) +Date d = foo(2) +Date d2 = foo() +''') + testHighlighting(GroovyAssignabilityCheckInspection) + } + + void testMethodRefs2() { + myFixture.configureByText('_.groovy', '''\ +class Bar { + def foo(int i, String s2) {s2} + def foo(int i, int i2) {i2} +} + +def cl = new Bar.&foo +cl = cl.curry(1) +String s = cl("2") +int s2 = cl("2") +int i = cl(3) +String i2 = cl(3) +''') + testHighlighting(GroovyAssignabilityCheckInspection) + } + } \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/memberPointer.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/memberPointer.java index 0dc2480009c2..b668dbd97d32 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/memberPointer.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/memberPointer.java @@ -1,2 +1,2 @@ -groovy.lang.Closure a = new org.codehaus.groovy.runtime.MethodClosure(new java.util.ArrayList(), "add"); +groovy.lang.Closure a = new org.codehaus.groovy.runtime.MethodClosure(new java.util.ArrayList(), "add"); a.call("2");