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 26a28be GROOVY-8638: erase generics for no-signature fields/methods like bridges 26a28be is described below commit 26a28be1f31a10b04ffc3315f19d4fca510d2581 Author: Eric Milles <eric.mil...@thomsonreuters.com> AuthorDate: Tue Jun 1 11:01:02 2021 -0500 GROOVY-8638: erase generics for no-signature fields/methods like bridges --- .../ast/decompiled/MemberSignatureParser.java | 9 ++++++ .../groovy/transform/stc/GenericsSTCTest.groovy | 19 ++++++++++++- .../groovy/ast/decompiled/AsmDecompilerTest.groovy | 32 ++++++++++------------ .../ast/decompiled/AsmDecompilerTestData.java | 1 + 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java index 552547e..f2c4aa5 100644 --- a/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java +++ b/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java @@ -27,6 +27,7 @@ import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.Parameter; import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.ast.stmt.ReturnStatement; +import org.codehaus.groovy.ast.tools.GenericsUtils; import org.objectweb.asm.Type; import org.objectweb.asm.signature.SignatureReader; import org.objectweb.asm.signature.SignatureVisitor; @@ -48,6 +49,9 @@ class MemberSignatureParser { type[0] = applyErasure(result, type[0]); } }); + } else { + // ex: java.util.Collections#EMPTY_LIST/EMPTY_MAP/EMPTY_SET + type[0] = GenericsUtils.nonGeneric(type[0]); } return new FieldNode(field.fieldName, field.accessModifiers, type[0], owner, field.value != null ? new ConstantExpression(field.value) : null); } @@ -99,6 +103,11 @@ class MemberSignatureParser { }; new SignatureReader(method.signature).accept(parser); typeParameters = parser.getTypeParameters(); + } else { + returnType[0] = GenericsUtils.nonGeneric(returnType[0]); + for (int i = 0, n = parameterTypes.length; i < n; i += 1) { + parameterTypes[i] = GenericsUtils.nonGeneric(parameterTypes[i]); + } } int nParameters = parameterTypes.length; diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy index 91fb1e6..c02e904 100644 --- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy +++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy @@ -468,6 +468,23 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase { ''' } + // GROOVY-8638 + void testReturnTypeInferenceWithMethodGenerics17() { + assertScript ''' + @Grab('com.google.guava:guava:30.1.1-jre') + import com.google.common.collect.* + + ListMultimap<String, Integer> mmap = ArrayListMultimap.create() + + Map<String, Collection<Integer>> map = mmap.asMap() + Set<Map.Entry<String, Collection<Integer>>> set = map.entrySet() + Iterator<Map.Entry<String, Collection<Integer>>> it = set.iterator() + while (it.hasNext()) { Map.Entry<String, Collection<Integer>> entry = it.next() + Collection<Integer> values = entry.value + } + ''' + } + void testDiamondInferrenceFromConstructor1() { assertScript ''' class Foo<U> { @@ -2918,7 +2935,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase { // GROOVY-6760 void testGenericsAtMethodLevelWithGenericsInTypeOfGenericType() { assertScript ''' - @Grab(group='com.netflix.rxjava', module='rxjava-core', version='0.18.1') + @Grab('com.netflix.rxjava:rxjava-core:0.18.1') import rx.Observable import java.util.concurrent.Callable diff --git a/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy b/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy index 73decc5..a02ae19 100644 --- a/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy +++ b/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy @@ -28,7 +28,7 @@ import org.codehaus.groovy.control.ClassNodeResolver import org.codehaus.groovy.control.CompilationUnit import org.objectweb.asm.Opcodes -class AsmDecompilerTest extends TestCase { +final class AsmDecompilerTest extends TestCase { void "test decompile class"() { ClassNode node = decompile() @@ -198,13 +198,9 @@ class AsmDecompilerTest extends TestCase { assert !anno.isTargetAllowed(AnnotationNode.LOCAL_VARIABLE_TARGET) } - static enum TestEnum { - SOURCE, CLASS, RUNTIME - } - void "test enum field"() { - def node = decompile(TestEnum.name).plainNodeReference - for (s in ['SOURCE', 'CLASS', 'RUNTIME']) { + def node = decompile(SomeEnum.name).plainNodeReference + for (s in ['FOO', 'BAR']) { def field = node.getDeclaredField(s) assert field assert field.type == node @@ -278,10 +274,14 @@ class AsmDecompilerTest extends TestCase { assert field.type.toString() == 'V -> java.lang.RuntimeException' } - static class SomeInnerclass {} - void "test static inner class"() { - assert (decompile(SomeInnerclass.name).modifiers & Opcodes.ACC_STATIC) != 0 + ClassNode cn = decompile(AsmDecompilerTestData.InnerStatic.name) + assert (cn.modifiers & Opcodes.ACC_STATIC) != 0 + } + + void "test static inner with dollar"() { + ClassNode cn = decompile(AsmDecompilerTestData.Inner$WithDollar.name) + assert (cn.modifiers & Opcodes.ACC_STATIC) != 0 } void "test static inner classes with same name"() { @@ -298,10 +298,6 @@ class AsmDecompilerTest extends TestCase { assert (cn.modifiers & Opcodes.ACC_ABSTRACT) == 0 } - void "test static inner with dollar"() { - assert (decompile(AsmDecompilerTestData.Inner$WithDollar.name).modifiers & Opcodes.ACC_STATIC) != 0 - } - void "test inner classes with same name"() { ClassNode cn = decompile(Groovy8632Abstract.InnerBuilder.name) assert (cn.modifiers & Opcodes.ACC_STATIC) == 0 @@ -339,14 +335,14 @@ class AsmDecompilerTest extends TestCase { assert asmType.genericsTypes.collect { it.name } == jvmType.genericsTypes.collect { it.name } } - private static ClassNode decompile(String cls = AsmDecompilerTestData.name) { - def classFileName = cls.replace('.', '/') + '.class' + //-------------------------------------------------------------------------- + + private static ClassNode decompile(String className = AsmDecompilerTestData.name) { + def classFileName = className.replace('.', '/') + '.class' def resource = AsmDecompilerTest.classLoader.getResource(classFileName) def stub = AsmDecompiler.parseClass(resource) def unit = new CompilationUnit(new GroovyClassLoader(AsmDecompilerTest.classLoader)) return new DecompiledClassNode(stub, new AsmReferenceResolver(new ClassNodeResolver(), unit)) } - } - diff --git a/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTestData.java b/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTestData.java index e816543..fcd81ff 100644 --- a/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTestData.java +++ b/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTestData.java @@ -73,6 +73,7 @@ public class AsmDecompilerTestData<T extends List<? super T>, V> extends SuperCl public List<T> genericField; class Inner<X> {} + static class InnerStatic {} static class Inner$WithDollar {} static <T extends List<? super T>> AsmDecompilerTestData<T, Integer>.Inner<String> returnInner() { return null; }