private Pair<Boolean, GroovyResolveResult[]> doResolveByShape( boolean allVariants, @Nullable GrExpression upToArgument) { final String name = getReferenceName(); LOG.assertTrue(name != null); final MethodResolverProcessor shapeProcessor = createMethodProcessor(allVariants, name, true, upToArgument); processMethods(shapeProcessor); GroovyResolveResult[] candidates = shapeProcessor.getCandidates(); assertAllAreValid(candidates); return Pair.create(shapeProcessor.hasApplicableCandidates(), candidates); }
private void processMethods(@NotNull MethodResolverProcessor methodResolver) { new GrReferenceResolveRunner(this).resolveImpl(methodResolver); if (methodResolver.hasApplicableCandidates()) { return; } // Search in ClosureMissingMethodContributor if (!isQualified() && getContext() instanceof GrMethodCall) { ClosureMissingMethodContributor.processMethodsFromClosures(this, methodResolver); } }
private void processMethods(final MethodResolverProcessor methodResolver) { GrReferenceResolveUtil.resolveImpl(methodResolver, this); if (methodResolver.hasApplicableCandidates()) { return; } // Search in ClosureMissingMethodContributor if (!isQualified() && getContext() instanceof GrMethodCall) { for (PsiElement e = this.getContext(); e != null; e = e.getContext()) { if (e instanceof GrClosableBlock) { ResolveState state = ResolveState.initial().put(ResolverProcessor.RESOLVE_CONTEXT, e); for (ClosureMissingMethodContributor contributor : ClosureMissingMethodContributor.EP_NAME.getExtensions()) { if (!contributor.processMembers((GrClosableBlock) e, methodResolver, this, state)) { return; } } } } } }
/** * priority: inside class C: local variable, c.method, c.property, c.getter in other places: local * variable, c.method, c.getter, c.property */ @NotNull private GroovyResolveResult[] resolveMethodOrProperty( boolean allVariants, @Nullable GrExpression upToArgument, boolean genericsMatter) { final String name = getReferenceName(); if (name == null) return GroovyResolveResult.EMPTY_ARRAY; PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, this); GrReferenceResolveUtil.resolveImpl(propertyResolver, this); final GroovyResolveResult[] propertyCandidates = propertyResolver.getCandidates(); if (!allVariants) { // search for local variables for (GroovyResolveResult candidate : propertyCandidates) { if (candidate.getElement() instanceof GrVariable && !(candidate.getElement() instanceof GrField)) { return propertyResolver.getCandidates(); } } } final Pair<Boolean, GroovyResolveResult[]> shapeResults = resolveByShape(allVariants, upToArgument); if (!genericsMatter && !allVariants && shapeResults.first) { assertAllAreValid(shapeResults.second); return shapeResults.second; } MethodResolverProcessor methodResolver = null; if (genericsMatter) { methodResolver = createMethodProcessor(allVariants, name, false, upToArgument); for (GroovyResolveResult result : shapeResults.second) { final ResolveState state = ResolveState.initial() .put(PsiSubstitutor.KEY, result.getSubstitutor()) .put(ResolverProcessor.RESOLVE_CONTEXT, result.getCurrentFileResolveContext()) .put(SpreadState.SPREAD_STATE, result.getSpreadState()); methodResolver.execute(result.getElement(), state); } if (!allVariants && methodResolver.hasApplicableCandidates()) { return methodResolver.getCandidates(); } } // search for fields inside its class if (!allVariants) { for (GroovyResolveResult candidate : propertyCandidates) { final PsiElement element = candidate.getElement(); if (element instanceof GrField) { final PsiClass containingClass = ((PsiField) element).getContainingClass(); if (containingClass != null && PsiTreeUtil.isContextAncestor(containingClass, this, true)) return propertyCandidates; } } } List<GroovyResolveResult> allCandidates = new ArrayList<GroovyResolveResult>(); ContainerUtil.addAll(allCandidates, propertyCandidates); ContainerUtil.addAll( allCandidates, genericsMatter ? methodResolver.getCandidates() : shapeResults.second); // search for getters for (String getterName : GroovyPropertyUtils.suggestGettersName(name)) { AccessorResolverProcessor getterResolver = new AccessorResolverProcessor( getterName, name, this, true, genericsMatter, GrReferenceResolveUtil.getQualifierType(this), getTypeArguments()); GrReferenceResolveUtil.resolveImpl(getterResolver, this); final GroovyResolveResult[] candidates = getterResolver.getCandidates(); // can be only one candidate if (!allVariants && candidates.length == 1) { return candidates; } ContainerUtil.addAll(allCandidates, candidates); } if (allCandidates.size() > 0) { return allCandidates.toArray(new GroovyResolveResult[allCandidates.size()]); } return GroovyResolveResult.EMPTY_ARRAY; }