public void visitAssignmentExpression(GrAssignmentExpression expression) { GrExpression rValue = expression.getRValue(); GrExpression lValue = expression.getLValue(); if (myExpression.equals(rValue)) { PsiType lType = lValue.getNominalType(); if (lType != null) { myResult = new TypeConstraint[] {SubtypeConstraint.create(lType)}; } else if (lValue instanceof GrReferenceExpression) { GroovyResolveResult result = ((GrReferenceExpression) lValue).advancedResolve(); PsiElement resolved = result.getElement(); if (resolved instanceof GrVariable) { PsiType type = ((GrVariable) resolved).getTypeGroovy(); if (type != null) { myResult = new TypeConstraint[] { SubtypeConstraint.create(result.getSubstitutor().substitute(type)) }; } } } } else if (myExpression.equals(lValue)) { if (rValue != null) { PsiType rType = rValue.getType(); if (rType != null) { myResult = new TypeConstraint[] {SupertypeConstraint.create(rType)}; } } } }
@NotNull @Override public GroovyResolveResult[] getCandidates() { if (!hasCandidates()) return GroovyResolveResult.EMPTY_ARRAY; final GroovyResolveResult[] results = ResolveUtil.filterSameSignatureCandidates(getCandidatesInternal()); List<GroovyResolveResult> list = new ArrayList<GroovyResolveResult>(results.length); myPropertyNames.removeAll(myPreferredFieldNames); Set<String> usedFields = ContainerUtil.newHashSet(); for (GroovyResolveResult result : results) { final PsiElement element = result.getElement(); if (element instanceof PsiField) { final String name = ((PsiField) element).getName(); if (myPropertyNames.contains(name) || myLocalVars.contains(name) || usedFields.contains(name)) { continue; } else { usedFields.add(name); } } list.add(result); } return list.toArray(new GroovyResolveResult[list.size()]); }
private static void removeParametersFromCall( GrMethodCallExpression methodCall, GrIntroduceParameterSettings settings) { final GroovyResolveResult resolveResult = methodCall.advancedResolve(); final PsiElement resolved = resolveResult.getElement(); LOG.assertTrue(resolved instanceof PsiMethod); final GrClosureSignature signature = GrClosureSignatureUtil.createSignature( (PsiMethod) resolved, resolveResult.getSubstitutor()); final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, methodCall); LOG.assertTrue(argInfos != null); settings .parametersToRemove() .forEach( new TIntProcedure() { @Override public boolean execute(int value) { final List<PsiElement> args = argInfos[value].args; for (PsiElement arg : args) { arg.delete(); } return true; } }); }
private GroovyResolveResult[] resolveTypeOrProperty() { if (isDefinitelyKeyOfMap()) return GroovyResolveResult.EMPTY_ARRAY; final GroovyResolveResult[] results = resolveTypeOrPropertyInner(); if (results.length == 0) return GroovyResolveResult.EMPTY_ARRAY; if (!ResolveUtil.mayBeKeyOfMap(this)) return results; // filter out all members from super classes. We should return only accessible members from map // classes List<GroovyResolveResult> filtered = new ArrayList<GroovyResolveResult>(); for (GroovyResolveResult result : results) { final PsiElement element = result.getElement(); if (element instanceof PsiMember) { if (((PsiMember) element).hasModifierProperty(PsiModifier.PRIVATE)) continue; final PsiClass containingClass = ((PsiMember) element).getContainingClass(); if (containingClass != null) { if (!InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_MAP)) continue; final String name = containingClass.getQualifiedName(); if (name != null && name.startsWith("java.")) continue; if (containingClass.getLanguage() != GroovyFileType.GROOVY_LANGUAGE && !InheritanceUtil.isInheritor( containingClass, GroovyCommonClassNames.DEFAULT_BASE_CLASS_NAME)) { continue; } } } filtered.add(result); } return ContainerUtil.toArray(filtered, new GroovyResolveResult[filtered.size()]); }
@Override @Nullable public PsiType getNominalType() { final GroovyResolveResult resolveResult = advancedResolve(); PsiElement resolved = resolveResult.getElement(); for (GrReferenceTypeEnhancer enhancer : GrReferenceTypeEnhancer.EP_NAME.getExtensions()) { PsiType type = enhancer.getReferenceType(this, resolved); if (type != null) { return type; } } IElementType dotType = getDotTokenType(); if (dotType == GroovyTokenTypes.mMEMBER_POINTER) { return GrClosureType.create(multiResolve(false), this); } if (isDefinitelyKeyOfMap()) { final PsiType type = getTypeFromMapAccess(this); if (type != null) { return type; } } PsiType result = getNominalTypeInner(resolved); if (result == null) return null; result = TypesUtil.substituteAndNormalizeType( result, resolveResult.getSubstitutor(), resolveResult.getSpreadState(), this); return result; }
@Nullable private static HighlightInfo checkCodeRefInner(GrCodeReferenceElement refElement) { if (PsiTreeUtil.getParentOfType(refElement, GroovyDocPsiElement.class) != null) return null; PsiElement nameElement = refElement.getReferenceNameElement(); if (nameElement == null) return null; if (isResolvedStaticImport(refElement)) return null; GroovyResolveResult resolveResult = refElement.advancedResolve(); final PsiElement resolved = resolveResult.getElement(); if (!(refElement.getParent() instanceof GrPackageDefinition) && resolved == null) { String message = GroovyBundle.message("cannot.resolve", refElement.getReferenceName()); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF) .range(nameElement) .descriptionAndTooltip(message) .create(); // todo implement for nested classes HighlightDisplayKey displayKey = HighlightDisplayKey.find(SHORT_NAME); registerCreateClassByTypeFix(refElement, info, displayKey); registerAddImportFixes(refElement, info, displayKey); UnresolvedReferenceQuickFixProvider.registerReferenceFixes( refElement, new QuickFixActionRegistrarAdapter(info, displayKey)); OrderEntryFix.registerFixes(new QuickFixActionRegistrarAdapter(info, displayKey), refElement); return info; } return null; }
private static boolean isStaticOk(GroovyResolveResult resolveResult) { if (resolveResult.isStaticsOK()) return true; PsiElement resolved = resolveResult.getElement(); LOG.assertTrue(resolved != null); LOG.assertTrue(resolved instanceof PsiModifierListOwner, resolved + " : " + resolved.getText()); return ((PsiModifierListOwner) resolved).hasModifierProperty(STATIC); }
@Nullable private static HighlightInfo checkRefInner(GrReferenceExpression ref) { PsiElement refNameElement = ref.getReferenceNameElement(); if (refNameElement == null) return null; boolean cannotBeDynamic = PsiUtil.isCompileStatic(ref) || isPropertyAccessInStaticMethod(ref); GroovyResolveResult resolveResult = getBestResolveResult(ref); if (resolveResult.getElement() != null) { if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null; if (isStaticOk(resolveResult)) return null; String message = GroovyBundle.message("cannot.reference.non.static", ref.getReferenceName()); return createAnnotationForRef(ref, cannotBeDynamic, message); } if (ResolveUtil.isKeyOfMap(ref) || isClassReference(ref)) { return null; } if (!cannotBeDynamic) { if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null; GrUnresolvedAccessInspection inspection = getInstance(ref.getContainingFile(), ref.getProject()); if (!inspection.myHighlightIfGroovyObjectOverridden && areGroovyObjectMethodsOverridden(ref)) return null; if (!inspection.myHighlightIfMissingMethodsDeclared && areMissingMethodsDeclared(ref)) return null; if (GroovySuppressableInspectionTool.isElementToolSuppressedIn(ref, SHORT_NAME)) return null; } if (cannotBeDynamic || shouldHighlightAsUnresolved(ref)) { HighlightInfo info = createAnnotationForRef( ref, cannotBeDynamic, GroovyBundle.message("cannot.resolve", ref.getReferenceName())); LOG.assertTrue(info != null); HighlightDisplayKey displayKey = HighlightDisplayKey.find(SHORT_NAME); if (ref.getParent() instanceof GrMethodCall) { registerStaticImportFix(ref, info, displayKey); } else { registerCreateClassByTypeFix(ref, info, displayKey); registerAddImportFixes(ref, info, displayKey); } registerReferenceFixes(ref, info, cannotBeDynamic, displayKey); UnresolvedReferenceQuickFixProvider.registerReferenceFixes( ref, new QuickFixActionRegistrarAdapter(info, displayKey)); OrderEntryFix.registerFixes(new QuickFixActionRegistrarAdapter(info, displayKey), ref); return info; } return null; }
private static PsiType doFun(GrReferenceExpression refExpr) { if (ResolveUtil.isClassReference(refExpr)) { GrExpression qualifier = refExpr.getQualifier(); LOG.assertTrue(qualifier != null); return TypesUtil.createJavaLangClassType( qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope()); } if (PsiUtil.isCompileStatic(refExpr)) { final GroovyResolveResult resolveResult = refExpr.advancedResolve(); final PsiElement resolvedF = resolveResult.getElement(); final PsiType type; if (resolvedF instanceof GrField) { type = ((GrField) resolvedF).getType(); } else if (resolvedF instanceof GrAccessorMethod) { type = ((GrAccessorMethod) resolvedF).getProperty().getType(); } else { type = null; } if (type != null) { return resolveResult.getSubstitutor().substitute(type); } } final PsiElement resolved = refExpr.resolve(); final PsiType nominal = refExpr.getNominalType(); Boolean reassigned = GrReassignedLocalVarsChecker.isReassignedVar(refExpr); if (reassigned != null && reassigned.booleanValue()) { return GrReassignedLocalVarsChecker.getReassignedVarType(refExpr, true); } final PsiType inferred = getInferredTypes(refExpr, resolved); if (inferred == null) { if (nominal == null) { // inside nested closure we could still try to infer from variable initializer. Not sound, // but makes sense if (resolved instanceof GrVariable) { LOG.assertTrue(resolved.isValid()); return ((GrVariable) resolved).getTypeGroovy(); } } return nominal; } if (nominal == null) return inferred; if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) { if (resolved instanceof GrVariable && ((GrVariable) resolved).getTypeElementGroovy() != null) { return nominal; } } return inferred; }
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { final GroovyResolveResult result = advancedResolve(); if (result.isInvokedOnProperty()) { final String name = GroovyPropertyUtils.getPropertyNameByAccessorName(newElementName); if (name != null) { newElementName = name; } } if (PsiUtil.isThisOrSuperRef(this)) return this; return handleElementRenameSimple(newElementName); }
@Nullable private PsiType extractLastParameterType(GroovyResolveResult candidate) { PsiElement element = candidate.getElement(); if (element instanceof PsiMethod) { PsiParameter[] parameters = ((PsiMethod) element).getParameterList().getParameters(); if (parameters.length > 1) { PsiParameter last = parameters[parameters.length - 1]; return TypesUtil.substituteBoxAndNormalizeType( last.getType(), candidate.getSubstitutor(), candidate.getSpreadState(), this); } } return null; }
private static boolean containsLocalVar(GroovyResolveResult[] fieldCandidates) { boolean preferVar = false; if (fieldCandidates.length > 0) { for (GroovyResolveResult candidate : fieldCandidates) { PsiElement element = candidate.getElement(); LOG.assertTrue(element != null, candidate); if (GroovyRefactoringUtil.isLocalVariable(element)) { preferVar = true; break; } } } return preferVar; }
private static PsiReference[] createReferencesForNamedArgument( @NotNull PsiElement element, GrNamedArgument namedArgument, @NotNull ProcessingContext context) { String labelName = namedArgument.getLabelName(); if (labelName == null) return PsiReference.EMPTY_ARRAY; if (!GroovyMethodInfo.getAllSupportedNamedArguments().contains(labelName)) { // Optimization: avoid unnecessary resolve. return PsiReference.EMPTY_ARRAY; } PsiElement call = PsiUtil.getCallByNamedParameter(namedArgument); if (!(call instanceof GrMethodCall)) return PsiReference.EMPTY_ARRAY; GrExpression invokedExpression = ((GrMethodCall) call).getInvokedExpression(); if (!(invokedExpression instanceof GrReferenceExpression)) return PsiReference.EMPTY_ARRAY; for (GroovyResolveResult result : ((GrReferenceExpression) invokedExpression).multiResolve(false)) { PsiElement eMethod = result.getElement(); if (!(eMethod instanceof PsiMethod)) continue; PsiMethod method = (PsiMethod) eMethod; for (GroovyMethodInfo info : GroovyMethodInfo.getInfos(method)) { Object referenceProvider = info.getNamedArgReferenceProvider(labelName); if (referenceProvider != null) { PsiReference[] refs; if (referenceProvider instanceof GroovyNamedArgumentReferenceProvider) { refs = ((GroovyNamedArgumentReferenceProvider) referenceProvider) .createRef(element, namedArgument, result, context); } else { refs = ((PsiReferenceProvider) referenceProvider) .getReferencesByElement(element, context); } if (refs.length > 0) { return refs; } } } } return PsiReference.EMPTY_ARRAY; }
@Override @Nullable public PsiJavaCodeReferenceElement getNameReferenceElement() { final GroovyResolveResult resolveResult = resolveWithStub(); final PsiElement resolved = resolveResult.getElement(); if (!(resolved instanceof PsiClass)) return null; return new LightClassReference( getManager(), getClassReference().getText(), (PsiClass) resolved, resolveResult.getSubstitutor()); }
private static GroovyResolveResult getBestResolveResult(GrReferenceExpression ref) { GroovyResolveResult[] results = ref.multiResolve(false); if (results.length == 0) return GroovyResolveResult.EMPTY_RESULT; if (results.length == 1) return results[0]; for (GroovyResolveResult result : results) { if (result.isAccessible() && result.isStaticsOK()) return result; } for (GroovyResolveResult result : results) { if (result.isStaticsOK()) return result; } return results[0]; }
private Set<GroovyResolveResult> filterCorrectParameterCount( Set<GroovyResolveResult> candidates) { if (myArgumentTypes == null) return candidates; Set<GroovyResolveResult> result = new HashSet<GroovyResolveResult>(); for (GroovyResolveResult candidate : candidates) { final PsiElement element = candidate.getElement(); if (element instanceof PsiMethod && ((PsiMethod) element).getParameterList().getParametersCount() == myArgumentTypes.length) { result.add(candidate); } } if (!result.isEmpty()) return result; return candidates; }
private static void filterOutBindings(@NotNull List<GroovyResolveResult> candidates) { boolean hasNonBinding = false; for (GroovyResolveResult candidate : candidates) { if (!(candidate.getElement() instanceof GrBindingVariable)) { hasNonBinding = true; } } if (hasNonBinding) { for (Iterator<GroovyResolveResult> iterator = candidates.iterator(); iterator.hasNext(); ) { GroovyResolveResult candidate = iterator.next(); if (candidate.getElement() instanceof GrBindingVariable) { iterator.remove(); } } } }
@NotNull private static GroovyResolveResult[] collapseReflectedMethods(GroovyResolveResult[] candidates) { Set<GrMethod> visited = ContainerUtil.newHashSet(); List<GroovyResolveResult> collapsed = ContainerUtil.newArrayList(); for (GroovyResolveResult result : candidates) { PsiElement element = result.getElement(); if (element instanceof GrReflectedMethod) { GrMethod baseMethod = ((GrReflectedMethod) element).getBaseMethod(); if (visited.add(baseMethod)) { collapsed.add( PsiImplUtil.reflectedToBase(result, baseMethod, (GrReflectedMethod) element)); } } else { collapsed.add(result); } } return collapsed.toArray(new GroovyResolveResult[collapsed.size()]); }
private static boolean canBeSimplified(PsiElement element) { if (PsiTreeUtil.getParentOfType(element, PsiComment.class) != null) return false; if (element instanceof GrCodeReferenceElement) { if (PsiTreeUtil.getParentOfType(element, GrImportStatement.class, GrPackageDefinition.class) != null) return false; } else if (element instanceof GrReferenceExpression) { if (!PsiImplUtil.seemsToBeQualifiedClassName((GrReferenceExpression) element)) return false; } else { return false; } final GrReferenceElement ref = (GrReferenceElement) element; if (ref.getQualifier() == null) return false; if (!(ref.getContainingFile() instanceof GroovyFileBase)) return false; final PsiElement resolved = ref.resolve(); if (!(resolved instanceof PsiClass)) return false; final String name = ((PsiClass) resolved).getName(); if (name == null) return false; final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject()); final GrReferenceExpression shortedRef = factory.createReferenceExpressionFromText(name, element); final GroovyResolveResult resolveResult = shortedRef.advancedResolve(); if (element.getManager().areElementsEquivalent(resolved, resolveResult.getElement())) { return true; } final PsiClass containingClass = ((PsiClass) resolved).getContainingClass(); if (containingClass != null && !GroovyCodeStyleSettingsFacade.getInstance(containingClass.getProject()) .insertInnerClassImports()) { return false; } return resolveResult.getElement() == null || !resolveResult.isAccessible() || !resolveResult.isStaticsOK(); }
@Override public void getNamedArguments( @NotNull GrCall call, @Nullable PsiElement resolve, @Nullable String argumentName, boolean forCompletion, Map<String, ArgumentDescriptor> result) { if (!(call instanceof GrNewExpression)) return; if (resolve != null) { if (!(resolve instanceof PsiMethod)) return; PsiMethod method = (PsiMethod) resolve; if (!method.isConstructor()) return; } GrNewExpression newCall = (GrNewExpression) call; GrArgumentList argumentList = newCall.getArgumentList(); if (argumentList == null) return; GrExpression[] expressionArguments = argumentList.getExpressionArguments(); if (expressionArguments.length > 1 || (expressionArguments.length == 1 && !(expressionArguments[0] instanceof GrReferenceExpression))) { return; } for (GroovyResolveResult resolveResult : newCall.multiResolveClass()) { PsiElement element = resolveResult.getElement(); if (!(element instanceof PsiClass)) continue; PsiClass aClass = (PsiClass) element; if (!isClassHasConstructorWithMap(aClass)) continue; PsiClassType classType = JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass); processClass(call, classType, argumentName, result); } }
@NotNull private static GroovyResolveResult generatePropertyResolveResult( @NotNull String name, @NotNull PsiMethod method, @Nullable PsiType type, @Nullable GroovyResolveResult resolveResult) { PsiType nonNullType = type != null ? type : TypesUtil.getJavaLangObject(method); final GrPropertyForCompletion field = new GrPropertyForCompletion(method, name, nonNullType); if (resolveResult != null) { return new GroovyResolveResultImpl( field, resolveResult.getCurrentFileResolveContext(), resolveResult.getSpreadState(), resolveResult.getSubstitutor(), resolveResult.isAccessible(), resolveResult.isStaticsOK()); } else { return new GroovyResolveResultImpl(field, true); } }
private PsiType inferIteratorType( GroovyResolveResult iteratorMethodResult, GrExpression tupleInitializer) { PsiElement method = iteratorMethodResult.getElement(); if (method instanceof PsiMethod) { return iteratorMethodResult.getSubstitutor().substitute(((PsiMethod) method).getReturnType()); } else { PsiType initializerType = tupleInitializer.getType(); PsiType iterableParam = PsiUtil.extractIterableTypeParameter(initializerType, false); JavaPsiFacade facade = JavaPsiFacade.getInstance(context.project); PsiClass iterableClass = facade.findClass(CommonClassNames.JAVA_UTIL_ITERATOR, tupleInitializer.getResolveScope()); if (iterableClass != null && iterableParam != null) { return facade.getElementFactory().createType(iterableClass, iterableParam); } else { return facade .getElementFactory() .createTypeFromText(CommonClassNames.JAVA_UTIL_ITERATOR, tupleInitializer); } } }
public void visitMethodCallExpression(GrMethodCallExpression methodCall) { final GrExpression invokedExpression = methodCall.getInvokedExpression(); if (myExpression.equals(invokedExpression)) { myResult = new TypeConstraint[] { SubtypeConstraint.create(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, methodCall) }; return; } final GrClosableBlock[] closureArgs = methodCall.getClosureArguments(); //noinspection SuspiciousMethodCalls final int closureIndex = Arrays.asList(closureArgs).indexOf(myExpression); if (closureIndex >= 0) { List<TypeConstraint> constraints = new ArrayList<TypeConstraint>(); for (GroovyResolveResult variant : ResolveUtil.getCallVariants(myExpression)) { final GrArgumentList argumentList = methodCall.getArgumentList(); final GrNamedArgument[] namedArgs = argumentList == null ? GrNamedArgument.EMPTY_ARRAY : argumentList.getNamedArguments(); final GrExpression[] expressionArgs = argumentList == null ? GrExpression.EMPTY_ARRAY : argumentList.getExpressionArguments(); try { final Map<GrExpression, Pair<PsiParameter, PsiType>> map = GrClosureSignatureUtil.mapArgumentsToParameters( variant, methodCall, true, true, namedArgs, expressionArgs, closureArgs); addConstraintsFromMap(constraints, map); } catch (RuntimeException e) { LOG.error( "call: " + methodCall.getText() + "\nsymbol: " + variant.getElement().getText(), e); } } if (!constraints.isEmpty()) { myResult = constraints.toArray(new TypeConstraint[constraints.size()]); } } }
@Override public void visitNamedArgument(GrNamedArgument argument) { GrArgumentLabel label = argument.getLabel(); if (label != null) { PsiElement pparent = argument.getParent().getParent(); if (pparent instanceof GrCall && resolvesToDefaultConstructor(((GrCall) pparent))) { final GroovyResolveResult resolveResult = label.advancedResolve(); PsiElement resolved = resolveResult.getElement(); PsiType type; if (resolved instanceof PsiField) { type = ((PsiField) resolved).getType(); } else if (resolved instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertySetter((PsiMethod) resolved)) { type = ((PsiMethod) resolved).getParameterList().getParameters()[0].getType(); } else { type = null; } type = resolveResult.getSubstitutor().substitute(type); if (type != null) { myResult = createSimpleSubTypeResult(type); } } } }
private static String getMethodCandidateInfo(GrReferenceExpression expr) { final GroovyResolveResult[] candidates = expr.multiResolve(false); final String text = expr.getText(); if (candidates.length > 0) { @NonNls final StringBuilder sb = new StringBuilder(); for (final GroovyResolveResult candidate : candidates) { final PsiElement element = candidate.getElement(); if (!(element instanceof PsiMethod)) { continue; } final String str = PsiFormatUtil.formatMethod( (PsiMethod) element, candidate.getSubstitutor(), PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_TYPE); createElementLink(sb, element, str); } return CodeInsightBundle.message("javadoc.candidates", text, sb); } return CodeInsightBundle.message("javadoc.candidates.not.found", text); }
private GroovyResolveResult[] filterCandidates() { List<GroovyResolveResult> array = getCandidatesInternal(); if (array.size() == 1) return array.toArray(new GroovyResolveResult[array.size()]); List<GroovyResolveResult> result = new ArrayList<GroovyResolveResult>(); Iterator<GroovyResolveResult> itr = array.iterator(); result.add(itr.next()); Outer: while (itr.hasNext()) { GroovyResolveResult resolveResult = itr.next(); PsiElement currentElement = resolveResult.getElement(); if (currentElement instanceof PsiMethod) { PsiMethod currentMethod = (PsiMethod) currentElement; for (Iterator<GroovyResolveResult> iterator = result.iterator(); iterator.hasNext(); ) { final GroovyResolveResult otherResolveResult = iterator.next(); PsiElement other = otherResolveResult.getElement(); if (other instanceof PsiMethod) { PsiMethod otherMethod = (PsiMethod) other; int res = compareMethods( currentMethod, resolveResult.getSubstitutor(), resolveResult.getCurrentFileResolveContext(), otherMethod, otherResolveResult.getSubstitutor(), otherResolveResult.getCurrentFileResolveContext()); if (res > 0) { continue Outer; } else if (res < 0) { iterator.remove(); } } } } result.add(resolveResult); } return result.toArray(new GroovyResolveResult[result.size()]); }
@Nullable public static LookupElementBuilder createPropertyLookupElement( @NotNull PsiMethod accessor, @Nullable GroovyResolveResult resolveResult, @Nullable PrefixMatcher matcher) { String propName; PsiType propType; final boolean getter = GroovyPropertyUtils.isSimplePropertyGetter(accessor, null); if (getter) { propName = GroovyPropertyUtils.getPropertyNameByGetter(accessor); } else if (GroovyPropertyUtils.isSimplePropertySetter(accessor, null)) { propName = GroovyPropertyUtils.getPropertyNameBySetter(accessor); } else { return null; } assert propName != null; if (!PsiUtil.isValidReferenceName(propName)) { propName = "'" + propName + "'"; } if (matcher != null && !matcher.prefixMatches(propName)) { return null; } if (getter) { propType = PsiUtil.getSmartReturnType(accessor); } else { propType = accessor.getParameterList().getParameters()[0].getType(); } final PsiType substituted = resolveResult != null ? resolveResult.getSubstitutor().substitute(propType) : propType; LookupElementBuilder builder = LookupElementBuilder.create( generatePropertyResolveResult(propName, accessor, propType, resolveResult), propName) .withIcon(JetgroovyIcons.Groovy.Property); if (substituted != null) { builder = builder.withTypeText(substituted.getPresentableText()); } return builder; }
// hack for DGM.next(Number):Number private boolean isIncDecNumber(GroovyResolveResult result) { PsiElement element = result.getElement(); if (!(element instanceof PsiMethod)) return false; final PsiMethod method = element instanceof GrGdkMethod ? ((GrGdkMethod) element).getStaticMethod() : (PsiMethod) element; final String name = method.getName(); if (!"next".equals(name) && !"previous".equals(name)) return false; if (!PsiUtil.isDGMMethod(method)) return false; final PsiParameter[] parameters = method.getParameterList().getParameters(); if (parameters.length != 1) return false; if (!parameters[0].getType().equalsToText(CommonClassNames.JAVA_LANG_NUMBER)) return false; return true; }
private static void assertAllAreValid(GroovyResolveResult[] candidates) { for (GroovyResolveResult candidate : candidates) { final PsiElement element = candidate.getElement(); LOG.assertTrue(element == null || element.isValid()); } }
/** * 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; }