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/12/18 16:51:51 UTC

[groovy] branch master updated: minor refactor

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 d214c7bb5a minor refactor
d214c7bb5a is described below

commit d214c7bb5ab0b9449f474b57dfc85c5a547369d4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Dec 18 10:24:24 2022 -0600

    minor refactor
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 69 +++++++++++-----------
 1 file changed, 34 insertions(+), 35 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 ebdcb5639d..88f765dda5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1044,22 +1044,12 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         // but we must check if the binary expression is an assignment
         // because we need to check if a setter uses @DelegatesTo
         VariableExpression receiver = varX("%", setterInfo.receiverType);
-        // for "x op= y" expression, find type as if it was "x = x op y"
-        Expression valueExpression = rightExpression;
-        if (isCompoundAssignment(expression)) {
-            Token op = ((BinaryExpression) expression).getOperation();
-            if (op.getType() == ELVIS_EQUAL) { // GROOVY-10419: "x ?= y"
-                valueExpression = elvisX(leftExpression, rightExpression);
-            } else {
-                op = Token.newSymbol(TokenUtil.removeAssignment(op.getType()), op.getStartLine(), op.getStartColumn());
-                valueExpression = binX(leftExpression, op, rightExpression);
-            }
-        }
+        receiver.setType(setterInfo.receiverType); // same as origin type
 
-        Function<Expression, MethodNode> setterCall = right -> {
+        Function<Expression, MethodNode> setterCall = (value) -> {
             typeCheckingContext.pushEnclosingBinaryExpression(null); // GROOVY-10628: LHS re-purposed
             try {
-                MethodCallExpression call = new MethodCallExpression(receiver, setterInfo.name, right);
+                MethodCallExpression call = callX(receiver, setterInfo.name, value);
                 call.setImplicitThis(false);
                 visitMethodCallExpression(call);
                 return call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
@@ -1068,7 +1058,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             }
         };
 
-        Function<MethodNode, ClassNode> setterType = setter -> {
+        Function<MethodNode, ClassNode> setterType = (setter) -> {
             ClassNode type = setter.getParameters()[0].getOriginType();
             if (!setter.isStatic() && !(setter instanceof ExtensionMethodNode) && GenericsUtils.hasUnresolvedGenerics(type)) {
                 type = applyGenericsContext(extractPlaceHolders(setterInfo.receiverType, setter.getDeclaringClass()), type);
@@ -1076,6 +1066,18 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             return type;
         };
 
+        Expression valueExpression = rightExpression;
+        // for "x op= y", find type as if it was "x = x op y"
+        if (isCompoundAssignment(expression)) {
+            Token op = ((BinaryExpression) expression).getOperation();
+            if (op.getType() == ELVIS_EQUAL) { // GROOVY-10419: "x ?= y"
+                valueExpression = elvisX(leftExpression, rightExpression);
+            } else {
+                op = Token.newSymbol(TokenUtil.removeAssignment(op.getType()), op.getStartLine(), op.getStartColumn());
+                valueExpression = binX(leftExpression, op, rightExpression);
+            }
+        }
+
         MethodNode methodTarget = setterCall.apply(valueExpression);
         if (methodTarget == null && !isCompoundAssignment(expression)) {
             // if no direct match, try implicit conversion
@@ -2742,13 +2744,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             ClassNode[] args = getArgumentTypes(argumentList);
 
             List<MethodNode> mn = findMethod(type, 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(type, args, mn.get(0), call);
-                }
-            }
             if (mn.isEmpty()) {
                 mn = extension.handleMissingMethod(type, name, argumentList, args, call);
             }
@@ -2759,26 +2754,30 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 if (mn.size() != 1) {
                     addAmbiguousErrorMessage(mn, name, args, call);
                 } else {
-                    MethodNode directMethodCallCandidate = mn.get(0);
-                    ClassNode returnType = getType(directMethodCallCandidate);
+                    MethodNode targetMethod = mn.get(0);
+                    // GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
+                    resolvePlaceholdersFromImplicitTypeHints(args, argumentList, targetMethod.getParameters());
+                    typeCheckMethodsWithGenericsOrFail(type, args, targetMethod, call);
+
+                    ClassNode returnType = getType(targetMethod);
                     if (returnType.isUsingGenerics() && !returnType.isEnum()) {
                         closuresVisited = true; // visit closure/lambda arguments with selected method
-                        visitMethodCallArguments(type, argumentList, true, directMethodCallCandidate);
+                        visitMethodCallArguments(type, argumentList, true, targetMethod);
 
-                        ClassNode rt = inferReturnTypeGenerics(type, directMethodCallCandidate, argumentList);
+                        ClassNode rt = inferReturnTypeGenerics(type, targetMethod, argumentList);
                         if (rt != null && implementsInterfaceOrIsSubclassOf(rt, returnType))
                             returnType = rt;
                     }
                     storeType(call, returnType);
-                    storeTargetMethod(call, directMethodCallCandidate);
+                    storeTargetMethod(call, targetMethod);
                 }
             }
 
-            MethodNode target = call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
             if (!closuresVisited) {
-                visitMethodCallArguments(type, argumentList, true, target);
+                final MethodNode targetMethod = !mn.isEmpty() ? mn.get(0) : null;
+                visitMethodCallArguments(type, argumentList, true, targetMethod);
             }
-            if (target != null) { Parameter[] params = target.getParameters();
+            if (mn.size() == 1) { Parameter[] params = mn.get(0).getParameters();
                 checkClosureMetadata(argumentList.getExpressions(), params);
                 checkForbiddenSpreadArgument(argumentList, params);
             } else {
@@ -5394,25 +5393,25 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
 
     /**
      * Given method call like "m(Collections.emptyList())", the type of the call
-     * argument is {@code List<T>} without explicit type arguments. Knowing the
-     * method target of "m", {@code T} could be resolved.
+     * argument is {@code List<T>} without explicit type arguments. Now, knowing
+     * the method target of "m", {@code T} could be resolved.
      */
     private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals, final ArgumentListExpression argumentList, final Parameter[] parameterArray) {
         int np = parameterArray.length;
         for (int i = 0, n = actuals.length; np > 0 && i < n; i += 1) {
-            Expression a = argumentList.getExpression(i);
             Parameter p = parameterArray[Math.min(i, np - 1)];
-
-            ClassNode at = actuals[i], pt = p.getOriginType();
+            ClassNode pt = p.getOriginType(), at = actuals[i];
             if (!isUsingGenericsOrIsArrayUsingGenerics(pt)) continue;
             if (i >= (np - 1) && pt.isArray() && !at.isArray()) pt = pt.getComponentType();
 
+            var a = argumentList.getExpression(i);
+
             if (a instanceof ListExpression) {
                 actuals[i] = getLiteralResultType(pt, at, ArrayList_TYPE);
             } else if (a instanceof MapExpression) {
                 actuals[i] = getLiteralResultType(pt, at, LinkedHashMap_TYPE);
             } else if (a instanceof ConstructorCallExpression) {
-                inferDiamondType((ConstructorCallExpression) a, pt); // GROOVY-10086
+                inferDiamondType((ConstructorCallExpression) a, pt); // GROOVY-8974, GROOVY-9983, GROOVY-10086, et al.
             } else if (a instanceof TernaryExpression && at.getGenericsTypes() != null && at.getGenericsTypes().length == 0) {
                 // GROOVY-9983: double diamond scenario -- "m(flag ? new Type<>(...) : new Type<>(...))"
                 typeCheckingContext.pushEnclosingBinaryExpression(assignX(varX(p), a, a));