use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.
the class HighlightMethodUtil method checkConstructorCall.
static void checkConstructorCall(@NotNull PsiClassType.ClassResolveResult typeResolveResult, @NotNull PsiConstructorCall constructorCall, @NotNull PsiType type, PsiJavaCodeReferenceElement classReference, @NotNull HighlightInfoHolder holder, @NotNull JavaSdkVersion javaSdkVersion) {
PsiExpressionList list = constructorCall.getArgumentList();
if (list == null)
return;
PsiClass aClass = typeResolveResult.getElement();
if (aClass == null)
return;
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(holder.getProject()).getResolveHelper();
PsiClass accessObjectClass = null;
if (constructorCall instanceof PsiNewExpression) {
PsiExpression qualifier = ((PsiNewExpression) constructorCall).getQualifier();
if (qualifier != null) {
accessObjectClass = (PsiClass) PsiUtil.getAccessObjectClass(qualifier).getElement();
}
}
if (classReference != null && !resolveHelper.isAccessible(aClass, constructorCall, accessObjectClass)) {
String description = HighlightUtil.buildProblemWithAccessDescription(classReference, typeResolveResult);
PsiElement element = classReference.getReferenceNameElement();
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(description).create();
HighlightUtil.registerAccessQuickFixAction(aClass, classReference, info, null);
holder.add(info);
return;
}
PsiMethod[] constructors = aClass.getConstructors();
if (constructors.length == 0) {
if (list.getExpressions().length != 0) {
String constructorName = aClass.getName();
String argTypes = buildArgTypesList(list);
String description = JavaErrorMessages.message("wrong.constructor.arguments", constructorName + "()", argTypes);
String tooltip = createMismatchedArgumentsHtmlTooltip(list, null, PsiParameter.EMPTY_ARRAY, constructorName, PsiSubstitutor.EMPTY, aClass);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(list).description(description).escapedToolTip(tooltip).navigationShift(+1).create();
QuickFixAction.registerQuickFixAction(info, constructorCall.getTextRange(), QUICK_FIX_FACTORY.createCreateConstructorFromCallFix(constructorCall));
if (classReference != null) {
ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(list));
}
holder.add(info);
return;
}
if (classReference != null && aClass.hasModifierProperty(PsiModifier.PROTECTED) && callingProtectedConstructorFromDerivedClass(constructorCall, aClass)) {
holder.add(buildAccessProblem(classReference, typeResolveResult, aClass));
} else if (aClass.isInterface() && constructorCall instanceof PsiNewExpression) {
final PsiReferenceParameterList typeArgumentList = ((PsiNewExpression) constructorCall).getTypeArgumentList();
if (typeArgumentList.getTypeArguments().length > 0) {
holder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeArgumentList).descriptionAndTooltip("Anonymous class implements interface; cannot have type arguments").create());
}
}
} else {
PsiElement place = list;
if (constructorCall instanceof PsiNewExpression) {
final PsiAnonymousClass anonymousClass = ((PsiNewExpression) constructorCall).getAnonymousClass();
if (anonymousClass != null)
place = anonymousClass;
}
JavaResolveResult[] results = resolveHelper.multiResolveConstructor((PsiClassType) type, list, place);
MethodCandidateInfo result = null;
if (results.length == 1)
result = (MethodCandidateInfo) results[0];
PsiMethod constructor = result == null ? null : result.getElement();
boolean applicable = true;
try {
final PsiDiamondType diamondType = constructorCall instanceof PsiNewExpression ? PsiDiamondType.getDiamondType((PsiNewExpression) constructorCall) : null;
final JavaResolveResult staticFactory = diamondType != null ? diamondType.getStaticFactory() : null;
applicable = staticFactory instanceof MethodCandidateInfo ? ((MethodCandidateInfo) staticFactory).isApplicable() : result != null && result.isApplicable();
} catch (IndexNotReadyException e) {
// ignore
}
PsiElement infoElement = list.getTextLength() > 0 ? list : constructorCall;
if (constructor == null) {
String name = aClass.getName();
name += buildArgTypesList(list);
String description = JavaErrorMessages.message("cannot.resolve.constructor", name);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(list).descriptionAndTooltip(description).navigationShift(+1).create();
if (info != null) {
WrapExpressionFix.registerWrapAction(results, list.getExpressions(), info);
registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, results, infoElement, info);
holder.add(info);
}
} else {
if (classReference != null && (!result.isAccessible() || constructor.hasModifierProperty(PsiModifier.PROTECTED) && callingProtectedConstructorFromDerivedClass(constructorCall, aClass))) {
holder.add(buildAccessProblem(classReference, result, constructor));
} else if (!applicable) {
String constructorName = HighlightMessageUtil.getSymbolName(constructor, result.getSubstitutor());
String containerName = HighlightMessageUtil.getSymbolName(constructor.getContainingClass(), result.getSubstitutor());
String argTypes = buildArgTypesList(list);
String description = JavaErrorMessages.message("wrong.method.arguments", constructorName, containerName, argTypes);
String toolTip = createMismatchedArgumentsHtmlTooltip(result, list);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(infoElement).description(description).escapedToolTip(toolTip).navigationShift(+1).create();
if (info != null) {
JavaResolveResult[] methodCandidates = results;
if (constructorCall instanceof PsiNewExpression) {
methodCandidates = resolveHelper.getReferencedMethodCandidates((PsiCallExpression) constructorCall, true);
}
registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, methodCandidates, infoElement, info);
registerMethodReturnFixAction(info, result, constructorCall);
holder.add(info);
}
} else {
if (constructorCall instanceof PsiNewExpression) {
PsiReferenceParameterList typeArgumentList = ((PsiNewExpression) constructorCall).getTypeArgumentList();
HighlightInfo info = GenericsHighlightUtil.checkReferenceTypeArgumentList(constructor, typeArgumentList, result.getSubstitutor(), false, javaSdkVersion);
if (info != null) {
holder.add(info);
}
}
}
}
if (result != null && !holder.hasErrorResults()) {
holder.add(checkVarargParameterErasureToBeAccessible(result, constructorCall));
}
}
}
use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.
the class HighlightVisitorImpl method visitMethodReferenceExpression.
@Override
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
myHolder.add(checkFeature(expression, Feature.METHOD_REFERENCES));
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
if (parent instanceof PsiExpressionStatement)
return;
final JavaResolveResult result;
final JavaResolveResult[] results;
try {
results = expression.multiResolve(true);
result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
} catch (IndexNotReadyException e) {
return;
}
if (myRefCountHolder != null) {
myRefCountHolder.registerReference(expression, result);
}
final PsiElement method = result.getElement();
if (method != null && !result.isAccessible()) {
final String accessProblem = HighlightUtil.buildProblemWithAccessDescription(expression, result);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create();
HighlightUtil.registerAccessQuickFixAction((PsiMember) method, expression, info, result.getCurrentFileResolveScope());
myHolder.add(info);
} else {
final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
if (method instanceof PsiMethod && !expression.isConstructor()) {
PsiElement methodNameElement = expression.getReferenceNameElement();
if (methodNameElement != null) {
myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod) method, methodNameElement, false, colorsScheme));
}
}
myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(expression, colorsScheme));
}
if (!LambdaUtil.isValidLambdaContext(parent)) {
String description = "Method reference expression is not expected here";
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create());
}
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
if (!myHolder.hasErrorResults()) {
if (functionalInterfaceType != null) {
final boolean notFunctional = !LambdaUtil.isFunctionalType(functionalInterfaceType);
if (notFunctional) {
String description = functionalInterfaceType.getPresentableText() + " is not a functional interface";
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create());
}
}
}
if (!myHolder.hasErrorResults()) {
final PsiElement referenceNameElement = expression.getReferenceNameElement();
if (referenceNameElement instanceof PsiKeyword) {
if (!PsiMethodReferenceUtil.isValidQualifier(expression)) {
PsiElement qualifier = expression.getQualifier();
if (qualifier != null) {
String description = "Cannot find class " + qualifier.getText();
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create());
}
}
}
}
if (!myHolder.hasErrorResults()) {
checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
}
if (!myHolder.hasErrorResults() && functionalInterfaceType != null) {
final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
if (errorMessage != null) {
final HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create();
if (method instanceof PsiMethod && !((PsiMethod) method).isConstructor() && !((PsiMethod) method).hasModifierProperty(PsiModifier.ABSTRACT)) {
final boolean shouldHave = !((PsiMethod) method).hasModifierProperty(PsiModifier.STATIC);
final LocalQuickFixAndIntentionActionOnPsiElement fixStaticModifier = QuickFixFactory.getInstance().createModifierListFix((PsiModifierListOwner) method, PsiModifier.STATIC, shouldHave, false);
QuickFixAction.registerQuickFixAction(info, fixStaticModifier);
}
myHolder.add(info);
}
}
if (!myHolder.hasErrorResults()) {
PsiElement qualifier = expression.getQualifier();
if (qualifier instanceof PsiTypeElement) {
final PsiType psiType = ((PsiTypeElement) qualifier).getType();
final HighlightInfo genericArrayCreationInfo = GenericsHighlightUtil.checkGenericArrayCreation(qualifier, psiType);
if (genericArrayCreationInfo != null) {
myHolder.add(genericArrayCreationInfo);
} else {
final String wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments((PsiTypeElement) qualifier, psiType);
if (wildcardMessage != null) {
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(wildcardMessage).create());
}
}
}
}
if (!myHolder.hasErrorResults()) {
myHolder.add(PsiMethodReferenceHighlightingUtil.checkRawConstructorReference(expression));
}
if (!myHolder.hasErrorResults()) {
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
}
if (!myHolder.hasErrorResults()) {
final String badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType);
if (badReturnTypeMessage != null) {
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(badReturnTypeMessage).create());
}
}
if (!myHolder.hasErrorResults()) {
if (results.length == 0 || results[0] instanceof MethodCandidateInfo && !((MethodCandidateInfo) results[0]).isApplicable() && functionalInterfaceType != null) {
String description = null;
if (results.length == 1) {
description = ((MethodCandidateInfo) results[0]).getInferenceErrorMessage();
}
if (expression.isConstructor()) {
final PsiClass containingClass = PsiMethodReferenceUtil.getQualifierResolveResult(expression).getContainingClass();
if (containingClass != null) {
if (!myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) && !myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, containingClass)) && containingClass.isPhysical() && description == null) {
description = JavaErrorMessages.message("cannot.resolve.constructor", containingClass.getName());
}
}
} else if (description == null) {
description = JavaErrorMessages.message("cannot.resolve.method", expression.getReferenceName());
}
if (description != null) {
final PsiElement referenceNameElement = expression.getReferenceNameElement();
final HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(results.length == 0 ? HighlightInfoType.WRONG_REF : HighlightInfoType.ERROR).descriptionAndTooltip(description).range(referenceNameElement).create();
myHolder.add(highlightInfo);
final TextRange fixRange = HighlightMethodUtil.getFixRange(referenceNameElement);
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QuickFixFactory.getInstance().createCreateMethodFromUsageFix(expression));
}
}
}
}
use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.
the class PermuteArgumentsFix method registerFix.
public static void registerFix(HighlightInfo info, PsiCall callExpression, final CandidateInfo[] candidates, final TextRange fixRange) {
PsiExpression[] expressions = callExpression.getArgumentList().getExpressions();
if (expressions.length < 2)
return;
List<PsiCall> permutations = new ArrayList<>();
for (CandidateInfo candidate : candidates) {
if (candidate instanceof MethodCandidateInfo) {
MethodCandidateInfo methodCandidate = (MethodCandidateInfo) candidate;
PsiMethod method = methodCandidate.getElement();
PsiSubstitutor substitutor = methodCandidate.getSubstitutor();
PsiParameter[] parameters = method.getParameterList().getParameters();
if (expressions.length != parameters.length || parameters.length == 0)
continue;
int minIncompatibleIndex = parameters.length;
int maxIncompatibleIndex = 0;
int incompatibilitiesCount = 0;
for (int i = 0; i < parameters.length; i++) {
PsiParameter parameter = parameters[i];
PsiType type = substitutor.substitute(parameter.getType());
if (TypeConversionUtil.areTypesAssignmentCompatible(type, expressions[i]))
continue;
if (minIncompatibleIndex == parameters.length)
minIncompatibleIndex = i;
maxIncompatibleIndex = i;
incompatibilitiesCount++;
}
try {
registerSwapFixes(expressions, callExpression, permutations, methodCandidate, incompatibilitiesCount, minIncompatibleIndex, maxIncompatibleIndex);
registerShiftFixes(expressions, callExpression, permutations, methodCandidate, minIncompatibleIndex, maxIncompatibleIndex);
} catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
if (permutations.size() == 1) {
PermuteArgumentsFix fix = new PermuteArgumentsFix(callExpression, permutations.get(0));
QuickFixAction.registerQuickFixAction(info, fixRange, fix);
}
}
use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.
the class Java8ExpressionsCheckTest method testRejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload.
public void testRejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload() throws Exception {
final String filePath = BASE_PATH + "/" + getTestName(false) + ".java";
configureByFile(filePath);
PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiMethodCallExpression.class);
assertNotNull(methodCall);
final PsiResolveHelper helper = JavaPsiFacade.getInstance(methodCall.getProject()).getResolveHelper();
CandidateInfo[] candidates = helper.getReferencedMethodCandidates(methodCall, false, true);
for (CandidateInfo candidate : candidates) {
if (candidate instanceof MethodCandidateInfo) {
//try to cache top level session
candidate.getSubstitutor();
}
}
doTestConfiguredFile(false, false, filePath);
}
use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.
the class JavaMethodsConflictResolver method checkParametersNumber.
public boolean checkParametersNumber(@NotNull List<CandidateInfo> conflicts, final int argumentsCount, FactoryMap<MethodCandidateInfo, PsiSubstitutor> map, boolean ignoreIfStaticsProblem) {
boolean atLeastOneMatch = false;
TIntArrayList unmatchedIndices = null;
for (int i = 0; i < conflicts.size(); i++) {
ProgressManager.checkCanceled();
CandidateInfo info = conflicts.get(i);
if (ignoreIfStaticsProblem && !info.isStaticsScopeCorrect())
return true;
if (!(info instanceof MethodCandidateInfo))
continue;
PsiMethod method = ((MethodCandidateInfo) info).getElement();
final int parametersCount = method.getParameterList().getParametersCount();
boolean isVarargs = (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ? ((MethodCandidateInfo) info).isVarargs() : method.isVarArgs()) && parametersCount - 1 <= argumentsCount;
if (isVarargs || parametersCount == argumentsCount) {
// remove all unmatched before
if (unmatchedIndices != null) {
for (int u = unmatchedIndices.size() - 1; u >= 0; u--) {
int index = unmatchedIndices.get(u);
//ensure super method with varargs won't win over non-vararg override
if (ignoreIfStaticsProblem && isVarargs) {
MethodCandidateInfo candidateInfo = (MethodCandidateInfo) conflicts.get(index);
PsiMethod candidateToRemove = candidateInfo.getElement();
if (candidateToRemove != method) {
PsiSubstitutor candidateToRemoveSubst = map.get(candidateInfo);
PsiSubstitutor substitutor = map.get(info);
if (MethodSignatureUtil.isSubsignature(candidateToRemove.getSignature(candidateToRemoveSubst), method.getSignature(substitutor))) {
continue;
}
}
}
conflicts.remove(index);
i--;
}
unmatchedIndices = null;
}
atLeastOneMatch = true;
} else if (atLeastOneMatch) {
conflicts.remove(i);
i--;
} else {
if (unmatchedIndices == null)
unmatchedIndices = new TIntArrayList(conflicts.size() - i);
unmatchedIndices.add(i);
}
}
return atLeastOneMatch;
}
Aggregations