You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/12/11 10:44:35 UTC

[groovy] branch GROOVY_3_0_X updated (55858b1 -> 72dcff2)

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a change to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git.


    from 55858b1  Agree with the TOS of build scan
     new a0c7d82  make backing field synthetic
     new 1889669  minor edits
     new a5a8d51  GROOVY-8562: copy metadata instead of recalling checkOrMarkPrivateAccess
     new 867ac0c  Avoid building cancelled unexpectedly
     new 22dd2bf  Add one more test for lambda
     new 72dcff2  Add `serialVersionUID` field only for serializable lambda

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/workflows/gradle.yml                       |   2 +
 .../classgen/asm/sc/StaticTypesLambdaWriter.java   |   4 +-
 .../groovy/transform/LazyASTTransformation.java    |   2 +-
 .../transform/sc/StaticCompilationVisitor.java     | 269 +++++++++++----------
 .../transform/stc/StaticTypeCheckingVisitor.java   | 234 ++++++++----------
 src/test/groovy/transform/stc/LambdaTest.groovy    |  20 ++
 6 files changed, 264 insertions(+), 267 deletions(-)


[groovy] 02/06: minor edits

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 1889669d1d802ab725fbc29e12be9bfbe4541797
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Dec 10 11:14:30 2019 -0600

    minor edits
    
    (cherry picked from commit 14cf5a700c642ea1f1a67333f7112b580da61fe3)
---
 .../transform/sc/StaticCompilationVisitor.java     | 269 +++++++++++----------
 1 file changed, 135 insertions(+), 134 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
index f78f1c3..a331a58 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
@@ -61,19 +61,19 @@ import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
 import org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor;
-import org.codehaus.groovy.transform.stc.StaticTypesMarker;
-import org.objectweb.asm.Opcodes;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import static org.codehaus.groovy.ast.ClassHelper.Character_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.LIST_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.int_TYPE;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.applyGenericsContextToPlaceHolders;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
@@ -81,11 +81,19 @@ import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.extractSuperClassGenerics;
 import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.BINARY_EXP_TARGET;
 import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.COMPONENT_TYPE;
+import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.DYNAMIC_OUTER_NODE_CALLBACK;
 import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PRIVATE_BRIDGE_METHODS;
 import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PRIVATE_FIELDS_ACCESSORS;
 import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PRIVATE_FIELDS_MUTATORS;
+import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PROPERTY_OWNER;
+import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.RECEIVER_OF_DYNAMIC_PROPERTY;
 import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.STATIC_COMPILE_NODE;
 import static org.codehaus.groovy.transform.stc.StaticTypesMarker.DIRECT_METHOD_CALL_TARGET;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.DYNAMIC_RESOLUTION;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.INITIAL_EXPRESSION;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.PV_FIELDS_ACCESS;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.PV_FIELDS_MUTATION;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.PV_METHODS_ACCESS;
 import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
 import static org.objectweb.asm.Opcodes.ACC_STATIC;
 import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
@@ -100,16 +108,14 @@ import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
  * visitor.
  */
 public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
-    private static final ClassNode TYPECHECKED_CLASSNODE = ClassHelper.make(TypeChecked.class);
-    private static final ClassNode COMPILESTATIC_CLASSNODE = ClassHelper.make(CompileStatic.class);
-    private static final ClassNode[] TYPECHECKED_ANNOTATIONS = {TYPECHECKED_CLASSNODE, COMPILESTATIC_CLASSNODE};
 
-    public static final ClassNode ARRAYLIST_CLASSNODE = ClassHelper.make(ArrayList.class);
-    public static final MethodNode ARRAYLIST_CONSTRUCTOR;
-    public static final MethodNode ARRAYLIST_ADD_METHOD = ARRAYLIST_CLASSNODE.getMethod("add", new Parameter[]{new Parameter(ClassHelper.OBJECT_TYPE, "o")});
+    public static final ClassNode TYPECHECKED_CLASSNODE = ClassHelper.make(TypeChecked.class);
+    public static final ClassNode COMPILESTATIC_CLASSNODE = ClassHelper.make(CompileStatic.class);
 
+    public static final ClassNode  ARRAYLIST_CLASSNODE = ClassHelper.make(ArrayList.class);
+    public static final MethodNode ARRAYLIST_ADD_METHOD = ARRAYLIST_CLASSNODE.getMethod("add", new Parameter[]{new Parameter(OBJECT_TYPE, "o")});
+    public static final MethodNode ARRAYLIST_CONSTRUCTOR = new ConstructorNode(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, EmptyStatement.INSTANCE);
     static {
-        ARRAYLIST_CONSTRUCTOR = new ConstructorNode(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, EmptyStatement.INSTANCE);
         ARRAYLIST_CONSTRUCTOR.setDeclaringClass(StaticCompilationVisitor.ARRAYLIST_CLASSNODE);
     }
 
@@ -123,33 +129,33 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
 
     @Override
     protected ClassNode[] getTypeCheckingAnnotations() {
-        return TYPECHECKED_ANNOTATIONS;
+        return new ClassNode[]{TYPECHECKED_CLASSNODE, COMPILESTATIC_CLASSNODE};
     }
 
-    public static boolean isStaticallyCompiled(AnnotatedNode node) {
-        if (node.getNodeMetaData(STATIC_COMPILE_NODE)!=null) return (Boolean)node.getNodeMetaData(STATIC_COMPILE_NODE);
+    public static boolean isStaticallyCompiled(final AnnotatedNode node) {
+        if (node.getNodeMetaData(STATIC_COMPILE_NODE) != null) {
+            return (Boolean) node.getNodeMetaData(STATIC_COMPILE_NODE);
+        }
         if (node instanceof MethodNode) {
             return isStaticallyCompiled(node.getDeclaringClass());
         }
-        if (node instanceof InnerClassNode) {
-            return isStaticallyCompiled(((InnerClassNode)node).getOuterClass());
+        if (node instanceof ClassNode && ((ClassNode) node).getOuterClass() != null) {
+            return isStaticallyCompiled(((ClassNode) node).getOuterClass());
         }
         return false;
     }
 
-    private void addPrivateFieldAndMethodAccessors(ClassNode node) {
+    private void addPrivateFieldAndMethodAccessors(final ClassNode node) {
         addPrivateBridgeMethods(node);
         addPrivateFieldsAccessors(node);
-        Iterator<InnerClassNode> it = node.getInnerClasses();
-        while (it.hasNext()) {
+        for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
             addPrivateFieldAndMethodAccessors(it.next());
         }
     }
 
     private void addDynamicOuterClassAccessorsCallback(final ClassNode outer) {
-        if (outer != null && !isStaticallyCompiled(outer)
-                && outer.getNodeMetaData(StaticCompilationMetadataKeys.DYNAMIC_OUTER_NODE_CALLBACK) == null) {
-            outer.putNodeMetaData(StaticCompilationMetadataKeys.DYNAMIC_OUTER_NODE_CALLBACK, new CompilationUnit.PrimaryClassNodeOperation() {
+        if (outer != null && !isStaticallyCompiled(outer) && outer.getNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK) == null) {
+            outer.putNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK, new CompilationUnit.PrimaryClassNodeOperation() {
                 @Override
                 public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
                     if (classNode == outer) {
@@ -167,13 +173,13 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
         if (!skip && !anyMethodSkip(node)) {
             node.putNodeMetaData(MopWriter.Factory.class, StaticCompilationMopWriter.FACTORY);
         }
-        ClassNode oldCN = classNode;
-        classNode = node;
-        Iterator<InnerClassNode> innerClasses = classNode.getInnerClasses();
-        while (innerClasses.hasNext()) {
+
+        ClassNode previousClassNode = classNode; classNode = node;
+
+        for (Iterator<InnerClassNode> innerClasses = classNode.getInnerClasses(); innerClasses.hasNext(); ) {
             InnerClassNode innerClassNode = innerClasses.next();
             boolean innerStaticCompile = !(skip || isSkippedInnerClass(innerClassNode));
-            innerClassNode.putNodeMetaData(STATIC_COMPILE_NODE, innerStaticCompile);
+            innerClassNode.putNodeMetaData(STATIC_COMPILE_NODE, Boolean.valueOf(innerStaticCompile));
             innerClassNode.putNodeMetaData(WriterControllerFactory.class, node.getNodeMetaData(WriterControllerFactory.class));
             if (innerStaticCompile && !anyMethodSkip(innerClassNode)) {
                 innerClassNode.putNodeMetaData(MopWriter.Factory.class, StaticCompilationMopWriter.FACTORY);
@@ -182,7 +188,8 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
         super.visitClass(node);
         addPrivateFieldAndMethodAccessors(node);
         if (isStaticallyCompiled(node)) addDynamicOuterClassAccessorsCallback(node.getOuterClass());
-        classNode = oldCN;
+
+        classNode = previousClassNode;
     }
 
     private boolean anyMethodSkip(final ClassNode node) {
@@ -199,17 +206,13 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
      * a purely static constructor, so it may fail if it encounters dynamic
      * code here. Thus we make this kind of code fail
      */
-    private void checkForConstructorWithCSButClassWithout(MethodNode node) {
+    private void checkForConstructorWithCSButClassWithout(final MethodNode node) {
         if (!(node instanceof ConstructorNode)) return;
-        Object meta = node.getNodeMetaData(STATIC_COMPILE_NODE);
-        if (!Boolean.TRUE.equals(meta)) return;
-        ClassNode clz = typeCheckingContext.getEnclosingClassNode();
-        meta = clz.getNodeMetaData(STATIC_COMPILE_NODE);
-        if (Boolean.TRUE.equals(meta)) return;
-        if (    clz.getObjectInitializerStatements().isEmpty() &&
-                clz.getFields().isEmpty() &&
-                clz.getProperties().isEmpty())
-        {
+        if (!Boolean.TRUE.equals(node.getNodeMetaData(STATIC_COMPILE_NODE))) return;
+        ClassNode outerClass = typeCheckingContext.getEnclosingClassNode();
+        if (Boolean.TRUE.equals(outerClass.getNodeMetaData(STATIC_COMPILE_NODE))) return;
+        if (outerClass.getObjectInitializerStatements().isEmpty()
+                && outerClass.getFields().isEmpty() && outerClass.getProperties().isEmpty()) {
             return;
         }
 
@@ -219,7 +222,7 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
     @Override
     public void visitMethod(final MethodNode node) {
         if (isSkipMode(node)) {
-            node.putNodeMetaData(STATIC_COMPILE_NODE, false);
+            node.putNodeMetaData(STATIC_COMPILE_NODE, Boolean.FALSE);
         }
         super.visitMethod(node);
         checkForConstructorWithCSButClassWithout(node);
@@ -227,99 +230,95 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
     }
 
     /**
-     * Adds special accessors and mutators for private fields so that inner classes can get/set them
+     * Adds special accessors and mutators for private fields so that inner classes can get/set them.
      */
-    @SuppressWarnings("unchecked")
-    private static void addPrivateFieldsAccessors(ClassNode node) {
-        Set<ASTNode> accessedFields = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
-        Set<ASTNode> mutatedFields = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_MUTATION);
+    private static void addPrivateFieldsAccessors(final ClassNode node) {
+        Set<ASTNode> accessedFields = node.getNodeMetaData(PV_FIELDS_ACCESS);
+        Set<ASTNode> mutatedFields = node.getNodeMetaData(PV_FIELDS_MUTATION);
         if (accessedFields == null && mutatedFields == null) return;
-        Map<String, MethodNode> privateFieldAccessors = (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_ACCESSORS);
-        Map<String, MethodNode> privateFieldMutators = (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_MUTATORS);
+        Map<String, MethodNode> privateFieldAccessors = node.getNodeMetaData(PRIVATE_FIELDS_ACCESSORS);
+        Map<String, MethodNode> privateFieldMutators = node.getNodeMetaData(PRIVATE_FIELDS_MUTATORS);
         if (privateFieldAccessors != null || privateFieldMutators != null) {
             // already added
             return;
         }
         int acc = -1;
-        privateFieldAccessors = accessedFields != null ? new HashMap<String, MethodNode>() : null;
-        privateFieldMutators = mutatedFields != null ? new HashMap<String, MethodNode>() : null;
-        final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
+        privateFieldAccessors = accessedFields != null ? new HashMap<>() : null;
+        privateFieldMutators = mutatedFields != null ? new HashMap<>() : null;
+        final int access = ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC;
         for (FieldNode fieldNode : node.getFields()) {
             boolean generateAccessor = accessedFields != null && accessedFields.contains(fieldNode);
             boolean generateMutator = mutatedFields != null && mutatedFields.contains(fieldNode);
             if (generateAccessor) {
-                acc++;
+                acc += 1;
                 Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
                 Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
-                Statement stmt = new ExpressionStatement(new PropertyExpression(
-                        receiver,
-                        fieldNode.getName()
-                ));
+                Statement stmt = new ExpressionStatement(new PropertyExpression(receiver, fieldNode.getName()));
                 MethodNode accessor = node.addMethod("pfaccess$" + acc, access, fieldNode.getOriginType(), new Parameter[]{param}, ClassNode.EMPTY_ARRAY, stmt);
                 privateFieldAccessors.put(fieldNode.getName(), accessor);
             }
 
             if (generateMutator) {
-                //increment acc if it hasn't been incremented in the current iteration
-                if (!generateAccessor) acc++;
+                // increment acc if it hasn't been incremented in the current iteration
+                if (!generateAccessor) acc += 1;
                 Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
                 Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
                 Parameter value = new Parameter(fieldNode.getOriginType(), "$value");
-                Statement stmt = GeneralUtils.assignS(
-                        new PropertyExpression(receiver, fieldNode.getName()),
-                        new VariableExpression(value)
-                );
+                Statement stmt = GeneralUtils.assignS(new PropertyExpression(receiver, fieldNode.getName()), new VariableExpression(value));
                 MethodNode mutator = node.addMethod("pfaccess$0" + acc, access, fieldNode.getOriginType(), new Parameter[]{param, value}, ClassNode.EMPTY_ARRAY, stmt);
                 privateFieldMutators.put(fieldNode.getName(), mutator);
             }
         }
-        if (privateFieldAccessors != null) node.setNodeMetaData(PRIVATE_FIELDS_ACCESSORS, privateFieldAccessors);
-        if (privateFieldMutators != null) node.setNodeMetaData(PRIVATE_FIELDS_MUTATORS, privateFieldMutators);
+        if (privateFieldAccessors != null) {
+            node.setNodeMetaData(PRIVATE_FIELDS_ACCESSORS, privateFieldAccessors);
+        }
+        if (privateFieldMutators != null) {
+            node.setNodeMetaData(PRIVATE_FIELDS_MUTATORS, privateFieldMutators);
+        }
     }
 
     /**
-     * This method is used to add "bridge" methods for private methods of an inner/outer
-     * class, so that the outer class is capable of calling them. It does basically
-     * the same job as access$000 like methods in Java.
+     * Adds "bridge" methods for private methods of an inner/outer class so that
+     * the outer class is capable of calling them.  It does basically the same
+     * job as access$000 like methods in Java.
      *
      * @param node an inner/outer class node for which to generate bridge methods
      */
-    @SuppressWarnings("unchecked")
     private static void addPrivateBridgeMethods(final ClassNode node) {
-        Set<ASTNode> accessedMethods = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS);
-        if (accessedMethods==null) return;
-        List<MethodNode> methods = new ArrayList<MethodNode>(node.getAllDeclaredMethods());
+        Set<ASTNode> accessedMethods = node.getNodeMetaData(PV_METHODS_ACCESS);
+        if (accessedMethods == null) return;
+        List<MethodNode> methods = new ArrayList<>(node.getAllDeclaredMethods());
         methods.addAll(node.getDeclaredConstructors());
-        Map<MethodNode, MethodNode> privateBridgeMethods = (Map<MethodNode, MethodNode>) node.getNodeMetaData(PRIVATE_BRIDGE_METHODS);
-        if (privateBridgeMethods!=null) {
+        Map<MethodNode, MethodNode> privateBridgeMethods = node.getNodeMetaData(PRIVATE_BRIDGE_METHODS);
+        if (privateBridgeMethods != null) {
             // private bridge methods already added
             return;
         }
-        privateBridgeMethods = new HashMap<MethodNode, MethodNode>();
-        int i=-1;
-        final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
+        privateBridgeMethods = new HashMap<>();
+        int i = -1;
+        final int access = ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC;
         for (MethodNode method : methods) {
             if (accessedMethods.contains(method)) {
                 List<String> methodSpecificGenerics = methodSpecificGenerics(method);
-                i++;
+                i += 1;
                 ClassNode declaringClass = method.getDeclaringClass();
-                Map<String,ClassNode> genericsSpec = createGenericsSpec(node);
+                Map<String, ClassNode> genericsSpec = createGenericsSpec(node);
                 genericsSpec = addMethodGenerics(method, genericsSpec);
                 extractSuperClassGenerics(node, declaringClass, genericsSpec);
                 Parameter[] methodParameters = method.getParameters();
-                Parameter[] newParams = new Parameter[methodParameters.length+1];
-                for (int j = 1; j < newParams.length; j++) {
-                    Parameter orig = methodParameters[j-1];
+                Parameter[] newParams = new Parameter[methodParameters.length + 1];
+                for (int j = 1; j < newParams.length; j += 1) {
+                    Parameter orig = methodParameters[j - 1];
                     newParams[j] = new Parameter(
                             correctToGenericsSpecRecurse(genericsSpec, orig.getOriginType(), methodSpecificGenerics),
                             orig.getName()
                     );
                 }
                 Expression arguments;
-                if (method.getParameters()==null || method.getParameters().length==0) {
+                if (method.getParameters() == null || method.getParameters().length == 0) {
                     arguments = ArgumentListExpression.EMPTY_ARGUMENTS;
                 } else {
-                    List<Expression> args = new LinkedList<Expression>();
+                    List<Expression> args = new ArrayList<>();
                     for (Parameter parameter : methodParameters) {
                         args.add(new VariableExpression(parameter));
                     }
@@ -334,7 +333,7 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                     if (innerClasses.hasNext()) {
                         thatType = innerClasses.next();
                     } else {
-                        thatType = new InnerClassNode(node.redirect(), node.getName() + "$1", ACC_STATIC | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE);
+                        thatType = new InnerClassNode(node.redirect(), node.getName() + "$1", ACC_STATIC | ACC_SYNTHETIC, OBJECT_TYPE);
                         node.getModule().addClass(thatType);
                     }
                     newParams[0] = new Parameter(thatType.getPlainNodeReference(), "$that");
@@ -343,21 +342,21 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                     bridge = node.addConstructor(ACC_SYNTHETIC, newParams, ClassNode.EMPTY_ARRAY, body);
                 } else {
                     newParams[0] = new Parameter(node.getPlainNodeReference(), "$that");
-                    Expression receiver = method.isStatic()?new ClassExpression(node):new VariableExpression(newParams[0]);
+                    Expression receiver = method.isStatic() ? new ClassExpression(node) : new VariableExpression(newParams[0]);
                     MethodCallExpression mce = new MethodCallExpression(receiver, method.getName(), arguments);
                     mce.setMethodTarget(method);
 
                     ExpressionStatement returnStatement = new ExpressionStatement(mce);
                     bridge = node.addMethod(
-                            "access$"+i, access,
+                            "access$" + i, access,
                             correctToGenericsSpecRecurse(genericsSpec, method.getReturnType(), methodSpecificGenerics),
                             newParams,
                             method.getExceptions(),
                             returnStatement);
                 }
                 GenericsType[] origGenericsTypes = method.getGenericsTypes();
-                if (origGenericsTypes !=null) {
-                    bridge.setGenericsTypes(applyGenericsContextToPlaceHolders(genericsSpec,origGenericsTypes));
+                if (origGenericsTypes != null) {
+                    bridge.setGenericsTypes(applyGenericsContextToPlaceHolders(genericsSpec, origGenericsTypes));
                 }
                 privateBridgeMethods.put(method, bridge);
                 bridge.addAnnotation(new AnnotationNode(COMPILESTATIC_CLASSNODE));
@@ -369,51 +368,46 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
     }
 
     private static List<String> methodSpecificGenerics(final MethodNode method) {
-        List<String> genericTypeTokens = new ArrayList<String>();
-        GenericsType[] candidateGenericsTypes = method.getGenericsTypes();
-        if (candidateGenericsTypes != null) {
-            for (GenericsType gt : candidateGenericsTypes) {
-                genericTypeTokens.add(gt.getName());
+        List<String> genericTypeNames = new ArrayList<>();
+        GenericsType[] genericsTypes = method.getGenericsTypes();
+        if (genericsTypes != null) {
+            for (GenericsType gt : genericsTypes) {
+                genericTypeNames.add(gt.getName());
             }
         }
-        return genericTypeTokens;
+        return genericTypeNames;
     }
 
     private static void memorizeInitialExpressions(final MethodNode node) {
         // add node metadata for default parameters because they are erased by the Verifier
-        if (node.getParameters()!=null) {
+        if (node.getParameters() != null) {
             for (Parameter parameter : node.getParameters()) {
-                parameter.putNodeMetaData(StaticTypesMarker.INITIAL_EXPRESSION, parameter.getInitialExpression());
+                parameter.putNodeMetaData(INITIAL_EXPRESSION, parameter.getInitialExpression());
             }
         }
     }
 
     @Override
-    public void visitSpreadExpression(final SpreadExpression expression) {
-    }
-
-    @Override
     public void visitMethodCallExpression(final MethodCallExpression call) {
         super.visitMethodCallExpression(call);
 
-        MethodNode target = (MethodNode) call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
-        if (target!=null) {
+        MethodNode target = call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
+        if (target != null) {
             call.setMethodTarget(target);
             memorizeInitialExpressions(target);
         }
 
-        if (call.getMethodTarget()==null && call.getLineNumber()>0) {
+        if (call.getMethodTarget() == null && call.getLineNumber() > 0) {
             addError("Target method for method call expression hasn't been set", call);
         }
-
     }
 
     @Override
     public void visitConstructorCallExpression(final ConstructorCallExpression call) {
         super.visitConstructorCallExpression(call);
 
-        MethodNode target = (MethodNode) call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
-        if (target==null && call.getLineNumber()>0) {
+        MethodNode target = call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
+        if (target == null && call.getLineNumber() > 0) {
             addError("Target constructor for constructor call expression hasn't been set", call);
         } else {
             if (target==null) {
@@ -421,7 +415,7 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                 ArgumentListExpression argumentListExpression = InvocationWriter.makeArgumentList(call.getArguments());
                 List<Expression> expressions = argumentListExpression.getExpressions();
                 ClassNode[] args = new ClassNode[expressions.size()];
-                for (int i = 0; i < args.length; i++) {
+                for (int i = 0, n = args.length; i < n; i += 1) {
                     args[i] = typeChooser.resolveType(expressions.get(i), classNode);
                 }
                 MethodNode constructor = findMethodOrFail(call, call.isSuperCall() ? classNode.getSuperClass() : classNode, "<init>", args);
@@ -429,18 +423,18 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                 target = constructor;
             }
         }
-        if (target!=null) {
+        if (target != null) {
             memorizeInitialExpressions(target);
         }
     }
 
     @Override
-    public void visitForLoop(final ForStatement forLoop) {
-        super.visitForLoop(forLoop);
-        Expression collectionExpression = forLoop.getCollectionExpression();
+    public void visitForLoop(final ForStatement statement) {
+        super.visitForLoop(statement);
+        Expression collectionExpression = statement.getCollectionExpression();
         if (!(collectionExpression instanceof ClosureListExpression)) {
-            final ClassNode collectionType = getType(forLoop.getCollectionExpression());
-            ClassNode forLoopVariableType = forLoop.getVariableType();
+            ClassNode forLoopVariableType = statement.getVariableType();
+            ClassNode collectionType = getType(collectionExpression);
             ClassNode componentType;
             if (Character_TYPE.equals(ClassHelper.getWrapper(forLoopVariableType)) && STRING_TYPE.equals(collectionType)) {
                 // we allow auto-coercion here
@@ -448,15 +442,15 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
             } else {
                 componentType = inferLoopElementType(collectionType);
             }
-            forLoop.getVariable().setType(componentType);
+            statement.getVariable().setType(componentType);
         }
     }
 
     @Override
     protected MethodNode findMethodOrFail(final Expression expr, final ClassNode receiver, final String name, final ClassNode... args) {
         MethodNode methodNode = super.findMethodOrFail(expr, receiver, name, args);
-        if (expr instanceof BinaryExpression && methodNode!=null) {
-            expr.putNodeMetaData(BINARY_EXP_TARGET, new Object[] {methodNode, name});
+        if (expr instanceof BinaryExpression && methodNode != null) {
+            expr.putNodeMetaData(BINARY_EXP_TARGET, new Object[]{methodNode, name});
         }
         return methodNode;
     }
@@ -465,18 +459,19 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
     protected boolean existsProperty(final PropertyExpression pexp, final boolean checkForReadOnly, final ClassCodeVisitorSupport visitor) {
         Expression objectExpression = pexp.getObjectExpression();
         ClassNode objectExpressionType = getType(objectExpression);
-        final Reference<ClassNode> rType = new Reference<ClassNode>(objectExpressionType);
+        Reference<ClassNode> rType = new Reference<>(objectExpressionType);
         ClassCodeVisitorSupport receiverMemoizer = new ClassCodeVisitorSupport() {
             @Override
             protected SourceUnit getSourceUnit() {
                 return null;
             }
 
+            @Override
             public void visitField(final FieldNode node) {
-                if (visitor!=null) visitor.visitField(node);
+                if (visitor != null) visitor.visitField(node);
                 ClassNode declaringClass = node.getDeclaringClass();
-                if (declaringClass!=null) {
-                    if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(declaringClass, ClassHelper.LIST_TYPE)) {
+                if (declaringClass != null) {
+                    if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(declaringClass, LIST_TYPE)) {
                         boolean spread = declaringClass.getDeclaredField(node.getName()) != node;
                         pexp.setSpreadSafe(spread);
                     }
@@ -484,15 +479,16 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                 }
             }
 
+            @Override
             public void visitMethod(final MethodNode node) {
-                if (visitor!=null) visitor.visitMethod(node);
+                if (visitor != null) visitor.visitMethod(node);
                 ClassNode declaringClass = node.getDeclaringClass();
-                if (declaringClass!=null){
-                    if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(declaringClass, ClassHelper.LIST_TYPE)) {
+                if (declaringClass != null) {
+                    if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(declaringClass, LIST_TYPE)) {
                         List<MethodNode> properties = declaringClass.getDeclaredMethods(node.getName());
                         boolean spread = true;
                         for (MethodNode mn : properties) {
-                            if (node==mn) {
+                            if (node == mn) {
                                 spread = false;
                                 break;
                             }
@@ -506,14 +502,14 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
 
             @Override
             public void visitProperty(final PropertyNode node) {
-                if (visitor!=null) visitor.visitProperty(node);
+                if (visitor != null) visitor.visitProperty(node);
                 ClassNode declaringClass = node.getDeclaringClass();
-                if (declaringClass!=null) {
-                    if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(declaringClass, ClassHelper.LIST_TYPE)) {
+                if (declaringClass != null) {
+                    if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(declaringClass, LIST_TYPE)) {
                         List<PropertyNode> properties = declaringClass.getProperties();
                         boolean spread = true;
                         for (PropertyNode propertyNode : properties) {
-                            if (propertyNode==node) {
+                            if (propertyNode == node) {
                                 spread = false;
                                 break;
                             }
@@ -525,24 +521,29 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                 }
             }
         };
+
         boolean exists = super.existsProperty(pexp, checkForReadOnly, receiverMemoizer);
         if (exists) {
-            if (objectExpression.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER)==null) {
-                objectExpression.putNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER, rType.get());
+            if (objectExpression.getNodeMetaData(PROPERTY_OWNER) == null) {
+                objectExpression.putNodeMetaData(PROPERTY_OWNER, rType.get());
             }
-            if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(objectExpressionType, ClassHelper.LIST_TYPE)) {
-                objectExpression.putNodeMetaData(COMPONENT_TYPE, inferComponentType(objectExpressionType, ClassHelper.int_TYPE));
+            if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(objectExpressionType, LIST_TYPE)) {
+                objectExpression.putNodeMetaData(COMPONENT_TYPE, inferComponentType(objectExpressionType, int_TYPE));
             }
         }
         return exists;
     }
 
     @Override
-    public void visitPropertyExpression(final PropertyExpression pexp) {
-        super.visitPropertyExpression(pexp);
-        Object dynamic = pexp.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION);
-        if (dynamic !=null) {
-            pexp.getObjectExpression().putNodeMetaData(StaticCompilationMetadataKeys.RECEIVER_OF_DYNAMIC_PROPERTY, dynamic);
+    public void visitPropertyExpression(final PropertyExpression expression) {
+        super.visitPropertyExpression(expression);
+        Object dynamic = expression.getNodeMetaData(DYNAMIC_RESOLUTION);
+        if (dynamic != null) {
+            expression.getObjectExpression().putNodeMetaData(RECEIVER_OF_DYNAMIC_PROPERTY, dynamic);
         }
     }
+
+    @Override
+    public void visitSpreadExpression(final SpreadExpression expression) {
+    }
 }


[groovy] 06/06: Add `serialVersionUID` field only for serializable lambda

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 72dcff2051e976ebe5cccf58faa262a8130c2732
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Dec 11 18:00:36 2019 +0800

    Add `serialVersionUID` field only for serializable lambda
    
    (cherry picked from commit 3113667be88ef15a53d4e724022bba3edf3481bb)
---
 .../org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
index a80c5c8..8f2fe0c 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
@@ -282,7 +282,9 @@ public class StaticTypesLambdaWriter extends LambdaWriter implements AbstractFun
         answer.setUsingGenerics(outerClass.isUsingGenerics());
         answer.setSourcePosition(expression);
 
-        addSerialVersionUIDField(answer);
+        if (expression.isSerializable()) {
+            addSerialVersionUIDField(answer);
+        }
 
         if (staticMethodOrInStaticClass) {
             answer.setStaticClass(true);


[groovy] 05/06: Add one more test for lambda

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 22dd2bf4683d7a6e4ea72e0b3f605b5e341756fd
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Dec 11 15:21:10 2019 +0800

    Add one more test for lambda
    
    (cherry picked from commit 51b3289dc7373b7bdf35d3c9e7fcbf0c990ca503)
---
 src/test/groovy/transform/stc/LambdaTest.groovy | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/test/groovy/transform/stc/LambdaTest.groovy b/src/test/groovy/transform/stc/LambdaTest.groovy
index 3cdb6a1..7d02748 100644
--- a/src/test/groovy/transform/stc/LambdaTest.groovy
+++ b/src/test/groovy/transform/stc/LambdaTest.groovy
@@ -929,6 +929,26 @@ class LambdaTest extends GroovyTestCase {
         '''
     }
 
+    void testNestedLambdaAccessingInstanceFields() {
+        assertScript '''
+            @groovy.transform.CompileStatic
+            class Test1 {
+                private List<String> strList = ['a', 'e', 'f']
+                private Map<String, List<String>> strListHolder = ['strList': strList]
+                private String b = 'b'
+                def p() {
+                    ['abc', 'def', 'ghi'].stream().filter(e -> strList.stream().anyMatch(c -> e.contains(c + b))).toList()
+                }
+                def p2() {
+                    ['abc', 'def', 'ghi'].stream().filter(e -> strListHolder.strList.stream().anyMatch(c -> e.contains(c + b))).toList()
+                }
+            }
+            
+            assert ['abc'] == new Test1().p()
+            assert ['abc'] == new Test1().p2()
+        '''
+    }
+
     void testSerialize() {
         assertScript '''
         import java.util.function.Function


[groovy] 03/06: GROOVY-8562: copy metadata instead of recalling checkOrMarkPrivateAccess

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit a5a8d510fd550a97aa40655c58697112e9804ae8
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Dec 10 17:10:59 2019 -0600

    GROOVY-8562: copy metadata instead of recalling checkOrMarkPrivateAccess
    
    refactor visitVariableExpression to check accessedVariable in one pass
    
    (cherry picked from commit 5e5bfd8ed2e5bc6ed64126ed10680653bd1f8b78)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 234 +++++++++------------
 1 file changed, 103 insertions(+), 131 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 cb5dd85..2a8dea3 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -109,7 +109,6 @@ import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.syntax.Token;
 import org.codehaus.groovy.syntax.TokenUtil;
 import org.codehaus.groovy.transform.StaticTypesTransformation;
-import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
 import org.codehaus.groovy.transform.trait.Traits;
 import org.codehaus.groovy.util.ListHashMap;
 import org.objectweb.asm.Opcodes;
@@ -558,114 +557,20 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         }
     }
 
-    private void checkSuperCallFromClosure(final Expression call, final MethodNode directCallTarget) {
-        if (call instanceof MethodCallExpression && typeCheckingContext.getEnclosingClosure() != null) {
-            Expression objectExpression = ((MethodCallExpression) call).getObjectExpression();
-            if (isSuperExpression(objectExpression)) {
-                ClassNode current = typeCheckingContext.getEnclosingClassNode();
-                current.getNodeMetaData(SUPER_MOP_METHOD_REQUIRED, x -> new LinkedList<>()).add(directCallTarget);
-                call.putNodeMetaData(SUPER_MOP_METHOD_REQUIRED, current);
-            }
-        }
-    }
-
-    /**
-     * Wrap type in Class&lt;&gt; if usingClass==true.
-     */
-    private static ClassNode makeType(final ClassNode cn, final boolean usingClass) {
-        if (usingClass) {
-            ClassNode clazzType = CLASS_Type.getPlainNodeReference();
-            clazzType.setGenericsTypes(new GenericsType[]{new GenericsType(cn)});
-            return clazzType;
-        } else {
-            return cn;
-        }
-    }
-
-    private boolean storeTypeForThis(final VariableExpression vexp) {
-        if (vexp == VariableExpression.THIS_EXPRESSION) return true;
-        if (!vexp.isThisExpression()) return false;
-        ClassNode enclosingClassNode = typeCheckingContext.getEnclosingClassNode();
-        storeType(vexp, makeType(enclosingClassNode, typeCheckingContext.isInStaticContext));
-        return true;
-    }
-
-    private boolean storeTypeForSuper(final VariableExpression vexp) {
-        if (vexp == VariableExpression.SUPER_EXPRESSION) return true;
-        if (!vexp.isSuperExpression()) return false;
-        ClassNode superClassNode = typeCheckingContext.getEnclosingClassNode().getSuperClass();
-        storeType(vexp, makeType(superClassNode, typeCheckingContext.isInStaticContext));
-        return true;
-    }
-
     @Override
     public void visitVariableExpression(final VariableExpression vexp) {
         super.visitVariableExpression(vexp);
-
-        if (storeTypeForThis(vexp)) return;
         if (storeTypeForSuper(vexp)) return;
-        Variable accessedVariable = vexp.getAccessedVariable();
-        if (accessedVariable instanceof PropertyNode) {
-            // we must be careful, because the property node may be of a wrong type:
-            // if a class contains a getter and a setter of different types or
-            // overloaded setters, the type of the property node is arbitrary!
-            if (tryVariableExpressionAsProperty(vexp, vexp.getName())) {
-                BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
-                if (enclosingBinaryExpression != null) {
-                    Expression leftExpression = enclosingBinaryExpression.getLeftExpression();
-                    SetterInfo setterInfo = removeSetterInfo(leftExpression);
-                    if (setterInfo != null) {
-                        Expression rightExpression = enclosingBinaryExpression.getRightExpression();
-                        if (!ensureValidSetter(vexp, leftExpression, rightExpression, setterInfo)) {
-                            return;
-                        }
-                    }
-                }
-            }
-        } else if (accessedVariable instanceof FieldNode) {
-            FieldNode fieldNode = (FieldNode) accessedVariable;
-
-            TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
-            if (enclosingClosure != null) {
-                // GROOVY-8562
-                // when vexp has the same name as a property of the owner,
-                // the IMPLICIT_RECEIVER must be set in case it's the delegate
-                if (tryVariableExpressionAsProperty(vexp, vexp.getName())) {
-                    // IMPLICIT_RECEIVER is handled elsewhere
-                    // however other access needs to be fixed for private access
-                    if (vexp.getNodeMetaData(IMPLICIT_RECEIVER) == null) {
-                        ClassNode owner = vexp.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER);
-                        if (owner != null) {
-                            FieldNode veFieldNode = owner.getField(vexp.getName());
-                            if (veFieldNode != null) {
-                                fieldNode = veFieldNode;
-                                boolean lhsOfEnclosingAssignment = isLHSOfEnclosingAssignment(vexp);
-                                vexp.setAccessedVariable(fieldNode);
-                                checkOrMarkPrivateAccess(vexp, fieldNode, lhsOfEnclosingAssignment);
-                            }
-                        }
-                    }
-                }
-            }
-
-            ClassNode actualType = findActualTypeByGenericsPlaceholderName(
-                    fieldNode.getOriginType().getUnresolvedName(),
-                    makeDeclaringAndActualGenericsTypeMap(fieldNode.getDeclaringClass(), typeCheckingContext.getEnclosingClassNode())
-            );
-
-            if (actualType != null) {
-                storeType(vexp, actualType);
-                return;
-            }
-        }
+        if (storeTypeForThis(vexp)) return;
+        String name = vexp.getName();
 
         TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
         if (enclosingClosure != null) {
-            switch (vexp.getName()) {
+            switch (name) {
                 case "delegate":
-                    DelegationMetadata md = getDelegationMetadata(enclosingClosure.getClosureExpression());
-                    if (md != null) {
-                        storeType(vexp, md.getType());
+                    DelegationMetadata dm = getDelegationMetadata(enclosingClosure.getClosureExpression());
+                    if (dm != null) {
+                        storeType(vexp, dm.getType());
                         return;
                     }
                     // falls through
@@ -681,49 +586,92 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             }
         }
 
+        Variable accessedVariable = vexp.getAccessedVariable();
+        VariableExpression localVariableExpression = null;
         if (accessedVariable instanceof DynamicVariable) {
-            // a dynamic variable is either an undeclared variable
-            // or a member of a class used in a 'with'
-            DynamicVariable dyn = (DynamicVariable) accessedVariable;
-            // first, we must check the 'with' context
-            String dynName = dyn.getName();
-            if (tryVariableExpressionAsProperty(vexp, dynName)) return;
+            // a dynamic variable is either a class member used in a 'with' or an undeclared variable
+
+            if (tryVariableExpressionAsProperty(vexp, name)) return;
 
             if (!extension.handleUnresolvedVariableExpression(vexp)) {
-                addStaticTypeError("The variable [" + vexp.getName() + "] is undeclared.", vexp);
+                addStaticTypeError("The variable [" + name + "] is undeclared.", vexp);
             }
-        } else if (enclosingClosure == null) {
-            VariableExpression variable = null;
-            if (accessedVariable instanceof Parameter) {
-                variable = new ParameterVariableExpression((Parameter) accessedVariable);
-            } else if (accessedVariable instanceof VariableExpression) {
-                variable = (VariableExpression) accessedVariable;
-            }
-            if (variable != null) {
-                ClassNode inferredType = getInferredTypeFromTempInfo(variable, variable.getNodeMetaData(INFERRED_TYPE));
-                // instanceof applies, stash away the type, reusing key used elsewhere
-                if (inferredType != null && !inferredType.equals(OBJECT_TYPE)) {
-                    vexp.putNodeMetaData(INFERRED_RETURN_TYPE, inferredType);
+        } else if (accessedVariable instanceof FieldNode) {
+            if (enclosingClosure != null) {
+                tryVariableExpressionAsProperty(vexp, name);
+            } else {
+                // GROOVY-7691
+                FieldNode fieldNode = (FieldNode) accessedVariable;
+                ClassNode actualType = findActualTypeByGenericsPlaceholderName(
+                        fieldNode.getOriginType().getUnresolvedName(),
+                        makeDeclaringAndActualGenericsTypeMap(fieldNode.getDeclaringClass(), typeCheckingContext.getEnclosingClassNode())
+                );
+                if (actualType != null) {
+                    storeType(vexp, actualType);
+                }
+            }
+        } else if (accessedVariable instanceof PropertyNode) {
+            // we must be careful, because the property node may be of a wrong type:
+            // if a class contains a getter and a setter of different types or
+            // overloaded setters, the type of the property node is arbitrary!
+            if (tryVariableExpressionAsProperty(vexp, name)) {
+                BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
+                if (enclosingBinaryExpression != null) {
+                    Expression leftExpression = enclosingBinaryExpression.getLeftExpression();
+                    SetterInfo setterInfo = removeSetterInfo(leftExpression);
+                    if (setterInfo != null) {
+                        Expression rightExpression = enclosingBinaryExpression.getRightExpression();
+                        if (!ensureValidSetter(vexp, leftExpression, rightExpression, setterInfo)) {
+                            return;
+                        }
+                    }
                 }
             }
+        } else if (accessedVariable instanceof Parameter) {
+            if (enclosingClosure == null) {
+                localVariableExpression = new ParameterVariableExpression((Parameter) accessedVariable);
+            }
+        } else if (accessedVariable instanceof VariableExpression) {
+            if (enclosingClosure == null) {
+                localVariableExpression = (VariableExpression) accessedVariable;
+            }
+        }
+
+        if (localVariableExpression != null) {
+            ClassNode inferredType = localVariableExpression.getNodeMetaData(INFERRED_TYPE);
+            inferredType = getInferredTypeFromTempInfo(localVariableExpression, inferredType);
+            if (inferredType != null && !inferredType.equals(OBJECT_TYPE)) {
+                vexp.putNodeMetaData(INFERRED_RETURN_TYPE, inferredType);
+            }
         }
     }
 
+    private boolean storeTypeForSuper(final VariableExpression vexp) {
+        if (vexp == VariableExpression.SUPER_EXPRESSION) return true;
+        if (!vexp.isSuperExpression()) return false;
+        ClassNode superClassNode = typeCheckingContext.getEnclosingClassNode().getSuperClass();
+        storeType(vexp, makeType(superClassNode, typeCheckingContext.isInStaticContext));
+        return true;
+    }
+
+    private boolean storeTypeForThis(final VariableExpression vexp) {
+        if (vexp == VariableExpression.THIS_EXPRESSION) return true;
+        if (!vexp.isThisExpression()) return false;
+        ClassNode enclosingClassNode = typeCheckingContext.getEnclosingClassNode();
+        storeType(vexp, makeType(enclosingClassNode, typeCheckingContext.isInStaticContext));
+        return true;
+    }
+
     private boolean tryVariableExpressionAsProperty(final VariableExpression vexp, final String dynName) {
         PropertyExpression pexp = thisPropX(true, dynName);
         if (visitPropertyExpressionSilent(pexp, vexp)) {
-            ClassNode propertyType = getType(pexp);
-            pexp.removeNodeMetaData(INFERRED_TYPE);
-
             vexp.copyNodeMetaData(pexp.getObjectExpression());
-            Object val = pexp.getNodeMetaData(READONLY_PROPERTY);
-            if (val != null) vexp.putNodeMetaData(READONLY_PROPERTY, val);
-            val = pexp.getNodeMetaData(IMPLICIT_RECEIVER);
-            if (val != null) vexp.putNodeMetaData(IMPLICIT_RECEIVER, val);
-            val = pexp.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
-            if (val != null) vexp.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, val);
-
-            storeType(vexp, propertyType);
+            for (Object key : new Object[]{IMPLICIT_RECEIVER, READONLY_PROPERTY, PV_FIELDS_ACCESS, PV_FIELDS_MUTATION, DECLARATION_INFERRED_TYPE, DIRECT_METHOD_CALL_TARGET}) {
+                Object val = pexp.getNodeMetaData(key);
+                if (val != null) vexp.putNodeMetaData(key, val);
+            }
+            vexp.removeNodeMetaData(INFERRED_TYPE);
+            storeType(vexp, getType(pexp));
             return true;
         }
         return false;
@@ -3752,6 +3700,17 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         extension.onMethodSelection(call, directMethodCallCandidate);
     }
 
+    private void checkSuperCallFromClosure(final Expression call, final MethodNode directCallTarget) {
+        if (call instanceof MethodCallExpression && typeCheckingContext.getEnclosingClosure() != null) {
+            Expression objectExpression = ((MethodCallExpression) call).getObjectExpression();
+            if (isSuperExpression(objectExpression)) {
+                ClassNode current = typeCheckingContext.getEnclosingClassNode();
+                current.getNodeMetaData(SUPER_MOP_METHOD_REQUIRED, x -> new LinkedList<>()).add(directCallTarget);
+                call.putNodeMetaData(SUPER_MOP_METHOD_REQUIRED, current);
+            }
+        }
+    }
+
     protected boolean isClosureCall(final String name, final Expression objectExpression, final Expression arguments) {
         if (objectExpression instanceof ClosureExpression && ("call".equals(name) || "doCall".equals(name))) return true;
         if (isThisExpression(objectExpression)) {
@@ -4937,6 +4896,19 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
     }
 
     /**
+     * Wrap type in Class&lt;&gt; if usingClass==true.
+     */
+    private static ClassNode makeType(final ClassNode cn, final boolean usingClass) {
+        if (usingClass) {
+            ClassNode clazzType = CLASS_Type.getPlainNodeReference();
+            clazzType.setGenericsTypes(new GenericsType[]{new GenericsType(cn)});
+            return clazzType;
+        } else {
+            return cn;
+        }
+    }
+
+    /**
      * Stores the inferred return type of a closure or a method. We are using a separate key to store
      * inferred return type because the inferred type of a closure is {@link Closure}, which is different
      * from the inferred type of the code of the closure.


[groovy] 01/06: make backing field synthetic

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit a0c7d82b37f1ec3571c3fdf539b0ea42c3f1484a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Dec 10 10:09:26 2019 -0600

    make backing field synthetic
    
    (cherry picked from commit a61180d86caefc5ae666a59e887d05b2884a67f7)
---
 src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
index 47ae674..58fd226 100644
--- a/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
@@ -87,7 +87,7 @@ public class LazyASTTransformation extends AbstractASTTransformation {
 
         String backingFieldName = "$" + fieldNode.getName();
         fieldNode.rename(backingFieldName);
-        fieldNode.setModifiers(ACC_PRIVATE | (fieldNode.getModifiers() & (~(ACC_PUBLIC | ACC_PROTECTED))));
+        fieldNode.setModifiers(ACC_PRIVATE | ACC_SYNTHETIC | (fieldNode.getModifiers() & (~(ACC_PUBLIC | ACC_PROTECTED))));
         PropertyNode pNode = fieldNode.getDeclaringClass().getProperty(backingFieldName);
         if (pNode != null) {
             fieldNode.getDeclaringClass().getProperties().remove(pNode);


[groovy] 04/06: Avoid building cancelled unexpectedly

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 867ac0cca1b38cbc80ca737fb5f7d26fe48a605e
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Dec 11 10:14:55 2019 +0800

    Avoid building cancelled unexpectedly
    
    (cherry picked from commit 34e2e9250ee61cd7e04a5463699fb5fd73a35cc4)
---
 .github/workflows/gradle.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 7b39d2e..58ea012 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -20,6 +20,7 @@ on: [push, pull_request]
 jobs:
   test:
     strategy:
+      fail-fast: false
       matrix:
         os: [ubuntu-18.04]
         java: [8.0.232, 11.0.5]
@@ -37,6 +38,7 @@ jobs:
           GRADLE_SCANS_ACCEPT: yes
   testWithIndy:
     strategy:
+      fail-fast: false
       matrix:
         os: [ubuntu-18.04]
         java: [8.0.232, 11.0.5]