@NotNull private GroovyResolveResult[] doPolyResolve(boolean incompleteCode, boolean genericsMatter) { String name = getReferenceName(); if (name == null) return GroovyResolveResult.EMPTY_ARRAY; if (incompleteCode) { ResolverProcessor processor = CompletionProcessor.createRefSameNameProcessor(this, name); GrReferenceResolveUtil.resolveImpl(processor, this); GroovyResolveResult[] propertyCandidates = processor.getCandidates(); if (propertyCandidates.length > 0) return propertyCandidates; } try { ResolveProfiler.start(); switch (getKind()) { case METHOD_OR_PROPERTY: return resolveMethodOrProperty(false, null, genericsMatter); case TYPE_OR_PROPERTY: return resolveTypeOrProperty(); case METHOD_OR_PROPERTY_OR_TYPE: GroovyResolveResult[] results = resolveMethodOrProperty(false, null, genericsMatter); if (results.length == 0) results = resolveTypeOrProperty(); return results; default: return GroovyResolveResult.EMPTY_ARRAY; } } finally { final long time = ResolveProfiler.finish(); ResolveProfiler.write("ref " + getText() + " " + hashCode() + " : " + time); } }
@Override public void handleEvent(@NotNull Event event, Object associated) { super.handleEvent(event, associated); if (JavaScopeProcessorEvent.CHANGE_LEVEL == event && hasApplicableCandidates()) { myStopExecuting = true; } }
@Override public boolean execute(@NotNull PsiElement element, @NotNull ResolveState substitutor) { if (element instanceof PsiMethod && ((PsiMethod) element).isConstructor()) { return true; } super.execute(element, substitutor); return true; }
private GroovyResolveResult[] resolveTypeOrPropertyInner() { PsiElement nameElement = getReferenceNameElement(); String name = getReferenceName(); if (name == null || nameElement == null) return GroovyResolveResult.EMPTY_ARRAY; IElementType nameType = nameElement.getNode().getElementType(); if (nameType == GroovyTokenTypes.kTHIS) { ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>(); if (GrReferenceResolveUtil.resolveThisExpression(this, results)) { return results.toArray(new GroovyResolveResult[results.size()]); } } else if (nameType == GroovyTokenTypes.kSUPER) { ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>(); if (GrReferenceResolveUtil.resolveSuperExpression(this, results)) { return results.toArray(new GroovyResolveResult[results.size()]); } } EnumSet<ClassHint.ResolveKind> kinds = getParent() instanceof GrReferenceExpression ? ResolverProcessor.RESOLVE_KINDS_CLASS_PACKAGE : ResolverProcessor.RESOLVE_KINDS_CLASS; GroovyResolveResult[] classCandidates = null; ResolverProcessor processor = new PropertyResolverProcessor(name, this); GrReferenceResolveUtil.resolveImpl(processor, this); final GroovyResolveResult[] fieldCandidates = processor.getCandidates(); if (hasAt()) { return fieldCandidates; } boolean canBeClassOrPackage = ResolveUtil.canBeClassOrPackage(this); if (canBeClassOrPackage && findClassOrPackageAtFirst()) { boolean preferVar = containsLocalVar(fieldCandidates); if (!preferVar) { ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds); GrReferenceResolveUtil.resolveImpl(classProcessor, this); classCandidates = classProcessor.getCandidates(); if (classCandidates.length > 0) return classCandidates; } } // 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.isContextAncestor(containingClass, this, true)) return fieldCandidates; } else { return fieldCandidates; } } final boolean isLValue = PsiUtil.isLValue(this); String[] accessorNames = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name); List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>(); for (String accessorName : accessorNames) { AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor( accessorName, name, this, !isLValue, false, GrReferenceResolveUtil.getQualifierType(this), getTypeArguments()); GrReferenceResolveUtil.resolveImpl(accessorResolver, this); final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); // can be only one correct candidate or some incorrect if (candidates.length == 1 && candidates[0].isStaticsOK() && candidates[0].isAccessible()) { return candidates; } else { ContainerUtil.addAll(accessorResults, candidates); } } if (fieldCandidates.length > 0) return fieldCandidates; if (classCandidates == null && canBeClassOrPackage) { ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds); GrReferenceResolveUtil.resolveImpl(classProcessor, this); classCandidates = classProcessor.getCandidates(); } if (classCandidates != null && classCandidates.length > 0) return classCandidates; if (accessorResults.size() > 0) return new GroovyResolveResult[] {accessorResults.get(0)}; return GroovyResolveResult.EMPTY_ARRAY; }
@NotNull private GroovyResolveResult[] resolveTypeOrPropertyInner() { PsiElement nameElement = getReferenceNameElement(); String name = getReferenceName(); if (name == null || nameElement == null) return GroovyResolveResult.EMPTY_ARRAY; IElementType nameType = nameElement.getNode().getElementType(); if (nameType == GroovyTokenTypes.kTHIS) { GroovyResolveResult[] results = GrThisReferenceResolver.resolveThisExpression(this); if (results != null) { return results; } } else if (nameType == GroovyTokenTypes.kSUPER) { GroovyResolveResult[] results = GrSuperReferenceResolver.resolveSuperExpression(this); if (results != null) { return results; } } EnumSet<ClassHint.ResolveKind> kinds = getParent() instanceof GrReferenceExpression ? ClassHint.RESOLVE_KINDS_CLASS_PACKAGE : ClassHint.RESOLVE_KINDS_CLASS; GroovyResolveResult[] classCandidates = null; GrReferenceResolveRunner resolveRunner = new GrReferenceResolveRunner(this); ResolverProcessor processor = new PropertyResolverProcessor(name, this); resolveRunner.resolveImpl(processor); final GroovyResolveResult[] fieldCandidates = processor.getCandidates(); if (hasAt()) { return fieldCandidates; } boolean canBeClassOrPackage = ResolveUtil.canBeClassOrPackage(this); if (canBeClassOrPackage && findClassOrPackageAtFirst()) { ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds); resolveRunner.resolveImpl(classProcessor); classCandidates = classProcessor.getCandidates(); if (classCandidates.length > 0 && containsPackage(classCandidates)) { final PsiElement firstNonReferenceExprParent = PsiTreeUtil.skipParentsOfType(this, GrReferenceExpressionImpl.class); final GrReferenceExpressionImpl topRef = (GrReferenceExpressionImpl) PsiTreeUtil.findFirstParent( this, new Condition<PsiElement>() { @Override public boolean value(PsiElement parent) { return parent.getParent() == firstNonReferenceExprParent && parent instanceof GrReferenceExpressionImpl; } }); if (topRef != null) { final String fqn = topRef.getTextSkipWhiteSpaceAndComments(); if (JavaPsiFacade.getInstance(getProject()).findClass(fqn, getResolveScope()) != null) { return classCandidates; } } } } // 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 && PsiUtil.getContextClass(this) == containingClass) return fieldCandidates; } else if (!(element instanceof GrBindingVariable)) { return fieldCandidates; } } if (classCandidates != null && classCandidates.length > 0) return classCandidates; final boolean isLValue = PsiUtil.isLValue(this); String[] accessorNames = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name); List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>(); for (String accessorName : accessorNames) { AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor( accessorName, name, this, !isLValue, false, PsiImplUtil.getQualifierType(this), getTypeArguments()); resolveRunner.resolveImpl(accessorResolver); final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); // can be only one correct candidate or some incorrect if (candidates.length == 1 && candidates[0].isStaticsOK() && candidates[0].isAccessible()) { return candidates; } else { ContainerUtil.addAll(accessorResults, candidates); } } final ArrayList<GroovyResolveResult> fieldList = ContainerUtil.newArrayList(fieldCandidates); filterOutBindings(fieldList); if (!fieldList.isEmpty()) { return fieldList.toArray(new GroovyResolveResult[fieldList.size()]); } if (classCandidates == null && canBeClassOrPackage) { ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds); resolveRunner.resolveImpl(classProcessor); classCandidates = classProcessor.getCandidates(); } if (classCandidates != null && classCandidates.length > 0) return classCandidates; if (!accessorResults.isEmpty()) return new GroovyResolveResult[] {accessorResults.get(0)}; return GroovyResolveResult.EMPTY_ARRAY; }