groovy git commit: Minor refactoring to prepare supporting local variables

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

groovy git commit: Minor refactoring to prepare supporting local variables

Daniel.Sun
Repository: groovy
Updated Branches:
  refs/heads/native-lambda 61474c1ee -> b6ea72dbf


Minor refactoring to prepare supporting local variables


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/b6ea72db
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/b6ea72db
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/b6ea72db

Branch: refs/heads/native-lambda
Commit: b6ea72dbf2ee4ab63fb1b96569de609679807a34
Parents: 61474c1
Author: sunlan <[hidden email]>
Authored: Sun Jan 14 07:47:17 2018 +0800
Committer: sunlan <[hidden email]>
Committed: Sun Jan 14 07:47:17 2018 +0800

----------------------------------------------------------------------
 .../groovy/classgen/asm/LambdaWriter.java       |  5 ++
 .../asm/sc/StaticTypesLambdaWriter.java         | 29 +++++--
 .../groovy/runtime/ProxyGeneratorAdapter.java   |  2 +-
 src/test/gls/generics/GenericsTestBase.java     |  2 +-
 src/test/groovy/transform/stc/LambdaTest.groovy | 88 ++++++++++++++++++++
 5 files changed, 115 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b6ea72db/src/main/java/org/codehaus/groovy/classgen/asm/LambdaWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/LambdaWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/LambdaWriter.java
index 3a39688..6c0b53d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/LambdaWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/LambdaWriter.java
@@ -18,6 +18,7 @@
  */
 package org.codehaus.groovy.classgen.asm;
 
+import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.expr.LambdaExpression;
 
 public class LambdaWriter extends ClosureWriter {
@@ -28,4 +29,8 @@ public class LambdaWriter extends ClosureWriter {
     public void writeLambda(LambdaExpression expression) {
         super.writeClosure(expression);
     }
+
+    protected Parameter[] getLambdaSharedVariables(LambdaExpression expression) {
+        return super.getClosureSharedVariables(expression);
+    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/b6ea72db/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
----------------------------------------------------------------------
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 bdf10d8..e91e777 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
@@ -41,6 +41,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static org.codehaus.groovy.classgen.asm.sc.StaticInvocationWriter.PARAMETER_TYPE;
 import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
@@ -51,6 +52,8 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
  */
 public class StaticTypesLambdaWriter extends LambdaWriter {
     public static final String DO_CALL = "doCall";
+    public static final String ORIGINAL_PARAMETERS_WITH_EXACT_TYPE = "__ORIGINAL_PARAMETERS_WITH_EXACT_TYPE";
+    public static final String LAMBDA_SHARED_VARIABLES = "_LAMBDA_SHARED_VARIABLES";
     private StaticTypesClosureWriter staticTypesClosureWriter;
     private WriterController controller;
     private WriterControllerFactory factory;
@@ -87,19 +90,22 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
 
         ClassNode lambdaClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC);
         MethodNode syntheticLambdaMethodNode = lambdaClassNode.getMethods(DO_CALL).get(0);
-        String syntheticLambdaMethodWithExactTypeDesc = BytecodeHelper.getMethodDescriptor(syntheticLambdaMethodNode);
+
 
         controller.getOperandStack().push(parameterType.redirect());
         controller.getMethodVisitor().visitInvokeDynamicInsn(
                 abstractMethodNode.getName(),
-                createAbstractMethodDesc(parameterType),
+                createAbstractMethodDesc(syntheticLambdaMethodNode, parameterType),
                 createBootstrapMethod(),
-                createBootstrapMethodArguments(abstractMethodDesc, lambdaClassNode, syntheticLambdaMethodNode, syntheticLambdaMethodWithExactTypeDesc)
+                createBootstrapMethodArguments(abstractMethodDesc, lambdaClassNode, syntheticLambdaMethodNode)
         );
     }
 
-    private String createAbstractMethodDesc(ClassNode parameterType) {
-        return "()L" + parameterType.redirect().getPackageName().replace('.', '/') + "/" + parameterType.redirect().getNameWithoutPackage() + ";";
+    private String createAbstractMethodDesc(MethodNode syntheticLambdaMethodNode, ClassNode parameterType) {
+        Parameter[] lambdaSharedVariables = syntheticLambdaMethodNode.getNodeMetaData(LAMBDA_SHARED_VARIABLES);
+        String methodDescriptor = BytecodeHelper.getMethodDescriptor(parameterType.redirect(), lambdaSharedVariables);
+
+        return methodDescriptor;
     }
 
     private Handle createBootstrapMethod() {
@@ -112,17 +118,17 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         );
     }
 
-    private Object[] createBootstrapMethodArguments(String abstractMethodDesc, ClassNode lambdaClassNode, MethodNode syntheticLambdaMethodNode, String syntheticLambdaMethodWithExactTypeDesc) {
+    private Object[] createBootstrapMethodArguments(String abstractMethodDesc, ClassNode lambdaClassNode, MethodNode syntheticLambdaMethodNode) {
         return new Object[]{
                 Type.getType(abstractMethodDesc),
                 new Handle(
                         Opcodes.H_INVOKESTATIC,
                         lambdaClassNode.getName(),
                         syntheticLambdaMethodNode.getName(),
-                        syntheticLambdaMethodWithExactTypeDesc,
+                        BytecodeHelper.getMethodDescriptor(syntheticLambdaMethodNode),
                         false
                 ),
-                Type.getType(syntheticLambdaMethodWithExactTypeDesc)
+                Type.getType(BytecodeHelper.getMethodDescriptor(syntheticLambdaMethodNode.getReturnType(), syntheticLambdaMethodNode.getNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE)))
         };
     }
 
@@ -187,9 +193,14 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
     private void addSyntheticLambdaMethodNode(LambdaExpression expression, InnerClassNode answer) {
         Parameter[] parametersWithExactType = createParametersWithExactType(expression); // expression.getParameters();
         ClassNode returnType = expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE); //abstractMethodNode.getReturnType();
+        Parameter[] lambdaSharedVariables = getLambdaSharedVariables(expression);
+        Parameter[] methodParameter = Stream.concat(Arrays.stream(lambdaSharedVariables), Arrays.stream(parametersWithExactType)).toArray(Parameter[]::new);
 
         MethodNode methodNode =
-                answer.addMethod(DO_CALL, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, returnType, parametersWithExactType, ClassNode.EMPTY_ARRAY, expression.getCode());
+                answer.addMethod(DO_CALL, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, returnType, methodParameter, ClassNode.EMPTY_ARRAY, expression.getCode());
+        methodNode.putNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE, parametersWithExactType);
+        methodNode.putNodeMetaData(LAMBDA_SHARED_VARIABLES, lambdaSharedVariables);
+
         methodNode.setSourcePosition(expression);
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/b6ea72db/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java b/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java
index 207a7ca..0e1f6cc 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java
@@ -142,7 +142,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor implements Opcodes {
             final ClassLoader proxyLoader,
             final boolean emptyBody,
             final Class delegateClass) {
-        super(Opcodes.ASM4, new ClassWriter(0));
+        super(Opcodes.ASM5, new ClassWriter(0));
         this.loader = proxyLoader != null ? createInnerLoader(proxyLoader, interfaces) : findClassLoader(superClass, interfaces);
         this.visitedMethods = new LinkedHashSet<Object>();
         this.delegatedClosures = closureMap.isEmpty() ? EMPTY_DELEGATECLOSURE_MAP : new HashMap<String, Boolean>();

http://git-wip-us.apache.org/repos/asf/groovy/blob/b6ea72db/src/test/gls/generics/GenericsTestBase.java
----------------------------------------------------------------------
diff --git a/src/test/gls/generics/GenericsTestBase.java b/src/test/gls/generics/GenericsTestBase.java
index 801806f..dc5fc94 100644
--- a/src/test/gls/generics/GenericsTestBase.java
+++ b/src/test/gls/generics/GenericsTestBase.java
@@ -57,7 +57,7 @@ public abstract class GenericsTestBase extends GroovyTestCase {
     }
     private class GenericsTester extends ClassVisitor {
         public GenericsTester(ClassVisitor cv) {
-            super(Opcodes.ASM4,cv);
+            super(Opcodes.ASM5,cv);
         }
         public void visit(int version, int access, String name,
                 String signature, String superName, String[] interfaces) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/b6ea72db/src/test/groovy/transform/stc/LambdaTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/transform/stc/LambdaTest.groovy b/src/test/groovy/transform/stc/LambdaTest.groovy
index ba471fb..73ba540 100644
--- a/src/test/groovy/transform/stc/LambdaTest.groovy
+++ b/src/test/groovy/transform/stc/LambdaTest.groovy
@@ -194,4 +194,92 @@ TestScript0.groovy: 14: [Static type checking] - Cannot find matching method jav
         }
         '''
     }
+
+    void testFunctionWithLocalVariables() {
+        if (true) return
+
+        // FIXME
+        /*
+General error during class generation: ASM reporting processing error for Test1#p with signature void p() in TestScript0.groovy:12. TestScript0.groovy
+
+groovy.lang.GroovyRuntimeException: ASM reporting processing error for Test1#p with signature void p() in TestScript0.groovy:12. TestScript0.groovy
+ at org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorOrMethod(AsmClassGenerator.java:447)
+ at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:132)
+ at org.codehaus.groovy.classgen.AsmClassGenerator.visitMethod(AsmClassGenerator.java:568)
+ at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1095)
+ at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:54)
+ at org.codehaus.groovy.classgen.AsmClassGenerator.visitClass(AsmClassGenerator.java:261)
+ at org.codehaus.groovy.control.CompilationUnit$18.call(CompilationUnit.java:853)
+ at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1092)
+ at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:634)
+ at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:612)
+ at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:589)
+ at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:359)
+ at groovy.lang.GroovyClassLoader.access$300(GroovyClassLoader.java:92)
+ at groovy.lang.GroovyClassLoader$5.provide(GroovyClassLoader.java:328)
+ at groovy.lang.GroovyClassLoader$5.provide(GroovyClassLoader.java:325)
+ at org.codehaus.groovy.runtime.memoize.ConcurrentCommonCache.getAndPut(ConcurrentCommonCache.java:138)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:323)
+ at groovy.lang.GroovyShell.parseClass(GroovyShell.java:548)
+ at groovy.lang.GroovyShell.parse(GroovyShell.java:560)
+ at groovy.lang.GroovyShell.evaluate(GroovyShell.java:444)
+ at groovy.lang.GroovyShell.evaluate(GroovyShell.java:483)
+ at groovy.lang.GroovyShell.evaluate(GroovyShell.java:464)
+ at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:83)
+ at groovy.util.GroovyTestCase.assertScript(GroovyTestCase.java:203)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:498)
+ at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
+ at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
+ at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
+ at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
+ at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:169)
+ at groovy.transform.stc.LambdaTest.testFunctionWithLocalVariables(LambdaTest.groovy:203)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:498)
+ at junit.framework.TestCase.runTest(TestCase.java:176)
+ at junit.framework.TestCase.runBare(TestCase.java:141)
+ at junit.framework.TestResult$1.protect(TestResult.java:122)
+ at junit.framework.TestResult.runProtected(TestResult.java:142)
+ at junit.framework.TestResult.run(TestResult.java:125)
+ at junit.framework.TestCase.run(TestCase.java:129)
+ at junit.framework.TestSuite.runTest(TestSuite.java:252)
+ at junit.framework.TestSuite.run(TestSuite.java:247)
+ at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
+ at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
+ at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
+ at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
+ at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
+ at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
+Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
+ at org.objectweb.asm.Frame.merge(Frame.java:1501)
+ at org.objectweb.asm.Frame.merge(Frame.java:1478)
+ at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1497)
+ at org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorOrMethod(AsmClassGenerator.java:428)
+ ... 51 more
+
+         */
+
+        assertScript '''
+        import groovy.transform.CompileStatic
+        import java.util.stream.Collectors
+        import java.util.stream.Stream
+        
+        @CompileStatic
+        public class Test1 {
+            public static void main(String[] args) {
+                p();
+            }
+        
+            public static void p() {
+                String x = "#"
+                assert ['#1', '#2', '#3'] == Stream.of(1, 2, 3).map(e -> x + e).collect(Collectors.toList());
+            }
+        }
+        '''
+    }
 }