mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-84657 No need to report non-inferrable argument types when parameter types are not specified
This commit is contained in:
+88
-56
@@ -55,6 +55,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
@@ -264,8 +265,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
final PsiElement constructor = constructorResolveResult.getElement();
|
||||
|
||||
if (constructor != null) {
|
||||
if (!checkConstructorApplicability(constructorResolveResult, refElement)) return;
|
||||
if (!checkUnknownParams(refElement)) return;
|
||||
if (!checkConstructorApplicability(constructorResolveResult, refElement, true)) return;
|
||||
}
|
||||
else {
|
||||
final GroovyResolveResult[] results = constructorCall.multiResolve(false);
|
||||
@@ -273,10 +273,9 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
for (GroovyResolveResult result : results) {
|
||||
PsiElement resolved = result.getElement();
|
||||
if (resolved instanceof PsiMethod) {
|
||||
if (!checkConstructorApplicability(result, refElement)) return;
|
||||
if (!checkConstructorApplicability(result, refElement, false)) return;
|
||||
}
|
||||
}
|
||||
if (!checkUnknownParams(refElement)) return;
|
||||
registerError(getElementToHighlight(refElement, argList), GroovyBundle.message("constructor.call.is.ambiguous"));
|
||||
}
|
||||
else {
|
||||
@@ -336,21 +335,21 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
else if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()){
|
||||
checkLiteralConstructorApplicability(result, listOrMap);
|
||||
checkLiteralConstructorApplicability(result, listOrMap, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (GroovyResolveResult result : results) {
|
||||
PsiElement resolved = result.getElement();
|
||||
if (resolved instanceof PsiMethod) {
|
||||
if (!checkLiteralConstructorApplicability(result, listOrMap)) return;
|
||||
if (!checkLiteralConstructorApplicability(result, listOrMap, false)) return;
|
||||
}
|
||||
registerError(listOrMap, GroovyBundle.message("constructor.call.is.ambiguous"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkLiteralConstructorApplicability(GroovyResolveResult result, GrListOrMap listOrMap) {
|
||||
private boolean checkLiteralConstructorApplicability(GroovyResolveResult result, GrListOrMap listOrMap, boolean checkUnknownArgs) {
|
||||
final PsiElement element = result.getElement();
|
||||
LOG.assertTrue(element instanceof PsiMethod && ((PsiMethod)element).isConstructor());
|
||||
final PsiMethod constructor = (PsiMethod)element;
|
||||
@@ -373,15 +372,23 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
argumentTypes = new PsiType[]{listOrMap.getType()};
|
||||
}
|
||||
|
||||
if (PsiUtil.isApplicable(argumentTypes, constructor, result.getSubstitutor(), listOrMap, false)) {
|
||||
return true;
|
||||
GrClosureSignatureUtil.ApplicabilityResult applicable =
|
||||
PsiUtil.isApplicableConcrete(argumentTypes, constructor, result.getSubstitutor(), listOrMap, false);
|
||||
switch (applicable) {
|
||||
case inapplicable:
|
||||
highlightInapplicableMethodUsage(result, listOrMap, constructor, argumentTypes);
|
||||
return false;
|
||||
case canBeApplicable:
|
||||
if (checkUnknownArgs) {
|
||||
highlightUnknownArgs(listOrMap);
|
||||
}
|
||||
return !checkUnknownArgs;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
highlightInapplicableMethodUsage(result, listOrMap, constructor, argumentTypes);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkConstructorApplicability(GroovyResolveResult constructorResolveResult, GroovyPsiElement place) {
|
||||
private boolean checkConstructorApplicability(GroovyResolveResult constructorResolveResult, GroovyPsiElement place, boolean checkUnknownArgs) {
|
||||
final PsiElement element = constructorResolveResult.getElement();
|
||||
LOG.assertTrue(element instanceof PsiMethod && ((PsiMethod)element).isConstructor());
|
||||
final PsiMethod constructor = (PsiMethod)element;
|
||||
@@ -392,7 +399,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
|
||||
if (exprArgs.length == 0 && !PsiUtil.isConstructorHasRequiredParameters(constructor)) return true;
|
||||
}
|
||||
return checkMethodApplicability(constructorResolveResult, place);
|
||||
return checkMethodApplicability(constructorResolveResult, place, checkUnknownArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -422,25 +429,22 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
final PsiType type = referenceExpression.getType();
|
||||
if (resolved != null) {
|
||||
if (resolved instanceof PsiMethod && !resolveResult.isInvokedOnProperty()) {
|
||||
if (!checkMethodApplicability(resolveResult, referenceExpression)) return;
|
||||
if (!checkMethodApplicability(resolveResult, referenceExpression, true)) return;
|
||||
}
|
||||
else {
|
||||
if (!checkCallApplicability(type, referenceExpression)) return;
|
||||
if (!checkCallApplicability(type, referenceExpression, true)) return;
|
||||
}
|
||||
|
||||
if (!checkUnknownParams(referenceExpression)) return;
|
||||
}
|
||||
else if (results.length > 0) {
|
||||
for (GroovyResolveResult result : results) {
|
||||
resolved = result.getElement();
|
||||
if (resolved instanceof PsiMethod && !resolveResult.isInvokedOnProperty()) {
|
||||
if (!checkMethodApplicability(result, referenceExpression)) return;
|
||||
if (!checkMethodApplicability(result, referenceExpression, false)) return;
|
||||
}
|
||||
else {
|
||||
if (!checkCallApplicability(type, referenceExpression)) return;
|
||||
if (!checkCallApplicability(type, referenceExpression, false)) return;
|
||||
}
|
||||
}
|
||||
if (!checkUnknownParams(referenceExpression)) return;
|
||||
|
||||
registerError(getElementToHighlight(referenceExpression, PsiUtil.getArgumentsList(referenceExpression)),
|
||||
GroovyBundle.message("method.call.is.ambiguous"));
|
||||
@@ -448,14 +452,13 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkUnknownParams(PsiElement place) {
|
||||
private boolean checkUnknownParams(PsiElement place, PsiElement resolved) {
|
||||
PsiType[] args = PsiUtil.getArgumentTypes(place, true);
|
||||
if (args == null) return true;
|
||||
|
||||
for (PsiType arg : args) {
|
||||
if (arg == null) {
|
||||
registerError(getElementToHighlight(place, PsiUtil.getArgumentsList(place)), GroovyBundle.message("cannot.infer.argument.types"),
|
||||
LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.WEAK_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -523,7 +526,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
final GrExpression expression = call.getInvokedExpression();
|
||||
if (!(expression instanceof GrReferenceExpression)) { //it checks in visitRefExpr(...)
|
||||
final PsiType type = expression.getType();
|
||||
checkCallApplicability(type, expression);
|
||||
checkCallApplicability(type, expression, true);
|
||||
}
|
||||
|
||||
checkNamedArgumentsType(call);
|
||||
@@ -555,29 +558,36 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
|
||||
private boolean checkCallApplicability(PsiType type, GroovyPsiElement invokedExpr) {
|
||||
private boolean checkCallApplicability(PsiType type, GroovyPsiElement invokedExpr, boolean checkUnknownArgs) {
|
||||
|
||||
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invokedExpr, true);
|
||||
if (type instanceof GrClosureType) {
|
||||
if (argumentTypes == null) return true;
|
||||
|
||||
if (PsiUtil.isApplicable(argumentTypes, (GrClosureType)type, invokedExpr)) return true;
|
||||
|
||||
registerCannotApplyError(invokedExpr, argumentTypes, invokedExpr.getText());
|
||||
return false;
|
||||
GrClosureSignatureUtil.ApplicabilityResult result = PsiUtil.isApplicableConcrete(argumentTypes, (GrClosureType)type, invokedExpr);
|
||||
switch (result) {
|
||||
case inapplicable:
|
||||
registerCannotApplyError(invokedExpr, argumentTypes, invokedExpr.getText());
|
||||
return false;
|
||||
case canBeApplicable:
|
||||
if (checkUnknownArgs) {
|
||||
highlightUnknownArgs(invokedExpr);
|
||||
}
|
||||
return !checkUnknownArgs;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (type != null) {
|
||||
final GroovyResolveResult[] calls = ResolveUtil.getMethodCandidates(type, "call", invokedExpr, argumentTypes);
|
||||
for (GroovyResolveResult result : calls) {
|
||||
PsiElement resolved = result.getElement();
|
||||
if (resolved instanceof PsiMethod && !result.isInvokedOnProperty()) {
|
||||
if (!checkMethodApplicability(result, invokedExpr)) return false;
|
||||
if (!checkUnknownParams(invokedExpr)) return false;
|
||||
if (!checkMethodApplicability(result, invokedExpr, checkUnknownArgs && calls.length == 1)) return false;
|
||||
}
|
||||
else if (resolved instanceof PsiField) {
|
||||
if (!checkCallApplicability(((PsiField)resolved).getType(), invokedExpr)) return false;
|
||||
if (!checkCallApplicability(((PsiField)resolved).getType(), invokedExpr, checkUnknownArgs && calls.length == 1)) return false;
|
||||
}
|
||||
if (!checkUnknownParams(invokedExpr)) return false;
|
||||
}
|
||||
if (calls.length == 0 && !(invokedExpr instanceof GrString)) {
|
||||
registerCannotApplyError(invokedExpr, argumentTypes, invokedExpr.getText());
|
||||
@@ -609,7 +619,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private boolean checkMethodApplicability(GroovyResolveResult methodResolveResult, GroovyPsiElement place) {
|
||||
private boolean checkMethodApplicability(GroovyResolveResult methodResolveResult, GroovyPsiElement place, boolean checkUnknownArgs) {
|
||||
final PsiElement element = methodResolveResult.getElement();
|
||||
if (!(element instanceof PsiMethod)) return true;
|
||||
if (element instanceof GrBuilderMethod) return true;
|
||||
@@ -621,39 +631,61 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
if (qualifierExpression != null) {
|
||||
final PsiType type = qualifierExpression.getType();
|
||||
if (type instanceof GrClosureType) {
|
||||
if (!PsiUtil.isApplicable(argumentTypes, (GrClosureType)type, place)) {
|
||||
highlightInapplicableMethodUsage(methodResolveResult, place, method, argumentTypes);
|
||||
return false;
|
||||
GrClosureSignatureUtil.ApplicabilityResult result = PsiUtil.isApplicableConcrete(argumentTypes, (GrClosureType)type, place);
|
||||
switch (result) {
|
||||
case inapplicable:
|
||||
highlightInapplicableMethodUsage(methodResolveResult, place, method, argumentTypes);
|
||||
return false;
|
||||
case canBeApplicable:
|
||||
if (checkUnknownArgs) {
|
||||
highlightUnknownArgs(place);
|
||||
}
|
||||
return !checkUnknownArgs;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argumentTypes != null &&
|
||||
!PsiUtil.isApplicable(argumentTypes, method, methodResolveResult.getSubstitutor(), place, false)) {
|
||||
if (argumentTypes == null) return true;
|
||||
|
||||
//check for implicit use of property getter which returns closure
|
||||
if (GroovyPropertyUtils.isSimplePropertyGetter(method)) {
|
||||
if (method instanceof GrMethod || method instanceof GrAccessorMethod) {
|
||||
final PsiType returnType = PsiUtil.getSmartReturnType(method);
|
||||
if (returnType instanceof GrClosureType) {
|
||||
if (PsiUtil.isApplicable(argumentTypes, ((GrClosureType)returnType), place)) {
|
||||
GrClosureSignatureUtil.ApplicabilityResult applicable = PsiUtil.isApplicableConcrete(argumentTypes, method, methodResolveResult.getSubstitutor(), place, false);
|
||||
switch (applicable) {
|
||||
case inapplicable:
|
||||
//check for implicit use of property getter which returns closure
|
||||
if (GroovyPropertyUtils.isSimplePropertyGetter(method)) {
|
||||
if (method instanceof GrMethod || method instanceof GrAccessorMethod) {
|
||||
final PsiType returnType = PsiUtil.getSmartReturnType(method);
|
||||
if (returnType instanceof GrClosureType) {
|
||||
if (PsiUtil.isApplicable(argumentTypes, ((GrClosureType)returnType), place)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiType returnType = method.getReturnType();
|
||||
if (returnType != null) {
|
||||
if (TypesUtil.isAssignable(TypesUtil.createType(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, element), returnType, place)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiType returnType = method.getReturnType();
|
||||
if (returnType != null) {
|
||||
if (TypesUtil.isAssignable(TypesUtil.createType(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, element), returnType, place)) {
|
||||
return true;
|
||||
}
|
||||
highlightInapplicableMethodUsage(methodResolveResult, place, method, argumentTypes);
|
||||
return false;
|
||||
case canBeApplicable:
|
||||
if (checkUnknownArgs) {
|
||||
highlightUnknownArgs(place);
|
||||
}
|
||||
}
|
||||
|
||||
highlightInapplicableMethodUsage(methodResolveResult, place, method, argumentTypes);
|
||||
return false;
|
||||
return !checkUnknownArgs;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void highlightUnknownArgs(GroovyPsiElement place) {
|
||||
registerError(getElementToHighlight(place, PsiUtil.getArgumentsList(place)), GroovyBundle.message("cannot.infer.argument.types"),
|
||||
LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.WEAK_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+47
-17
@@ -167,26 +167,56 @@ public class GrClosureSignatureUtil {
|
||||
return new GrClosureSignatureImpl(parameters, returnType);
|
||||
}
|
||||
|
||||
public static boolean isSignatureApplicable(GrClosureSignature signature, PsiType[] args, GroovyPsiElement context) {
|
||||
if (mapArgTypesToParameters(signature, args, context, false) != null) return true;
|
||||
public static boolean isSignatureApplicable(@NotNull GrClosureSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) {
|
||||
return isSignatureApplicableConcrete(signature, args, context) != ApplicabilityResult.inapplicable;
|
||||
}
|
||||
|
||||
public static ApplicabilityResult isSignatureApplicableConcrete(@NotNull GrClosureSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) {
|
||||
ArgInfo<PsiType>[] map = mapArgTypesToParameters(signature, args, context, false);
|
||||
if (map != null) return isSignatureApplicableInner(map, signature);
|
||||
|
||||
// check for the case foo([1, 2, 3]) if foo(int, int, int)
|
||||
if (args.length == 1 && PsiUtil.isInMethodCallContext(context)) {
|
||||
final GrClosureParameter[] parameters = signature.getParameters();
|
||||
if (parameters.length == 1 && parameters[0].getType() instanceof PsiArrayType) return false;
|
||||
if (parameters.length == 1 && parameters[0].getType() instanceof PsiArrayType) return ApplicabilityResult.inapplicable;
|
||||
PsiType arg = args[0];
|
||||
if (arg instanceof GrTupleType) {
|
||||
args = ((GrTupleType)arg).getComponentTypes();
|
||||
if (mapArgTypesToParameters(signature, args, context, false) != null) return true;
|
||||
map = mapArgTypesToParameters(signature, args, context, false);
|
||||
if (map != null) return isSignatureApplicableInner(map, signature);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ApplicabilityResult.inapplicable;
|
||||
}
|
||||
|
||||
private static ApplicabilityResult isSignatureApplicableInner(@NotNull ArgInfo<PsiType>[] infos, @NotNull GrClosureSignature signature) {
|
||||
GrClosureParameter[] parameters = signature.getParameters();
|
||||
for (int i = 0; i < infos.length; i++) {
|
||||
ArgInfo<PsiType> info = infos[i];
|
||||
if (info.args.size() != 1 || info.isMultiArg) continue;
|
||||
PsiType type = info.args.get(0);
|
||||
if (type != null) continue;
|
||||
|
||||
PsiType pType = parameters[i].getType();
|
||||
if (pType != null && !pType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
return ApplicabilityResult.canBeApplicable;
|
||||
}
|
||||
}
|
||||
return ApplicabilityResult.applicable;
|
||||
}
|
||||
|
||||
public enum ApplicabilityResult {
|
||||
applicable, inapplicable, canBeApplicable;
|
||||
|
||||
public static boolean isApplicable(ApplicabilityResult r) {
|
||||
return r != inapplicable;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ArgInfo<PsiType>[] mapArgTypesToParameters(@NotNull GrClosureSignature signature,
|
||||
PsiType[] args,
|
||||
GroovyPsiElement context,
|
||||
@NotNull PsiType[] args,
|
||||
@NotNull GroovyPsiElement context,
|
||||
boolean partial) {
|
||||
return mapParametersToArguments(signature, args, FunctionUtil.<PsiType>id(), context, partial);
|
||||
}
|
||||
@@ -211,9 +241,9 @@ public class GrClosureSignatureUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <Arg> ArgWrapper<Arg>[] getActualArgs(GrCurriedClosureSignature signature,
|
||||
Arg[] args,
|
||||
Function<Arg, PsiType> typeComputer) {
|
||||
private static <Arg> ArgWrapper<Arg>[] getActualArgs(@NotNull GrCurriedClosureSignature signature,
|
||||
@NotNull Arg[] args,
|
||||
@NotNull Function<Arg, PsiType> typeComputer) {
|
||||
List<ArgWrapper<Arg>> actual = new ArrayList<ArgWrapper<Arg>>(signature.getParameterCount());
|
||||
for (Arg arg : args) {
|
||||
actual.add(new ArgWrapper<Arg>(typeComputer.fun(arg), arg));
|
||||
@@ -243,8 +273,8 @@ public class GrClosureSignatureUtil {
|
||||
|
||||
@Nullable
|
||||
private static <Arg> ArgInfo<Arg>[] mapParametersToArguments(@NotNull GrClosureSignature signature,
|
||||
Arg[] args,
|
||||
Function<Arg, PsiType> typeComputer,
|
||||
@NotNull Arg[] args,
|
||||
@NotNull Function<Arg, PsiType> typeComputer,
|
||||
@NotNull GroovyPsiElement context,
|
||||
boolean partial) {
|
||||
if (signature instanceof GrCurriedClosureSignature) {
|
||||
@@ -291,10 +321,10 @@ public class GrClosureSignatureUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <Arg> ArgInfo<Arg>[] mapSimple(GrClosureParameter[] params,
|
||||
Arg[] args,
|
||||
Function<Arg, PsiType> typeComputer,
|
||||
GroovyPsiElement context) {
|
||||
private static <Arg> ArgInfo<Arg>[] mapSimple(@NotNull GrClosureParameter[] params,
|
||||
@NotNull Arg[] args,
|
||||
@NotNull Function<Arg, PsiType> typeComputer,
|
||||
@NotNull GroovyPsiElement context) {
|
||||
ArgInfo<Arg>[] map = new ArgInfo[params.length];
|
||||
int optional = getOptionalParamCount(params, false);
|
||||
int notOptional = params.length - optional;
|
||||
@@ -315,7 +345,7 @@ public class GrClosureSignatureUtil {
|
||||
return map;
|
||||
}
|
||||
|
||||
private static boolean isAssignableByConversion(PsiType paramType, PsiType argType, GroovyPsiElement context) {
|
||||
private static boolean isAssignableByConversion(@Nullable PsiType paramType, @Nullable PsiType argType, @NotNull GroovyPsiElement context) {
|
||||
if (argType == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,11 +135,20 @@ public class PsiUtil {
|
||||
}
|
||||
|
||||
public static boolean isApplicable(@Nullable PsiType[] argumentTypes,
|
||||
PsiMethod method,
|
||||
PsiSubstitutor substitutor,
|
||||
GroovyPsiElement place,
|
||||
final boolean eraseParameterTypes) {
|
||||
if (argumentTypes == null) return true;
|
||||
PsiMethod method,
|
||||
PsiSubstitutor substitutor,
|
||||
GroovyPsiElement place,
|
||||
final boolean eraseParameterTypes) {
|
||||
return isApplicableConcrete(argumentTypes, method, substitutor, place, eraseParameterTypes) !=
|
||||
GrClosureSignatureUtil.ApplicabilityResult.inapplicable;
|
||||
}
|
||||
|
||||
public static GrClosureSignatureUtil.ApplicabilityResult isApplicableConcrete(@Nullable PsiType[] argumentTypes,
|
||||
PsiMethod method,
|
||||
PsiSubstitutor substitutor,
|
||||
GroovyPsiElement place,
|
||||
final boolean eraseParameterTypes) {
|
||||
if (argumentTypes == null) return GrClosureSignatureUtil.ApplicabilityResult.canBeApplicable;
|
||||
|
||||
GrClosureSignature signature = eraseParameterTypes
|
||||
? GrClosureSignatureUtil.createSignatureWithErasedParameterTypes(method)
|
||||
@@ -149,34 +158,45 @@ public class PsiUtil {
|
||||
if (method.isConstructor()) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length == 0 && argumentTypes.length == 1) {
|
||||
return InheritanceUtil.isInheritor(argumentTypes[0], CommonClassNames.JAVA_UTIL_MAP);
|
||||
return InheritanceUtil.isInheritor(argumentTypes[0], CommonClassNames.JAVA_UTIL_MAP)
|
||||
? GrClosureSignatureUtil.ApplicabilityResult.applicable
|
||||
: GrClosureSignatureUtil.ApplicabilityResult.inapplicable;
|
||||
}
|
||||
if (parameters.length == 1 &&
|
||||
argumentTypes.length == 0 &&
|
||||
InheritanceUtil.isInheritor(parameters[0].getType(), CommonClassNames.JAVA_UTIL_MAP)) {
|
||||
return false;
|
||||
return GrClosureSignatureUtil.ApplicabilityResult.inapplicable;
|
||||
}
|
||||
}
|
||||
LOG.assertTrue(signature != null);
|
||||
if (GrClosureSignatureUtil.isSignatureApplicable(signature, argumentTypes, place)) {
|
||||
return true;
|
||||
GrClosureSignatureUtil.ApplicabilityResult result = GrClosureSignatureUtil.isSignatureApplicableConcrete(signature, argumentTypes, place);
|
||||
if (result != GrClosureSignatureUtil.ApplicabilityResult.inapplicable) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (method instanceof GrBuilderMethod &&!((GrBuilderMethod)method).hasObligatoryNamedArguments()) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length > 0 && parameters[0].getType() instanceof GrMapType &&
|
||||
(argumentTypes.length == 0 || !(argumentTypes[0] instanceof GrMapType))) {
|
||||
return GrClosureSignatureUtil.isSignatureApplicable(GrClosureSignatureUtil.removeParam(signature, 0), argumentTypes, place);
|
||||
return GrClosureSignatureUtil.isSignatureApplicableConcrete(GrClosureSignatureUtil.removeParam(signature, 0), argumentTypes, place);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return GrClosureSignatureUtil.ApplicabilityResult.inapplicable;
|
||||
}
|
||||
|
||||
public static boolean isApplicable(@Nullable PsiType[] argumentTypes, GrClosureType type, GroovyPsiElement context) {
|
||||
if (argumentTypes == null) return true;
|
||||
public static boolean isApplicable(@Nullable PsiType[] argumentTypes,
|
||||
GrClosureType type,
|
||||
GroovyPsiElement context) {
|
||||
return isApplicableConcrete(argumentTypes, type, context) != GrClosureSignatureUtil.ApplicabilityResult.inapplicable;
|
||||
}
|
||||
|
||||
public static GrClosureSignatureUtil.ApplicabilityResult isApplicableConcrete(@Nullable PsiType[] argumentTypes,
|
||||
GrClosureType type,
|
||||
GroovyPsiElement context) {
|
||||
if (argumentTypes == null) return GrClosureSignatureUtil.ApplicabilityResult.canBeApplicable;
|
||||
|
||||
GrClosureSignature signature = type.getSignature();
|
||||
return GrClosureSignatureUtil.isSignatureApplicable(signature, argumentTypes, context);
|
||||
return GrClosureSignatureUtil.isSignatureApplicableConcrete(signature, argumentTypes, context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -788,4 +788,19 @@ class C {
|
||||
myFixture.testHighlighting(true, false, false)
|
||||
}
|
||||
|
||||
public void testNonInferrableArgsOfDefParams() {
|
||||
myFixture.configureByText('_.groovy', '''\
|
||||
def foo0(def a) { }
|
||||
def bar0(def b) { foo0(b) }
|
||||
|
||||
def foo1(Object a) { }
|
||||
def bar1(def b) { foo1(b) }
|
||||
|
||||
def foo2(String a) { }
|
||||
def bar2(def b) { foo2<weak_warning descr="Cannot infer argument types">(b)</weak_warning> }
|
||||
''')
|
||||
myFixture.enableInspections(new GroovyAssignabilityCheckInspection())
|
||||
myFixture.testHighlighting(true, false, true)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,4 +10,4 @@ def abc(Date d){}
|
||||
def abc(int i) {}
|
||||
|
||||
def x = unknown2
|
||||
abc<weak_warning descr="Cannot infer argument types">(x)</weak_warning>
|
||||
abc<warning descr="Method call is ambiguous">(x)</warning>
|
||||
Reference in New Issue
Block a user