@NotNull @Override public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression expr, boolean dummyImplicitConstructor, final boolean checkVarargs) { PsiFile containingFile = expr.getContainingFile(); final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr, containingFile) { @Override protected boolean acceptVarargs() { return checkVarargs; } }; try { PsiScopesUtil.setupAndRunProcessor(processor, expr, dummyImplicitConstructor); } catch (MethodProcessorSetupFailedException e) { return CandidateInfo.EMPTY_ARRAY; } return processor.getCandidates(); }
private static boolean processQualifierResult(@NotNull JavaResolveResult qualifierResult, @NotNull MethodsProcessor processor, @NotNull PsiMethodCallExpression methodCall) throws MethodProcessorSetupFailedException { PsiElement resolve = qualifierResult.getElement(); if (resolve == null) { throw new MethodProcessorSetupFailedException("Cant determine qualifier class!"); } if (resolve instanceof PsiTypeParameter) { processor.setAccessClass((PsiClass)resolve); } else if (resolve instanceof PsiClass) { PsiExpression qualifier = methodCall.getMethodExpression().getQualifierExpression(); if (!(qualifier instanceof PsiSuperExpression)) { processor.setAccessClass((PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement()); } } processor.setIsConstructor(false); processor.setName(methodCall.getMethodExpression().getReferenceName()); ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()); return resolve.processDeclarations(processor, state, methodCall, methodCall); }
@NotNull @Override public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression expr, boolean dummyImplicitConstructor, final boolean checkVarargs) { PsiFile containingFile = expr.getContainingFile(); final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr, containingFile) { @Override protected boolean acceptVarargs() { return checkVarargs; } }; try { PsiScopesUtil.setupAndRunProcessor(processor, expr, dummyImplicitConstructor); } catch(MethodProcessorSetupFailedException e) { return CandidateInfo.EMPTY_ARRAY; } return processor.getCandidates(); }
private static CandidateInfo[] getCandidates(PsiCallExpression call) { final MethodCandidatesProcessor processor = new MethodResolverProcessor(call, call.getContainingFile(), new PsiConflictResolver[0]) { @Override protected boolean acceptVarargs() { return false; } }; try { PsiScopesUtil.setupAndRunProcessor(processor, call, true); } catch(MethodProcessorSetupFailedException e) { return CandidateInfo.EMPTY_ARRAY; } final List<CandidateInfo> results = processor.getResults(); return results.toArray(new CandidateInfo[results.size()]); }
private static boolean processQualifierResult(@NotNull JavaResolveResult qualifierResult, @NotNull MethodsProcessor processor, @NotNull PsiMethodCallExpression methodCall) throws MethodProcessorSetupFailedException { PsiElement resolve = qualifierResult.getElement(); if (resolve == null) { throw new MethodProcessorSetupFailedException("Cant determine qualifier class!"); } if (resolve instanceof PsiTypeParameter) { processor.setAccessClass((PsiClass)resolve); } else if (resolve instanceof PsiClass) { PsiExpression qualifier = methodCall.getMethodExpression().getQualifierExpression(); if (!(qualifier instanceof PsiSuperExpression)) { processor.setAccessClass((PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement()); } else if (((PsiSuperExpression)qualifier).getQualifier() != null && PsiUtil.isLanguageLevel8OrHigher(qualifier) && CommonClassNames.JAVA_LANG_CLONEABLE.equals(((PsiClass)resolve).getQualifiedName()) && ((PsiClass)resolve).isInterface()) { processor.setAccessClass((PsiClass)resolve); } } processor.setIsConstructor(false); processor.setName(methodCall.getMethodExpression().getReferenceName()); ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()); return resolve.processDeclarations(processor, state, methodCall, methodCall); }
@Override public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall, PsiExpressionList expressionList, @NotNull PsiCallExpression contextCall, PsiTypeParameter typeParameter) { PsiExpression[] expressions = expressionList.getExpressions(); PsiElement parent = innerMethodCall; while (parent.getParent() instanceof PsiParenthesizedExpression) { parent = parent.getParent(); } int i = ArrayUtilRt.find(expressions, parent); if (i < 0) return null; PsiMethod owner = (PsiMethod)typeParameter.getOwner(); if (owner == null) return null; try { final JavaResolveResult[] results = getResults(contextCall, i); final PsiType innerReturnType = owner.getReturnType(); for (final JavaResolveResult result : results) { if (result == null) continue; final PsiSubstitutor substitutor = getSubstitutor(contextCall, expressions, i, result); final Pair<PsiType, ConstraintType> constraint = inferConstraint(typeParameter, innerMethodCall, i, innerReturnType, result, substitutor); if (constraint != null) return constraint; } } catch (MethodProcessorSetupFailedException ev) { return null; } return null; }
@NotNull protected JavaResolveResult[] getResults(@NotNull PsiCallExpression contextCall, final int exprIdx) throws MethodProcessorSetupFailedException { PsiFile containingFile = contextCall.getContainingFile(); final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall, containingFile); //can't call resolve() since it obtains full substitution, that may result in infinite recursion PsiScopesUtil.setupAndRunProcessor(processor, contextCall, false); return processor.getResult(); }
@NotNull private JavaResolveResult[] resolveToMethod(@NotNull PsiFile containingFile) { final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)getParent(); final MethodResolverProcessor processor = new MethodResolverProcessor(methodCall, containingFile); try { PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); } catch (MethodProcessorSetupFailedException e) { return JavaResolveResult.EMPTY_ARRAY; } return processor.getResult(); }
@Override @NotNull public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression expr, boolean dummyImplicitConstructor) { PsiFile containingFile = expr.getContainingFile(); final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr, containingFile); try { PsiScopesUtil.setupAndRunProcessor(processor, expr, dummyImplicitConstructor); } catch (MethodProcessorSetupFailedException e) { return CandidateInfo.EMPTY_ARRAY; } return processor.getCandidates(); }
private static boolean processQualifierResult(@NotNull JavaResolveResult qualifierResult, @NotNull MethodsProcessor processor, @NotNull PsiMethodCallExpression methodCall) throws MethodProcessorSetupFailedException { PsiElement resolve = qualifierResult.getElement(); if(resolve == null) { throw new MethodProcessorSetupFailedException("Cant determine qualifier class!"); } if(resolve instanceof PsiTypeParameter) { processor.setAccessClass((PsiClass) resolve); } else if(resolve instanceof PsiClass) { PsiExpression qualifier = methodCall.getMethodExpression().getQualifierExpression(); if(!(qualifier instanceof PsiSuperExpression)) { processor.setAccessClass((PsiClass) PsiUtil.getAccessObjectClass(qualifier).getElement()); } else if(((PsiSuperExpression) qualifier).getQualifier() != null && PsiUtil.isLanguageLevel8OrHigher(qualifier) && CommonClassNames.JAVA_LANG_CLONEABLE.equals(((PsiClass) resolve).getQualifiedName()) && ((PsiClass) resolve).isInterface()) { processor.setAccessClass((PsiClass) resolve); } } processor.setIsConstructor(false); processor.setName(methodCall.getMethodExpression().getReferenceName()); ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()); return resolve.processDeclarations(processor, state, methodCall, methodCall); }
@NotNull private JavaResolveResult[] resolveToMethod(@NotNull PsiFile containingFile) { final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) getParent(); final MethodResolverProcessor processor = new MethodResolverProcessor(methodCall, containingFile); try { PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); } catch(MethodProcessorSetupFailedException e) { return JavaResolveResult.EMPTY_ARRAY; } return processor.getResult(); }
@NotNull public static List<PsiClassType> getUnhandledExceptions(@NotNull final PsiCallExpression methodCall, @Nullable final PsiElement topElement, final boolean includeSelfCalls) { //exceptions only influence the invocation type after overload resolution is complete if (MethodCandidateInfo.isOverloadCheck()) { return Collections.emptyList(); } final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(methodCall.getArgumentList()); final JavaResolveResult result = properties != null ? properties.getInfo() : methodCall.resolveMethodGenerics(); final PsiMethod method = (PsiMethod)result.getElement(); if (method == null) { return Collections.emptyList(); } final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class); if (!includeSelfCalls && method == containingMethod) { return Collections.emptyList(); } final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes(); if (thrownExceptions.length == 0) { return Collections.emptyList(); } final PsiSubstitutor substitutor = getSubstitutor(result, methodCall); if (!isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) { final PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile(); final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile); try { PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); final List<Pair<PsiMethod, PsiSubstitutor>> candidates = ContainerUtil.mapNotNull( processor.getResults(), new Function<CandidateInfo, Pair<PsiMethod, PsiSubstitutor>>() { @Override public Pair<PsiMethod, PsiSubstitutor> fun(CandidateInfo info) { PsiElement element = info.getElement(); if (element instanceof PsiMethod && MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element) && !MethodSignatureUtil.isSuperMethod((PsiMethod)element, method)) { return Pair.create((PsiMethod)element, getSubstitutor(info, methodCall)); } return null; } }); if (candidates.size() > 1) { GlobalSearchScope scope = methodCall.getResolveScope(); final List<PsiClassType> ex = collectSubstituted(substitutor, thrownExceptions, scope); for (Pair<PsiMethod, PsiSubstitutor> pair : candidates) { final PsiClassType[] exceptions = pair.first.getThrowsList().getReferencedTypes(); if (exceptions.length == 0) { return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY); } retainExceptions(ex, collectSubstituted(pair.second, exceptions, scope)); } return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()])); } } catch (MethodProcessorSetupFailedException ignore) { return Collections.emptyList(); } } return getUnhandledExceptions(method, methodCall, topElement, substitutor); }
@NotNull public static List<PsiClassType> getUnhandledExceptions(@NotNull final PsiCallExpression methodCall, @Nullable final PsiElement topElement, boolean includeSelfCalls) { final JavaResolveResult result = methodCall.resolveMethodGenerics(); final PsiMethod method = (PsiMethod)result.getElement(); PsiMethod containingMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class); if (!includeSelfCalls && method == containingMethod) { return Collections.emptyList(); } final PsiSubstitutor substitutor = result.getSubstitutor(); if (method != null && !isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) { final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes(); if (thrownExceptions.length > 0) { PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile(); final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile); try { PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); final List<CandidateInfo> results = processor.getResults(); if (results.size() > 1) { final List<PsiClassType> ex = collectSubstituted(substitutor, thrownExceptions); for (CandidateInfo info : results) { final PsiElement element = info.getElement(); if (element instanceof PsiMethod && MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element)) { final PsiClassType[] exceptions = ((PsiMethod)element).getThrowsList().getReferencedTypes(); if (exceptions.length == 0) { return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY); } retainExceptions(ex, collectSubstituted(info.getSubstitutor(), exceptions)); } } return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()])); } } catch (MethodProcessorSetupFailedException ignore) { return Collections.emptyList(); } } } return getUnhandledExceptions(method, methodCall, topElement, substitutor); }
@NotNull public static List<PsiClassType> getUnhandledExceptions(@NotNull final PsiCallExpression methodCall, @Nullable final PsiElement topElement, final boolean includeSelfCalls) { //exceptions only influence the invocation type after overload resolution is complete if(MethodCandidateInfo.isOverloadCheck()) { return Collections.emptyList(); } final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(methodCall.getArgumentList()); final JavaResolveResult result = properties != null ? properties.getInfo() : PsiDiamondType.getDiamondsAwareResolveResult(methodCall); final PsiElement element = result.getElement(); final PsiMethod method = element instanceof PsiMethod ? (PsiMethod) element : null; if(method == null) { return Collections.emptyList(); } final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class); if(!includeSelfCalls && method == containingMethod) { return Collections.emptyList(); } if(properties != null) { PsiUtilCore.ensureValid(method); } final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes(); if(thrownExceptions.length == 0) { return Collections.emptyList(); } final PsiSubstitutor substitutor = result.getSubstitutor(); if(!isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) { final PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile(); final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression) methodCall, containingFile); try { PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); final List<Pair<PsiMethod, PsiSubstitutor>> candidates = ContainerUtil.mapNotNull(processor.getResults(), info -> { PsiElement element1 = info.getElement(); if(info instanceof MethodCandidateInfo && element1 != method && //don't check self MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod) element1) && !MethodSignatureUtil.isSuperMethod((PsiMethod) element1, method) && !(((MethodCandidateInfo) info) .isToInferApplicability() && !((MethodCandidateInfo) info).isApplicable())) { return Pair.create((PsiMethod) element1, ((MethodCandidateInfo) info).getSubstitutor(false)); } return null; }); if(!candidates.isEmpty()) { GlobalSearchScope scope = methodCall.getResolveScope(); final List<PsiClassType> ex = collectSubstituted(substitutor, thrownExceptions, scope); for(Pair<PsiMethod, PsiSubstitutor> pair : candidates) { final PsiClassType[] exceptions = pair.first.getThrowsList().getReferencedTypes(); if(exceptions.length == 0) { return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY); } retainExceptions(ex, collectSubstituted(pair.second, exceptions, scope)); } return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()])); } } catch(MethodProcessorSetupFailedException ignore) { return Collections.emptyList(); } } return getUnhandledExceptions(method, methodCall, topElement, substitutor); }
@Override public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall, PsiExpressionList expressionList, @NotNull PsiCallExpression contextCall, PsiTypeParameter typeParameter) { PsiExpression[] expressions = expressionList.getExpressions(); PsiElement parent = innerMethodCall; while(parent.getParent() instanceof PsiParenthesizedExpression) { parent = parent.getParent(); } int i = ArrayUtilRt.find(expressions, parent); if(i < 0) { return null; } PsiMethod owner = (PsiMethod) typeParameter.getOwner(); if(owner == null) { return null; } try { final JavaResolveResult[] results = getResults(contextCall, i); final PsiType innerReturnType = owner.getReturnType(); for(final JavaResolveResult result : results) { if(result == null) { continue; } final PsiSubstitutor substitutor = getSubstitutor(contextCall, expressions, i, result); final Pair<PsiType, ConstraintType> constraint = inferConstraint(typeParameter, innerMethodCall, i, innerReturnType, result, substitutor); if(constraint != null) { return constraint; } } } catch(MethodProcessorSetupFailedException ev) { return null; } return null; }