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 2020/10/29 04:55:16 UTC
[groovy] branch master updated: GROOVY-9790: bootstrap method
initialization exception raised when lambda parameter type is wrong
This is an automated email from the ASF dual-hosted git repository.
sunlan 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 d735788 GROOVY-9790: bootstrap method initialization exception raised when lambda parameter type is wrong
d735788 is described below
commit d7357882f116a2e18daba6d64a66220f7a2c6327
Author: Daniel Sun <su...@apache.org>
AuthorDate: Fri Oct 23 17:37:13 2020 +0800
GROOVY-9790: bootstrap method initialization exception raised when lambda parameter type is wrong
---
.../asm/sc/AbstractFunctionalInterfaceWriter.java | 20 ++++--
src/test/groovy/bugs/Groovy9790.groovy | 72 ++++++++++++++++++++++
2 files changed, 88 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
index e425cc0..57c681c 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
@@ -24,6 +24,7 @@ import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.classgen.asm.BytecodeHelper;
+import org.codehaus.groovy.syntax.RuntimeParserException;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@@ -32,6 +33,7 @@ import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
+import static org.codehaus.groovy.ast.ClassHelper.getUnwrapper;
import static org.codehaus.groovy.ast.ClassHelper.getWrapper;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.INFERRED_FUNCTIONAL_INTERFACE_TYPE;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.PARAMETER_TYPE;
@@ -106,17 +108,27 @@ public interface AbstractFunctionalInterfaceWriter {
}
default ClassNode convertParameterType(ClassNode parameterType, ClassNode inferredType) {
+ if (!getWrapper(inferredType.redirect()).isDerivedFrom(getWrapper(parameterType.redirect()))) {
+ throw new RuntimeParserException("The inferred type[" + inferredType.redirect() + "] is not compatible with the parameter type[" + parameterType.redirect() + "]", parameterType);
+ }
+
ClassNode type;
boolean isParameterTypePrimitive = ClassHelper.isPrimitiveType(parameterType);
boolean isInferredTypePrimitive = ClassHelper.isPrimitiveType(inferredType);
if (!isParameterTypePrimitive && isInferredTypePrimitive) {
- // The non-primitive type and primitive type are not allowed to mix since Java 9+
- // java.lang.invoke.LambdaConversionException: Type mismatch for instantiated parameter 0: int is not a subtype of class java.lang.Object
- type = getWrapper(inferredType);
+ if (parameterType != getUnwrapper(parameterType) && inferredType != getWrapper(inferredType)) {
+ // GROOVY-9790: bootstrap method initialization exception raised when lambda parameter type is wrong
+ // java.lang.BootstrapMethodError: bootstrap method initialization exception
+ type = inferredType;
+ } else {
+ // The non-primitive type and primitive type are not allowed to mix since Java 9+
+ // java.lang.invoke.LambdaConversionException: Type mismatch for instantiated parameter 0: int is not a subtype of class java.lang.Object
+ type = getWrapper(inferredType);
+ }
} else if (isParameterTypePrimitive && !isInferredTypePrimitive) {
// The non-primitive type and primitive type are not allowed to mix since Java 9+
// java.lang.invoke.LambdaConversionException: Type mismatch for instantiated parameter 0: class java.lang.Integer is not a subtype of int
- type = ClassHelper.getUnwrapper(inferredType);
+ type = getUnwrapper(inferredType);
} else {
type = inferredType;
}
diff --git a/src/test/groovy/bugs/Groovy9790.groovy b/src/test/groovy/bugs/Groovy9790.groovy
new file mode 100644
index 0000000..b2b4044
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9790.groovy
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package bugs
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+import static groovy.test.GroovyAssert.shouldFail
+
+@CompileStatic
+final class Groovy9790 {
+ @Test
+ void "test GROOVY-9790 - 1"() {
+ assertScript '''
+ import java.util.stream.IntStream
+
+ @groovy.transform.CompileStatic
+ def x() {
+ IntStream.range(0, 2).forEach((Integer i) -> { assert 0 <= i && i < 2})
+ }
+
+ x()
+ '''
+ }
+
+ @Test
+ void "test GROOVY-9790 - 2"() {
+ assertScript '''
+ import java.util.stream.IntStream
+
+ @groovy.transform.CompileStatic
+ def x() {
+ IntStream.range(0, 2).forEach((int i) -> { assert 0 <= i && i < 2})
+ }
+
+ x()
+ '''
+ }
+
+ @Test
+ void "test GROOVY-9790 - 3"() {
+ def err = shouldFail '''
+ import java.util.stream.IntStream
+
+ @groovy.transform.CompileStatic
+ def x() {
+ IntStream.range(0, 2).forEach((String i) -> { return i })
+ }
+
+ x()
+ '''
+
+ assert err.toString().contains('The inferred type[int] is not compatible with the parameter type[java.lang.String]\n. At [6:48]')
+ }
+}