You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/10/25 23:59:44 UTC
[groovy] branch master updated: STC: simplify `visitStaticMethodCallExpression`
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 837794caca STC: simplify `visitStaticMethodCallExpression`
837794caca is described below
commit 837794caca5a26ce8493fda0d573cca072dd3040
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Oct 25 18:59:30 2022 -0500
STC: simplify `visitStaticMethodCallExpression`
---
.../transform/stc/StaticTypeCheckingVisitor.java | 55 +++++++++-------------
1 file changed, 21 insertions(+), 34 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 8a248221b3..e3997e0303 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2711,66 +2711,53 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
addStaticTypeError("cannot resolve dynamic method name at compile time.", call);
return;
}
-
if (extension.beforeMethodCall(call)) {
extension.afterMethodCall(call);
return;
}
+ try {
+ ClassNode receiver = call.getOwnerType();
+ ArgumentListExpression argumentList = InvocationWriter.makeArgumentList(call.getArguments());
- ClassNode receiver = call.getOwnerType();
- ArgumentListExpression argumentList = InvocationWriter.makeArgumentList(call.getArguments());
-
- visitMethodCallArguments(receiver, argumentList, false, null);
- ClassNode[] args = getArgumentTypes(argumentList);
+ boolean closuresVisited = false; // visit *after* method has been chosen
+ visitMethodCallArguments(receiver, argumentList, closuresVisited, null);
+ ClassNode[] args = getArgumentTypes(argumentList);
- try {
- // method call receivers are :
- // - possible "with" receivers
- // - the actual receiver as found in the method call expression
- // - any of the potential receivers found in the instanceof temporary table
- // in that order
- List<Receiver<String>> receivers = new LinkedList<>();
- addReceivers(receivers, makeOwnerList(new ClassExpression(receiver)), false);
- List<MethodNode> mn = null;
- Receiver<String> chosenReceiver = null;
- for (Receiver<String> currentReceiver : receivers) {
- mn = findMethod(currentReceiver.getType(), name, args);
- if (!mn.isEmpty()) {
- if (mn.size() == 1) {
- // GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
- resolvePlaceholdersFromImplicitTypeHints(args, argumentList, mn.get(0).getParameters());
- typeCheckMethodsWithGenericsOrFail(currentReceiver.getType(), args, mn.get(0), call);
- }
- chosenReceiver = currentReceiver;
- break;
+ List<MethodNode> mn = findMethod(receiver, name, args);
+ if (!mn.isEmpty()) {
+ if (mn.size() == 1) {
+ // GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
+ resolvePlaceholdersFromImplicitTypeHints(args, argumentList, mn.get(0).getParameters());
+ typeCheckMethodsWithGenericsOrFail(receiver, args, mn.get(0), call);
}
}
if (mn.isEmpty()) {
mn = extension.handleMissingMethod(receiver, name, argumentList, args, call);
}
- boolean callArgsVisited = false;
if (mn.isEmpty()) {
addNoMatchingMethodError(receiver, name, args, call);
} else {
mn = disambiguateMethods(mn, receiver, args, call);
- if (mn.size() == 1) {
+ if (mn.size() != 1) {
+ addAmbiguousErrorMessage(mn, name, args, call);
+ } else {
MethodNode directMethodCallCandidate = mn.get(0);
ClassNode returnType = getType(directMethodCallCandidate);
if (returnType.isUsingGenerics() && !returnType.isEnum()) {
- visitMethodCallArguments(receiver, argumentList, true, directMethodCallCandidate); callArgsVisited = true;
- ClassNode rt = inferReturnTypeGenerics(chosenReceiver.getType(), directMethodCallCandidate, argumentList);
+ closuresVisited = true; // now visit closure/lambda arguments with selected method
+ visitMethodCallArguments(receiver, argumentList, true, directMethodCallCandidate);
+
+ ClassNode rt = inferReturnTypeGenerics(receiver, directMethodCallCandidate, argumentList);
if (rt != null && implementsInterfaceOrIsSubclassOf(rt, returnType))
returnType = rt;
}
storeType(call, returnType);
storeTargetMethod(call, directMethodCallCandidate);
- } else {
- addAmbiguousErrorMessage(mn, name, args, call);
}
}
MethodNode target = call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
- if (!callArgsVisited) {
+ if (!closuresVisited) {
visitMethodCallArguments(receiver, argumentList, true, target);
}
if (target != null) { Parameter[] params = target.getParameters();
@@ -5053,7 +5040,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
if (!name.endsWith("init>")) { // also search for extension methods
- findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), receiver, name, args, methods);
+ methods.addAll(findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), receiver, name));
}
methods = filterMethodsByVisibility(methods, typeCheckingContext.getEnclosingClassNode());
List<MethodNode> chosen = chooseBestMethod(receiver, methods, args);