Repository: groovy
Updated Branches:
  refs/heads/native-lambda f02cf2123 -> 0b8beb93c


Fix types in the operand stack


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

Branch: refs/heads/native-lambda
Commit: 0b8beb93c60c2ea05bf6b1b4490cebffd2056e1a
Parents: f02cf21
Author: sunlan <[email protected]>
Authored: Mon Jan 29 12:51:21 2018 +0800
Committer: sunlan <[email protected]>
Committed: Mon Jan 29 12:51:21 2018 +0800

----------------------------------------------------------------------
 .../asm/sc/StaticTypesLambdaWriter.java         | 35 +++++++++-----------
 .../stc/StaticTypeCheckingVisitor.java          |  5 +++
 src/test/groovy/transform/stc/LambdaTest.groovy | 10 ++----
 3 files changed, 24 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/0b8beb93/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 008d798..7f44c90 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
@@ -113,10 +113,10 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
 
         ClassNode classNode = controller.getClassNode();
         boolean isInterface = classNode.isInterface();
-        ClassNode lambdaClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC 
| (isInterface ? ACC_STATIC : 0) | ACC_SYNTHETIC, abstractMethodNode);
-        MethodNode syntheticLambdaMethodNode = 
lambdaClassNode.getMethods(DO_CALL).get(0);
+        ClassNode lambdaWrapperClassNode = getOrAddLambdaClass(expression, 
ACC_PUBLIC | (isInterface ? ACC_STATIC : 0) | ACC_SYNTHETIC, 
abstractMethodNode);
+        MethodNode syntheticLambdaMethodNode = 
lambdaWrapperClassNode.getMethods(DO_CALL).get(0);
 
-        BytecodeVariable lambdaWrapperVariable = 
newGroovyLambdaWrapperAndLoad(lambdaClassNode, syntheticLambdaMethodNode);
+        BytecodeVariable lambdaWrapperVariable = 
newGroovyLambdaWrapperAndLoad(lambdaWrapperClassNode, 
syntheticLambdaMethodNode);
 
         loadEnclosingClassInstance();
 
@@ -126,11 +126,11 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
 
         mv.visitInvokeDynamicInsn(
                 abstractMethodNode.getName(),
-                createAbstractMethodDesc(lambdaType, lambdaClassNode),
+                createAbstractMethodDesc(lambdaType, lambdaWrapperClassNode),
                 createBootstrapMethod(isInterface),
-                createBootstrapMethodArguments(abstractMethodDesc, 
lambdaClassNode, syntheticLambdaMethodNode)
+                createBootstrapMethodArguments(abstractMethodDesc, 
lambdaWrapperClassNode, syntheticLambdaMethodNode)
         );
-        operandStack.replace(lambdaType.redirect(), 1);
+        operandStack.replace(lambdaType.redirect(), 2);
 
         if (null != expression.getNodeMetaData(INFERRED_LAMBDA_TYPE)) {
             // FIXME declaring variable whose initial value is a lambda, e.g. 
`Function<Integer, String> f = (Integer e) -> 'a' + e`
@@ -175,23 +175,20 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
         }
 
 
-        saveLambdaObjectInWrapper(lambdaType, lambdaWrapperVariable);
+        saveLambdaObjectInWrapper(lambdaWrapperVariable);
+        operandStack.replace(lambdaType.redirect(), 2);
     }
 
-    private void saveLambdaObjectInWrapper(ClassNode lambdaType, 
BytecodeVariable lambdaWrapperVariable) {
+    private void saveLambdaObjectInWrapper(BytecodeVariable 
lambdaWrapperVariable) {
         MethodVisitor mv = controller.getMethodVisitor();
         OperandStack operandStack = controller.getOperandStack();
 
         mv.visitInsn(DUP);
-        operandStack.push(lambdaType.redirect());
         operandStack.loadOrStoreVariable(lambdaWrapperVariable, false);
-        operandStack.push(ClassHelper.LAMBDA_TYPE);
         operandStack.swap();
 
         mv.visitMethodInsn(
                 INVOKEVIRTUAL, "groovy/lang/Lambda", "setLambdaObject", 
"(Ljava/lang/Object;)V", false);
-
-        operandStack.remove(1);
     }
 
     private ClassNode getLambdaType(LambdaExpression expression) {
@@ -216,10 +213,10 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
         }
     }
 
-    private BytecodeVariable newGroovyLambdaWrapperAndLoad(ClassNode 
lambdaClassNode, MethodNode syntheticLambdaMethodNode) {
+    private BytecodeVariable newGroovyLambdaWrapperAndLoad(ClassNode 
lambdaWrapperClassNode, MethodNode syntheticLambdaMethodNode) {
         MethodVisitor mv = controller.getMethodVisitor();
-        String lambdaClassInternalName = 
BytecodeHelper.getClassInternalName(lambdaClassNode);
-        mv.visitTypeInsn(NEW, lambdaClassInternalName);
+        String lambdaWrapperClassInternalName = 
BytecodeHelper.getClassInternalName(lambdaWrapperClassNode);
+        mv.visitTypeInsn(NEW, lambdaWrapperClassInternalName);
         mv.visitInsn(DUP);
 
         loadEnclosingClassInstance();
@@ -228,7 +225,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         loadSharedVariables(syntheticLambdaMethodNode);
 
         List<ConstructorNode> constructorNodeList =
-                lambdaClassNode.getDeclaredConstructors().stream()
+                lambdaWrapperClassNode.getDeclaredConstructors().stream()
                         .filter(e -> 
Boolean.TRUE.equals(e.getNodeMetaData(IS_GENERATED_CONSTRUCTOR)))
                         .collect(Collectors.toList());
 
@@ -237,10 +234,10 @@ public class StaticTypesLambdaWriter extends LambdaWriter 
{
         }
 
         ConstructorNode constructorNode = constructorNodeList.get(0);
-        Parameter[] lambdaClassConstructorParameters = 
constructorNode.getParameters();
-        mv.visitMethodInsn(INVOKESPECIAL, lambdaClassInternalName, INIT, 
BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, 
lambdaClassConstructorParameters), lambdaClassNode.isInterface());
+        Parameter[] lambdaWrapperClassConstructorParameters = 
constructorNode.getParameters();
+        mv.visitMethodInsn(INVOKESPECIAL, lambdaWrapperClassInternalName, 
INIT, BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, 
lambdaWrapperClassConstructorParameters), lambdaWrapperClassNode.isInterface());
         OperandStack operandStack = controller.getOperandStack();
-        operandStack.replace(ClassHelper.LAMBDA_TYPE, 
lambdaClassConstructorParameters.length);
+        operandStack.replace(ClassHelper.LAMBDA_TYPE, 
lambdaWrapperClassConstructorParameters.length);
 
         BytecodeVariable variable = 
controller.getCompileStack().defineVariable(new 
VariableExpression(LAMBDA_WRAPPER, ClassHelper.LAMBDA_TYPE), false);
         operandStack.storeVar(variable);

http://git-wip-us.apache.org/repos/asf/groovy/blob/0b8beb93/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
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 a372284..4688e3b 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -133,6 +133,7 @@ import static 
org.codehaus.groovy.ast.ClassHelper.GROOVY_OBJECT_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.GSTRING_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Integer_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Iterator_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.LAMBDA_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.LIST_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Long_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.MAP_TYPE;
@@ -4098,6 +4099,10 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
             if (receiver.isInterface()) {
                 collectAllInterfaceMethodsByName(receiver, name, methods);
                 methods.addAll(OBJECT_TYPE.getMethods(name));
+
+                if 
(!receiver.getAnnotations(ClassHelper.FunctionalInterface_Type).isEmpty()) {
+                    methods.addAll(LAMBDA_TYPE.getDeclaredMethods("call"));
+                }
             }
             // TODO: investigate the trait exclusion a bit further, needed 
otherwise
             // CallMethodOfTraitInsideClosureAndClosureParamTypeInference 
fails saying

http://git-wip-us.apache.org/repos/asf/groovy/blob/0b8beb93/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 212ec11..1a0b1ab 100644
--- a/src/test/groovy/transform/stc/LambdaTest.groovy
+++ b/src/test/groovy/transform/stc/LambdaTest.groovy
@@ -405,16 +405,11 @@ TestScript0.groovy: 14: [Static type checking] - Cannot 
find matching method jav
     void testFunctionCall() {
         if (SKIP_ERRORS) return
 
-        /* FIXME
-        [Static type checking] - Cannot find matching method 
java.lang.Object#plus(int). Please check if the declared type is correct and if 
the method exists.
- @ line 13, column 35.
-                   assert 2 == (e -> e + 1)(1)
-         */
-
         assertScript '''
         import groovy.transform.CompileStatic
         import java.util.stream.Collectors
         import java.util.stream.Stream
+        import java.util.function.Function
         
         @CompileStatic
         public class Test1 {
@@ -423,7 +418,8 @@ TestScript0.groovy: 14: [Static type checking] - Cannot 
find matching method jav
             }
         
             public static void p() {
-                assert 2 == (e -> e + 1)(1)
+                Function<Integer, Integer> f = (Integer e) -> (Integer) (e + 
1) // Casting is required...  [Static type checking] - Incompatible generic 
argument types. Cannot assign java.util.function.Function <java.lang.Integer, 
int> to: java.util.function.Function <Integer, Integer>
+                assert 2 == f(1)
             }
         }
         '''

Reply via email to