diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 8e6322a9648f..9d8fb3543879 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -264,7 +264,7 @@ public class GroovyCompletionContributor extends CompletionContributor { } else if (call instanceof GrCallExpression) { GrCallExpression constructorCall = (GrCallExpression)call; - ContainerUtil.addAll(results, constructorCall.getMethodVariants(null)); + ContainerUtil.addAll(results, constructorCall.getCallVariants(null)); final PsiType type = ((GrCallExpression)call).getType(); if (type instanceof PsiClassType) { final PsiClass psiClass = ((PsiClassType)type).resolve(); 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 415e55368dde..13820441edee 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 @@ -114,7 +114,7 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandler namedElements = ContainerUtil.findAll(variants, new Condition() { public boolean value(GroovyResolveResult groovyResolveResult) { final PsiElement element = groovyResolveResult.getElement(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java index 48aeb07117d5..65a6ae7ace1e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrCallExpression.java @@ -43,7 +43,7 @@ public interface GrCallExpression extends GrExpression, GrCall { PsiMethod resolveMethod(); @NotNull - GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument); + GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument); //PsiElement addNamedArgument(GrNamedArgument argument); } 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 a37a96beddbd..4e1878887643 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 @@ -127,7 +127,7 @@ public class GroovyExpectedTypesProvider { final int closureIndex = closureArgs.indexOf(myExpression); if (closureIndex >= 0) { List constraints = new ArrayList(); - for (GroovyResolveResult variant : ResolveUtil.getMethodVariants(myExpression)) { + for (GroovyResolveResult variant : ResolveUtil.getCallVariants(myExpression)) { PsiParameter[] parameters = getCallParameters(variant); if (parameters == null || parameters.length == 0) continue; @@ -178,7 +178,7 @@ public class GroovyExpectedTypesProvider { int idx = list.getExpressionArgumentIndex(myExpression); List constraints = new ArrayList(); - for (GroovyResolveResult variant : ResolveUtil.getMethodVariants(list)) { + for (GroovyResolveResult variant : ResolveUtil.getCallVariants(list)) { PsiParameter[] parameters = getCallParameters(variant); if (parameters == null || parameters.length <= idx) continue; PsiType parameterType = variant.getSubstitutor().substitute(parameters[idx].getType()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java index b79ecbde0668..22ff2fab9fc6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java @@ -182,7 +182,7 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx } @NotNull - public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) { + public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) { final GrCodeReferenceElement referenceElement = getReferenceElement(); if (referenceElement == null) return GroovyResolveResult.EMPTY_ARRAY; final GroovyResolveResult[] classResults = referenceElement.multiResolve(false); 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 16311308b982..947db67a586f 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 @@ -77,6 +77,120 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements super(node); } + public GroovyResolveResult[] resolveTypeOrProperty() { + String name = getReferenceName(); + if (name == null) return GroovyResolveResult.EMPTY_ARRAY; + + EnumSet kinds = getParent() instanceof GrReferenceExpression + ? EnumSet.of(ClassHint.ResolveKind.CLASS, ClassHint.ResolveKind.PACKAGE) + : EnumSet.of(ClassHint.ResolveKind.CLASS); + boolean hasAt = hasAt(); + GroovyResolveResult[] classCandidates = GroovyResolveResult.EMPTY_ARRAY; + if (!hasAt) { + ResolverProcessor classProcessor = new ClassResolverProcessor(getReferenceName(), this, kinds); + resolveImpl(classProcessor); + classCandidates = classProcessor.getCandidates(); + for (GroovyResolveResult classCandidate : classCandidates) { + final PsiElement element = classCandidate.getElement(); + if (element instanceof PsiClass && ((PsiClass)element).isEnum()) { + return classCandidates; + } + } + } + + ResolverProcessor processor = new PropertyResolverProcessor(name, this); + resolveImpl(processor); + final GroovyResolveResult[] fieldCandidates = processor.getCandidates(); + + if (hasAt) { + return fieldCandidates; + } + + //if reference expression is in class we need to return field instead of accessor method + for (GroovyResolveResult candidate : fieldCandidates) { + final PsiElement element = candidate.getElement(); + if (element instanceof PsiField) { + final PsiClass containingClass = ((PsiField)element).getContainingClass(); + if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, this, true)) return fieldCandidates; + } else { + return fieldCandidates; + } + } + + final boolean isLValue = PsiUtil.isLValue(this); + String[] names; + names = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name); + List accessorResults = new ArrayList(); + for (String getterName : names) { + AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(getterName, this, !isLValue); + resolveImpl(accessorResolver); + final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate + if (candidates.length == 1 && candidates[0].isStaticsOK()) { + return candidates; + } + else { + ContainerUtil.addAll(accessorResults, candidates); + } + } + if (fieldCandidates.length > 0) return fieldCandidates; + if (accessorResults.size() > 0) return new GroovyResolveResult[]{accessorResults.get(0)}; + + return classCandidates; + } + + public GroovyResolveResult[] resolveMethodOrProperty() { + return resolveMethodOrProperty(false, null); + } + + public GroovyResolveResult[] getCallVariants(GrExpression upToArgument) { + return resolveMethodOrProperty(true, upToArgument); + } + + private GroovyResolveResult[] resolveMethodOrProperty(boolean allVariants, GrExpression upToArgument) { + String name = getReferenceName(); + if (name == null) return GroovyResolveResult.EMPTY_ARRAY; + + final PsiType[] argTypes = PsiUtil.getArgumentTypes(this, false, upToArgument); + MethodResolverProcessor methodResolver = runMethodResolverProcessor(argTypes, allVariants); + assert methodResolver != null; + if (!allVariants && methodResolver.hasApplicableCandidates()) return methodResolver.getCandidates(); + + final String[] names = GroovyPropertyUtils.suggestGettersName(name); + List list = new ArrayList(); + for (String getterName : names) { + AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, this, true); + resolveImpl(getterResolver); + final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate + if (!allVariants && candidates.length == 1 && candidates[0].isStaticsOK()) { + putUserData(IS_RESOLVED_TO_GETTER, true); + return candidates; + } + else { + ContainerUtil.addAll(list, candidates); + } + } + + PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, this); + resolveImpl(propertyResolver); + if (!allVariants && propertyResolver.hasCandidates()) return propertyResolver.getCandidates(); + + if (allVariants) { + if (list.isEmpty()) ContainerUtil.addAll(list, propertyResolver.getCandidates()); + ContainerUtil.addAll(list, methodResolver.getCandidates()); + return list.toArray(new GroovyResolveResult[list.size()]); + } + + if (methodResolver.hasCandidates()) { + return methodResolver.getCandidates(); + } + else if (list.size() > 0) { + putUserData(IS_RESOLVED_TO_GETTER, true); + return list.toArray(new GroovyResolveResult[list.size()]); + } + + return GroovyResolveResult.EMPTY_ARRAY; + } + public void accept(GroovyElementVisitor visitor) { visitor.visitReferenceExpression(this); } @@ -422,108 +536,13 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements switch (kind) { case METHOD_OR_PROPERTY: - return resolveMethodOrProperty(refExpr, name); + return refExpr.resolveMethodOrProperty(); case TYPE_OR_PROPERTY: - return resolveTypeOrProperty(refExpr, name); + return refExpr.resolveTypeOrProperty(); default: return GroovyResolveResult.EMPTY_ARRAY; } } - - private static GroovyResolveResult[] resolveTypeOrProperty(GrReferenceExpressionImpl refExpr, String name) { - EnumSet kinds = refExpr.getParent() instanceof GrReferenceExpression - ? EnumSet.of(ClassHint.ResolveKind.CLASS, ClassHint.ResolveKind.PACKAGE) - : EnumSet.of(ClassHint.ResolveKind.CLASS); - boolean hasAt = refExpr.hasAt(); - GroovyResolveResult[] classCandidates = GroovyResolveResult.EMPTY_ARRAY; - if (!hasAt) { - ResolverProcessor classProcessor = new ClassResolverProcessor(refExpr.getReferenceName(), refExpr, kinds); - refExpr.resolveImpl(classProcessor); - classCandidates = classProcessor.getCandidates(); - for (GroovyResolveResult classCandidate : classCandidates) { - final PsiElement element = classCandidate.getElement(); - if (element instanceof PsiClass && ((PsiClass)element).isEnum()) { - return classCandidates; - } - } - } - - ResolverProcessor processor = new PropertyResolverProcessor(name, refExpr); - refExpr.resolveImpl(processor); - final GroovyResolveResult[] fieldCandidates = processor.getCandidates(); - - if (refExpr.hasAt()) { - return fieldCandidates; - } - - //if reference expression is in class we need to return field instead of accessor method - for (GroovyResolveResult candidate : fieldCandidates) { - final PsiElement element = candidate.getElement(); - if (element instanceof PsiField) { - final PsiClass containingClass = ((PsiField)element).getContainingClass(); - if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, refExpr, true)) return fieldCandidates; - } else { - return fieldCandidates; - } - } - - final boolean isLValue = PsiUtil.isLValue(refExpr); - String[] names; - names = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name); - List accessorResults = new ArrayList(); - for (String getterName : names) { - AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(getterName, refExpr, !isLValue); - refExpr.resolveImpl(accessorResolver); - final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate - if (candidates.length == 1 && candidates[0].isStaticsOK()) { - return candidates; - } - else { - ContainerUtil.addAll(accessorResults, candidates); - } - } - if (fieldCandidates.length > 0) return fieldCandidates; - if (accessorResults.size() > 0) return new GroovyResolveResult[]{accessorResults.get(0)}; - - return classCandidates; - } - - private static GroovyResolveResult[] resolveMethodOrProperty(GrReferenceExpressionImpl refExpr, String name) { - final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false); - MethodResolverProcessor methodResolver = refExpr.runMethodResolverProcessor(argTypes, false); - assert methodResolver != null; - if (methodResolver.hasApplicableCandidates()) return methodResolver.getCandidates(); - - final String[] names = GroovyPropertyUtils.suggestGettersName(name); - List list = new ArrayList(); - for (String getterName : names) { - AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, refExpr, true); - refExpr.resolveImpl(getterResolver); - final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate - if (candidates.length == 1 && candidates[0].isStaticsOK()) { - refExpr.putUserData(IS_RESOLVED_TO_GETTER, true); - return candidates; - } - else { - ContainerUtil.addAll(list, candidates); - } - } - - PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, refExpr); - refExpr.resolveImpl(propertyResolver); - if (propertyResolver.hasCandidates()) return propertyResolver.getCandidates(); - - if (methodResolver.hasCandidates()) { - return methodResolver.getCandidates(); - } - else if (list.size() > 0) { - refExpr.putUserData(IS_RESOLVED_TO_GETTER, true); - return list.toArray(new GroovyResolveResult[list.size()]); - } - - return GroovyResolveResult.EMPTY_ARRAY; - } - } private void resolveImpl(ResolverProcessor processor) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java index 5a7033e7aefc..240808ac9b5b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java @@ -41,7 +41,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrRefer import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; -import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor; import java.util.ArrayList; @@ -187,17 +186,11 @@ public class GrMethodCallExpressionImpl extends GrCallExpressionImpl implements } @NotNull - public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) { + public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) { final GrExpression invoked = getInvokedExpression(); if (!(invoked instanceof GrReferenceExpressionImpl)) return GroovyResolveResult.EMPTY_ARRAY; - final PsiType[] partialArgs = PsiUtil.getArgumentTypes(invoked, false, upToArgument); - final MethodResolverProcessor processor = ((GrReferenceExpressionImpl)invoked).runMethodResolverProcessor(partialArgs, true); - if (processor != null) { - return processor.getCandidates(); - } - - return GroovyResolveResult.EMPTY_ARRAY; + return ((GrReferenceExpressionImpl)invoked).getCallVariants(upToArgument); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java index 67b76bf82b5b..f2e50cb1d9a1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyExpressionPattern.java @@ -42,7 +42,7 @@ public class GroovyExpressionPattern method) { return new GroovyMethodCallPattern().and(this).with(new PatternCondition("methodCall") { public boolean accepts(@NotNull GrCallExpression callExpression, ProcessingContext context) { - final GroovyResolveResult[] results = callExpression.getMethodVariants(null); + final GroovyResolveResult[] results = callExpression.getCallVariants(null); for (GroovyResolveResult result : results) { if (method.getCondition().accepts(result.getElement(), context)) { return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index c4b5a4ceb29d..26df489a80b6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -632,7 +632,7 @@ public class PsiUtil { } public static boolean isRawMethodCall(GrMethodCallExpression call) { - final GroovyResolveResult[] resolveResults = call.getMethodVariants(null); + final GroovyResolveResult[] resolveResults = call.getCallVariants(null); if (resolveResults.length == 0) return false; final PsiElement element = resolveResults[0].getElement(); if (element instanceof PsiMethod) { 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 9659d975a867..47905ecaec05 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 @@ -439,11 +439,11 @@ public class ResolveUtil { return true; } - public static GroovyResolveResult[] getMethodVariants(GroovyPsiElement place) { + public static GroovyResolveResult[] getCallVariants(GroovyPsiElement place) { final PsiElement parent = place.getParent(); GroovyResolveResult[] variants = GroovyResolveResult.EMPTY_ARRAY; if (parent instanceof GrCallExpression) { - variants = ((GrCallExpression) parent).getMethodVariants(place instanceof GrExpression ? (GrExpression)place : null); + variants = ((GrCallExpression) parent).getCallVariants(place instanceof GrExpression ? (GrExpression)place : null); } else if (parent instanceof GrConstructorInvocation) { final PsiClass clazz = ((GrConstructorInvocation) parent).getDelegatedClass(); if (clazz != null) {