@Override public void consume(Object o) { if (!(o instanceof GroovyResolveResult)) { LOG.error(o); return; } GroovyResolveResult result = (GroovyResolveResult) o; if (!result.isStaticsOK()) { if (myInapplicable == null) myInapplicable = ContainerUtil.newArrayList(); myInapplicable.add(result); return; } if (!result.isAccessible() && myParameters.getInvocationCount() < 2) return; if (mySkipPackages && result.getElement() instanceof PsiPackage) return; PsiElement element = result.getElement(); if (element instanceof PsiVariable && !myMatcher.prefixMatches(((PsiVariable) element).getName())) { return; } if (element instanceof GrReflectedMethod) { element = ((GrReflectedMethod) element).getBaseMethod(); if (!myProcessedMethodWithOptionalParams.add((GrMethod) element)) return; result = new GroovyResolveResultImpl( element, result.getCurrentFileResolveContext(), result.getSpreadState(), result.getSubstitutor(), result.isAccessible(), result.isStaticsOK(), result.isInvokedOnProperty(), result.isValidResult()); } if (myFieldPointerOperator && !(element instanceof PsiVariable)) { return; } if (myMethodPointerOperator && !(element instanceof PsiMethod)) { return; } addCandidate(result); if (!myFieldPointerOperator && !myMethodPointerOperator) { if (element instanceof PsiMethod) { processProperty((PsiMethod) element, result); } else if (element instanceof GrField) { if (((GrField) element).isProperty()) { processPropertyFromField((GrField) element, result); } } } if (element instanceof GrVariable && !(element instanceof GrField)) { myLocalVars.add(((GrVariable) element).getName()); } }
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)}; } } } }
@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 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; }
@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 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(); } } } }
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 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(); }
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()]); }
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; }
@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 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; }
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; }
@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 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; }
@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()]); }
@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); } }
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()]); } } }
// 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; }
@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); }
@Override public PsiType fun(GrIndexPropertyImpl index) { GrExpression selected = index.getInvokedExpression(); PsiType thisType = selected.getType(); if (thisType == null) return null; GrArgumentList argList = index.getArgumentList(); PsiType[] argTypes = PsiUtil.getArgumentTypes(argList); if (argTypes == null) return null; final PsiManager manager = index.getManager(); final GlobalSearchScope resolveScope = index.getResolveScope(); if (argTypes.length == 0) { PsiType arrType = null; if (selected instanceof GrBuiltinTypeClassExpression) { arrType = ((GrBuiltinTypeClassExpression) selected).getPrimitiveType(); } if (selected instanceof GrReferenceExpression) { final PsiElement resolved = ((GrReferenceExpression) selected).resolve(); if (resolved instanceof PsiClass) { String qname = ((PsiClass) resolved).getQualifiedName(); if (qname != null) { arrType = TypesUtil.createTypeByFQClassName(qname, index); } } } if (arrType != null) { final PsiArrayType param = arrType.createArrayType(); return TypesUtil.createJavaLangClassType(param, index.getProject(), resolveScope); } } if (PsiImplUtil.isSimpleArrayAccess( thisType, argTypes, manager, resolveScope, PsiUtil.isLValue(index))) { return TypesUtil.boxPrimitiveType( ((PsiArrayType) thisType).getComponentType(), manager, resolveScope); } final GroovyResolveResult[] candidates = index.multiResolve(false); PsiType[] args = PsiUtil.getArgumentTypes( argList.getNamedArguments(), argList.getExpressionArguments(), GrClosableBlock.EMPTY_ARRAY, true, null, false); final GroovyResolveResult candidate = PsiImplUtil.extractUniqueResult(candidates); final PsiElement element = candidate.getElement(); if (element instanceof PsiNamedElement) { final String name = ((PsiNamedElement) element).getName(); if ("putAt".equals(name) && args != null) { args = ArrayUtil.append( args, TypeInferenceHelper.getInitializerFor(index), PsiType.class); } } PsiType overloadedOperatorType = ResolveUtil.extractReturnTypeFromCandidate(candidate, index, args); PsiType componentType = extractMapValueType(thisType, args, manager, resolveScope); if (overloadedOperatorType != null && (componentType == null || !TypesUtil.isAssignable( overloadedOperatorType, componentType, manager, resolveScope))) { return TypesUtil.boxPrimitiveType(overloadedOperatorType, manager, resolveScope); } return componentType; }
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; }
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; }
@Override public void renameElement( final PsiElement psiElement, String newName, final UsageInfo[] usages, @Nullable RefactoringElementListener listener) throws IncorrectOperationException { final GrField field = (GrField) psiElement; String fieldName = field.getName(); NameProvider nameProvider = new NameProvider(field, newName); MultiMap<PsiNamedElement, UsageInfo> propertyUsages = MultiMap.createLinked(); MultiMap<PsiNamedElement, UsageInfo> simpleUsages = MultiMap.createLinked(); List<PsiReference> unknownUsages = new ArrayList<>(); for (UsageInfo usage : usages) { final PsiReference ref = usage.getReference(); if (ref instanceof GrReferenceExpression) { final GroovyResolveResult resolveResult = ((GrReferenceExpression) ref).advancedResolve(); final PsiElement element = resolveResult.getElement(); if (resolveResult.isInvokedOnProperty()) { propertyUsages.putValue((PsiNamedElement) element, usage); } else { simpleUsages.putValue((PsiNamedElement) element, usage); } } else if (ref != null) { unknownUsages.add(ref); } } for (PsiReference ref : unknownUsages) { handleElementRename(newName, ref, fieldName); } field.setName(newName); nameProvider.putNewElements(field); PsiManager manager = field.getManager(); for (PsiNamedElement element : simpleUsages.keySet()) { for (UsageInfo info : simpleUsages.get(element)) { final String name = nameProvider.getNewName(element); rename( nameProvider.getNewElement(element), info, name == null ? newName : name, name != null, manager); } } for (PsiNamedElement element : propertyUsages.keySet()) { for (UsageInfo info : propertyUsages.get(element)) { rename(element, info, newName, true, manager); } } if (listener != null) { listener.elementRenamed(field); } }