diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java index 649037a08b7..9b5cc18440a 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java @@ -70,6 +70,8 @@ import java.security.PrivilegedAction; import java.util.List; +import static org.codehaus.groovy.runtime.MetaClassHelper.EMPTY_CLASS_ARRAY; + /** * Java 8 based functions. * @@ -77,19 +79,20 @@ */ public class Java8 implements VMPlugin { - private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; private static final Method[] EMPTY_METHOD_ARRAY = new Method[0]; private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; private static final Permission ACCESS_PERMISSION = new ReflectPermission("suppressAccessChecks"); - public static GenericsType configureTypeVariableDefinition(final ClassNode base, final ClassNode[] cBounds) { + public static GenericsType configureTypeVariableDefinition(final ClassNode base, final ClassNode[] bounds) { ClassNode redirect = base.redirect(); base.setRedirect(null); GenericsType gt; - if (cBounds == null || cBounds.length == 0) { + if (bounds == null || bounds.length == 0) { gt = new GenericsType(base); } else { - gt = new GenericsType(base, cBounds, null); + // GROOVY-10756: fix erasure -- ResolveVisitor#resolveGenericsHeader + if (!ClassHelper.OBJECT_TYPE.equals(bounds[0])) redirect = bounds[0]; + gt = new GenericsType(base, bounds, null); gt.setName(base.getName()); gt.setPlaceholder(true); } @@ -97,25 +100,25 @@ public static GenericsType configureTypeVariableDefinition(final ClassNode base, return gt; } - private static ClassNode configureClass(final Class c) { - if (c.isPrimitive()) { - return ClassHelper.make(c); - } else { - return ClassHelper.makeWithoutCaching(c, false); - } - } - public static ClassNode configureTypeVariableReference(final String name) { ClassNode cn = ClassHelper.makeWithoutCaching(name); cn.setGenericsPlaceHolder(true); ClassNode cn2 = ClassHelper.makeWithoutCaching(name); cn2.setGenericsPlaceHolder(true); - GenericsType[] gts = new GenericsType[]{new GenericsType(cn2)}; - cn.setGenericsTypes(gts); + + cn.setGenericsTypes(new GenericsType[]{new GenericsType(cn2)}); cn.setRedirect(ClassHelper.OBJECT_TYPE); return cn; } + private static ClassNode configureClass(final Class c) { + if (c.isPrimitive()) { + return ClassHelper.make(c); + } else { + return ClassHelper.makeWithoutCaching(c, false); + } + } + private static void setRetentionPolicy(final RetentionPolicy value, final AnnotationNode node) { switch (value) { case RUNTIME: @@ -132,11 +135,7 @@ private static void setRetentionPolicy(final RetentionPolicy value, final Annota } } - private static void setMethodDefaultValue(final MethodNode mn, final Method m) { - ConstantExpression cExp = new ConstantExpression(m.getDefaultValue()); - mn.setCode(new ReturnStatement(cExp)); - mn.setAnnotationDefault(true); - } + //-------------------------------------------------------------------------- @Override public Class[] getPluginDefaultGroovyMethods() { @@ -187,27 +186,7 @@ protected int getElementCode(final ElementType value) { @Override public void setAdditionalClassInformation(final ClassNode cn) { - setGenericsTypes(cn); - } - - private void setGenericsTypes(final ClassNode cn) { - TypeVariable[] tvs = cn.getTypeClass().getTypeParameters(); - GenericsType[] gts = configureTypeVariable(tvs); - cn.setGenericsTypes(gts); - } - - private GenericsType[] configureTypeVariable(final TypeVariable[] tvs) { - final int n = tvs.length; - if (n == 0) return null; - GenericsType[] gts = new GenericsType[n]; - for (int i = 0; i < n; i += 1) { - gts[i] = configureTypeVariableDefinition(tvs[i]); - } - return gts; - } - - private GenericsType configureTypeVariableDefinition(final TypeVariable tv) { - return configureTypeVariableDefinition(configureTypeVariableReference(tv.getName()), configureTypes(tv.getBounds())); + cn.setGenericsTypes(configureTypeParameters(cn.getTypeClass().getTypeParameters())); } private ClassNode[] configureTypes(final Type[] types) { @@ -228,7 +207,7 @@ private ClassNode configureType(final Type type) { } else if (type instanceof GenericArrayType) { return configureGenericArray((GenericArrayType) type); } else if (type instanceof TypeVariable) { - return configureTypeVariableReference(((TypeVariable) type).getName()); + return configureTypeVariableReference(((TypeVariable) type).getName()); } else if (type instanceof Class) { return configureClass((Class) type); } else if (type == null) { @@ -286,6 +265,18 @@ private GenericsType[] configureTypeArguments(final Type[] ta) { return gts; } + private GenericsType[] configureTypeParameters(final TypeVariable[] tp) { + final int n = tp.length; + if (n == 0) return null; + GenericsType[] gt = new GenericsType[n]; + for (int i = 0; i < n; i += 1) { + ClassNode t = configureTypeVariableReference(tp[i].getName()); + ClassNode[] bounds = configureTypes(tp[i].getBounds()); + gt[i] = configureTypeVariableDefinition(t, bounds); + } + return gt; + } + // @Override @@ -378,8 +369,7 @@ private Expression toAnnotationValueExpression(final Object value) { @Override public void configureAnnotationNodeFromDefinition(final AnnotationNode definition, final AnnotationNode root) { - ClassNode type = definition.getClassNode(); - final String typeName = type.getName(); + String typeName = definition.getClassNode().getName(); if ("java.lang.annotation.Retention".equals(typeName)) { Expression exp = definition.getMember("value"); if (!(exp instanceof PropertyExpression)) return; @@ -390,16 +380,16 @@ public void configureAnnotationNodeFromDefinition(final AnnotationNode definitio } else if ("java.lang.annotation.Target".equals(typeName)) { Expression exp = definition.getMember("value"); if (!(exp instanceof ListExpression)) return; - ListExpression le = (ListExpression) exp; - int bitmap = 0; - for (Expression e : le.getExpressions()) { + ListExpression list = (ListExpression) exp; + int targets = 0; + for (Expression e : list.getExpressions()) { if (!(e instanceof PropertyExpression)) return; PropertyExpression element = (PropertyExpression) e; String name = element.getPropertyAsString(); - ElementType value = ElementType.valueOf(name); - bitmap |= getElementCode(value); + ElementType type = ElementType.valueOf(name); + targets |= getElementCode(type); } - root.setAllowedTargets(bitmap); + root.setAllowedTargets(targets); } } @@ -409,29 +399,32 @@ public void configureClassNode(final CompileUnit compileUnit, final ClassNode cl Class clazz = classNode.getTypeClass(); Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { - ClassNode ret = makeClassNode(compileUnit, f.getGenericType(), f.getType()); - FieldNode fn = new FieldNode(f.getName(), f.getModifiers(), ret, classNode, null); + ClassNode rt = makeClassNode(compileUnit, f.getGenericType(), f.getType()); + FieldNode fn = new FieldNode(f.getName(), f.getModifiers(), rt, classNode, null); setAnnotationMetaData(f.getAnnotations(), fn); classNode.addField(fn); } Method[] methods = clazz.getDeclaredMethods(); for (Method m : methods) { - ClassNode ret = makeClassNode(compileUnit, m.getGenericReturnType(), m.getReturnType()); + ClassNode rt = makeClassNode(compileUnit, m.getGenericReturnType(), m.getReturnType()); Parameter[] params = makeParameters(compileUnit, m.getGenericParameterTypes(), m.getParameterTypes(), m.getParameterAnnotations(), m); ClassNode[] exceptions = makeClassNodes(compileUnit, m.getGenericExceptionTypes(), m.getExceptionTypes()); - MethodNode mn = new MethodNode(m.getName(), m.getModifiers(), ret, params, exceptions, null); - mn.setSynthetic(m.isSynthetic()); - setMethodDefaultValue(mn, m); + MethodNode mn = new MethodNode(m.getName(), m.getModifiers(), rt, params, exceptions, null); setAnnotationMetaData(m.getAnnotations(), mn); - mn.setGenericsTypes(configureTypeVariable(m.getTypeParameters())); + if (true) { // TODO: GROOVY-10862 + mn.setAnnotationDefault(true); + mn.setCode(new ReturnStatement(new ConstantExpression(m.getDefaultValue()))); + } + mn.setGenericsTypes(configureTypeParameters(m.getTypeParameters())); + mn.setSynthetic(m.isSynthetic()); classNode.addMethod(mn); } Constructor[] constructors = clazz.getDeclaredConstructors(); - for (Constructor ctor : constructors) { - Parameter[] params = makeParameters(compileUnit, ctor.getGenericParameterTypes(), ctor.getParameterTypes(), getConstructorParameterAnnotations(ctor), ctor); - ClassNode[] exceptions = makeClassNodes(compileUnit, ctor.getGenericExceptionTypes(), ctor.getExceptionTypes()); - ConstructorNode cn = classNode.addConstructor(ctor.getModifiers(), params, exceptions, null); - setAnnotationMetaData(ctor.getAnnotations(), cn); + for (Constructor c : constructors) { + Parameter[] params = makeParameters(compileUnit, c.getGenericParameterTypes(), c.getParameterTypes(), getConstructorParameterAnnotations(c), c); + ClassNode[] exceptions = makeClassNodes(compileUnit, c.getGenericExceptionTypes(), c.getExceptionTypes()); + ConstructorNode cn = classNode.addConstructor(c.getModifiers(), params, exceptions, null); + setAnnotationMetaData(c.getAnnotations(), cn); } Class sc = clazz.getSuperclass(); @@ -572,7 +565,7 @@ private Parameter[] makeParameters(final CompileUnit cu, final Type[] types, fin fillParameterNames(names, member); for (int i = 0; i < n; i += 1) { setAnnotationMetaData(parameterAnnotations[i], - params[i] = new Parameter(makeClassNode(cu, types[i], cls[i]), names[i])); + params[i] = new Parameter(makeClassNode(cu, types[i], cls[i]), names[i])); } } return params; @@ -589,6 +582,8 @@ protected void fillParameterNames(final String[] names, final Member member) { } } + //-------------------------------------------------------------------------- + /** * The following scenarios can not set accessible, i.e. the return value is false * 1) SecurityException occurred diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy index 9c64d32efe0..25742714bf7 100644 --- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy +++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy @@ -739,6 +739,11 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase { def file = Pogo10756.files[0] file?.name """ + + assertScript """import ${Pogo10756.name.replace('$','.')} + def files = Pogo10756.files + files*.name + """ } static class Pogo10756 { diff --git a/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy b/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy index a02ae19abdf..bbe96f953f6 100644 --- a/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy +++ b/src/test/org/codehaus/groovy/ast/decompiled/AsmDecompilerTest.groovy @@ -18,7 +18,6 @@ */ package org.codehaus.groovy.ast.decompiled -import junit.framework.TestCase import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.ClassNode @@ -26,24 +25,27 @@ import org.codehaus.groovy.ast.decompiled.support.* import org.codehaus.groovy.ast.expr.* import org.codehaus.groovy.control.ClassNodeResolver import org.codehaus.groovy.control.CompilationUnit -import org.objectweb.asm.Opcodes +import org.junit.Test -final class AsmDecompilerTest extends TestCase { +import static java.lang.reflect.Modifier.* - void "test decompile class"() { +final class AsmDecompilerTest { + + @Test + void "basic class"() { ClassNode node = decompile() - assert AsmDecompilerTestData.name == node.name - assert (node.modifiers & Opcodes.ACC_PUBLIC) != 0 + assert node.name == AsmDecompilerTestData.name assert !node.genericsPlaceHolder + assert isPublic(node.modifiers) assert node.usingGenerics def t = node.genericsTypes[0] assert t.name == 'T' assert t.placeholder - assert t.type.name == Object.name assert t.type.genericsPlaceHolder - assert !t.lowerBound + assert t.type.name == List.name // erasure of "T extends List" + assert t.lowerBound == null def list = t.upperBounds[0] assert list.name == List.name @@ -52,35 +54,41 @@ final class AsmDecompilerTest extends TestCase { def wildcard = list.genericsTypes[0] assert wildcard.wildcard - assert !wildcard.type.genericsPlaceHolder //todo? + assert !wildcard.type.genericsPlaceHolder + assert wildcard.type.name == Object.name // erasure of "? super T" assert !wildcard.upperBounds def tRef = wildcard.lowerBound assert tRef.genericsPlaceHolder assert tRef.usingGenerics assert tRef.name == Object.name + assert tRef.unresolvedName == 'T' assert tRef.genericsTypes[0].name == 'T' def v = node.genericsTypes[1] assert v.name == 'V' assert v.placeholder - assert v.upperBounds[0].toString() == Object.name + assert v.type.name == Object.name + assert v.upperBounds[0].name == Object.name } - void "test method object return type"() { - def method = decompile().getDeclaredMethod("objectMethod") + @Test + void "method object return type"() { + def method = decompile().getDeclaredMethod('objectMethod') assert method.returnType.name == ClassNode.name } - void "test method primitive array return type"() { - def method = decompile().getDeclaredMethod("primitiveArrayMethod") + @Test + void "method primitive array return type"() { + def method = decompile().getDeclaredMethod('primitiveArrayMethod') assert method.returnType.array assert method.returnType.componentType.array assert method.returnType.componentType.componentType == ClassHelper.int_TYPE } - void "test method parameters and exceptions"() { - def method = decompile().getDeclaredMethods("withParametersThrowing")[0] + @Test + void "method parameters and exceptions"() { + def method = decompile().getDeclaredMethods('withParametersThrowing')[0] assert method.parameters.length == 2 assert method.parameters[0].type == ClassHelper.int_TYPE @@ -90,17 +98,20 @@ final class AsmDecompilerTest extends TestCase { assert method.exceptions[0].name == IOException.name } - void "test field"() { - def field = decompile().getDeclaredField("aField") + @Test + void "basic field"() { + def field = decompile().getDeclaredField('aField') assert field.type.name == Object.name } - void "test constructor"() { + @Test + void "constructor"() { def constructor = decompile().getDeclaredConstructors()[0] assert constructor.parameters[0].type == ClassHelper.boolean_TYPE } - void "test supers"() { + @Test + void "supers"() { def node = decompile() assert node.superClass.name == SuperClass.name assert !node.superClass.usingGenerics @@ -126,12 +137,13 @@ final class AsmDecompilerTest extends TestCase { assert !string.type.usingGenerics } - void "test simple class annotations"() { + @Test + void "simple class annotations"() { def node = decompile().annotations[0] assert node.classNode.name == Anno.name - assert ((ConstantExpression) node.members.stringAttr).value == "s" + assert ((ConstantExpression) node.members.stringAttr).value == 's' assert !node.members.booleanAttr assert ((ClassExpression) node.members.clsAttr).type.name == String.name @@ -139,35 +151,40 @@ final class AsmDecompilerTest extends TestCase { assert ((PropertyExpression) node.members.enumAttr).objectExpression.type.name == SomeEnum.name } - void "test member annotations"() { + @Test + void "member annotations"() { def node = decompile() - assert node.getDeclaredField("aField").annotations[0].classNode.name == Anno.name - assert node.getDeclaredMethod("objectMethod").annotations[0].classNode.name == Anno.name - assert !node.getDeclaredMethods("withParametersThrowing")[0].annotations + assert node.getDeclaredField('aField').annotations[0].classNode.name == Anno.name + assert node.getDeclaredMethod('objectMethod').annotations[0].classNode.name == Anno.name + assert !node.getDeclaredMethods('withParametersThrowing')[0].annotations } - void "test parameter annotations"() { + @Test + void "parameter annotations"() { def node = decompile() - def params = node.getDeclaredMethods("withParametersThrowing")[0].parameters + def params = node.getDeclaredMethods('withParametersThrowing')[0].parameters assert params[0].annotations.collect { it.classNode.name } == [Anno.name] assert !params[1].annotations } - void "test primitive array attribute"() { + @Test + void "primitive array attribute"() { def node = decompile().annotations[0] def list = ((ListExpression) node.members.intArrayAttr).expressions assert list.collect { ((ConstantExpression) it).value } == [4, 2] } - void "test class array attribute"() { + @Test + void "class array attribute"() { def node = decompile().annotations[0] def list = ((ListExpression) node.members.classArrayAttr).expressions assert list.collect { ((ClassExpression) it).type.name } == [AsmDecompilerTestData.name] } - void "test annotation array attribute"() { + @Test + void "annotation array attribute"() { def node = decompile().annotations[0] def list = ((ListExpression) node.members.annoArrayAttr).expressions @@ -181,14 +198,16 @@ final class AsmDecompilerTest extends TestCase { assert ((ConstantExpression) annotationNode.members.booleanAttr).value == false } - void "test annotation default method"() { - def method = decompile(Anno.name).getDeclaredMethod('booleanAttr') + @Test + void "annotation default method"() { + def method = decompile(Anno).getDeclaredMethod('booleanAttr') assert method.hasAnnotationDefault() assert method.code } - void "test annotation retention and targets"() { - def anno = decompile().getAnnotations(decompile(Anno.name))[0] + @Test + void "annotation retention and targets"() { + def anno = decompile().getAnnotations(decompile(Anno))[0] assert anno.hasRuntimeRetention() assert !anno.hasClassRetention() assert !anno.hasSourceRetention() @@ -198,8 +217,9 @@ final class AsmDecompilerTest extends TestCase { assert !anno.isTargetAllowed(AnnotationNode.LOCAL_VARIABLE_TARGET) } - void "test enum field"() { - def node = decompile(SomeEnum.name).plainNodeReference + @Test + void "enum field"() { + def node = decompile(SomeEnum).plainNodeReference for (s in ['FOO', 'BAR']) { def field = node.getDeclaredField(s) assert field @@ -207,8 +227,9 @@ final class AsmDecompilerTest extends TestCase { } } - void "test generic method"() { - def method = decompile().getDeclaredMethods("genericMethod")[0] + @Test + void "generic method"() { + def method = decompile().getDeclaredMethods('genericMethod')[0] assert method.genericsTypes.size() == 2 assert method.genericsTypes[0].name == 'A' @@ -240,18 +261,21 @@ final class AsmDecompilerTest extends TestCase { assert wildcard.upperBounds == null } - void "test non-generic exceptions"() { - def method = decompile().getDeclaredMethods("nonGenericExceptions")[0] + @Test + void "non-generic exceptions"() { + def method = decompile().getDeclaredMethods('nonGenericExceptions')[0] assert method.exceptions[0].name == IOException.name } - void "test non-generic parameters"() { - def method = decompile().getDeclaredMethods("nonGenericParameters")[0] + @Test + void "non-generic parameters"() { + def method = decompile().getDeclaredMethods('nonGenericParameters')[0] assert method.parameters[0].type == ClassHelper.boolean_TYPE } - void "test generic field"() { - def type = decompile().getDeclaredField("genericField").type + @Test + void "generic field"() { + def type = decompile().getDeclaredField('genericField').type assert type.name == List.name assert type.usingGenerics @@ -262,83 +286,92 @@ final class AsmDecompilerTest extends TestCase { assert tRef.genericsTypes[0].name == 'T' } - void "test non-trivial erasure"() { - def cls = decompile(NonTrivialErasure.name) + @Test + void "non-trivial erasure"() { + def cls = decompile(NonTrivialErasure) - def method = cls.getDeclaredMethods("method")[0] + def method = cls.getDeclaredMethods('method')[0] assert method.returnType.toString() == 'V -> java.lang.RuntimeException' assert method.parameters[0].type.toString() == 'V -> java.lang.RuntimeException' assert method.exceptions[0].toString() == 'V -> java.lang.RuntimeException' - def field = cls.getDeclaredField("field") + def field = cls.getDeclaredField('field') assert field.type.toString() == 'V -> java.lang.RuntimeException' } - void "test static inner class"() { - ClassNode cn = decompile(AsmDecompilerTestData.InnerStatic.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) != 0 + @Test + void "static inner class"() { + ClassNode cn = decompile(AsmDecompilerTestData.InnerStatic) + assert isStatic(cn.modifiers) } - void "test static inner with dollar"() { - ClassNode cn = decompile(AsmDecompilerTestData.Inner$WithDollar.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) != 0 + @Test + void "static inner with dollar"() { + ClassNode cn = decompile(AsmDecompilerTestData.Inner$WithDollar) + assert isStatic(cn.modifiers) } - void "test static inner classes with same name"() { - ClassNode cn = decompile(Groovy8632Abstract.Builder.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) != 0 - assert (cn.modifiers & Opcodes.ACC_ABSTRACT) != 0 + @Test + void "static inner classes with same name"() { + ClassNode cn = decompile(Groovy8632Abstract.Builder) + assert isStatic(cn.modifiers) + assert isAbstract(cn.modifiers) - cn = decompile(Groovy8632.Builder.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) != 0 - assert (cn.modifiers & Opcodes.ACC_ABSTRACT) == 0 + cn = decompile(Groovy8632.Builder) + assert isStatic(cn.modifiers) + assert !isAbstract(cn.modifiers) - cn = decompile(Groovy8632Groovy.Builder.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) != 0 - assert (cn.modifiers & Opcodes.ACC_ABSTRACT) == 0 + cn = decompile(Groovy8632Groovy.Builder) + assert isStatic(cn.modifiers) + assert !isAbstract(cn.modifiers) } - void "test inner classes with same name"() { - ClassNode cn = decompile(Groovy8632Abstract.InnerBuilder.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) == 0 - assert (cn.modifiers & Opcodes.ACC_ABSTRACT) != 0 + @Test + void "inner classes with same name"() { + ClassNode cn = decompile(Groovy8632Abstract.InnerBuilder) + assert !isStatic(cn.modifiers) + assert isAbstract(cn.modifiers) - cn = decompile(Groovy8632.InnerBuilder.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) == 0 - assert (cn.modifiers & Opcodes.ACC_ABSTRACT) == 0 + cn = decompile(Groovy8632.InnerBuilder) + assert !isStatic(cn.modifiers) + assert !isAbstract(cn.modifiers) - cn = decompile(Groovy8632Groovy.InnerBuilder.name) - assert (cn.modifiers & Opcodes.ACC_STATIC) == 0 - assert (cn.modifiers & Opcodes.ACC_ABSTRACT) == 0 + cn = decompile(Groovy8632Groovy.InnerBuilder) + assert !isStatic(cn.modifiers) + assert !isAbstract(cn.modifiers) } - void "test private inner class"() { - ClassNode cn = decompile(Groovy8632.InnerPrivate.name) - assert (cn.modifiers & Opcodes.ACC_PRIVATE) != 0 - assert (cn.modifiers & Opcodes.ACC_PUBLIC) == 0 + @Test + void "private inner class"() { + ClassNode cn = decompile(Groovy8632.InnerPrivate) + assert isPrivate(cn.modifiers) + assert !isPublic(cn.modifiers) } - void "test protected inner class"() { - ClassNode cn = decompile(Groovy8632.InnerProtected.name) - assert (cn.modifiers & Opcodes.ACC_PROTECTED) != 0 - assert (cn.modifiers & Opcodes.ACC_PUBLIC) == 0 + @Test + void "protected inner class"() { + ClassNode cn = decompile(Groovy8632.InnerProtected) + assert isProtected(cn.modifiers) + assert !isPublic(cn.modifiers) } - void "test non-parameterized generics"() { - assert decompile().getDeclaredMethod("nonParameterizedGenerics").genericsTypes == null + @Test + void "non-parameterized generics"() { + assert decompile().getDeclaredMethod('nonParameterizedGenerics').genericsTypes == null } - void "test non-static parameterized inner"() { - def asmType = decompile().getDeclaredMethod("returnInner").returnType - def jvmType = new ClassNode(AsmDecompilerTestData).getDeclaredMethod("returnInner").returnType + @Test + void "non-static parameterized inner"() { + def asmType = decompile().getDeclaredMethod('returnInner').returnType + def jvmType = new ClassNode(AsmDecompilerTestData).getDeclaredMethod('returnInner').returnType assert asmType == jvmType - assert asmType.genericsTypes.collect { it.name } == jvmType.genericsTypes.collect { it.name } + assert asmType.genericsTypes*.name == jvmType.genericsTypes*.name } //-------------------------------------------------------------------------- - private static ClassNode decompile(String className = AsmDecompilerTestData.name) { - def classFileName = className.replace('.', '/') + '.class' + private static ClassNode decompile(Class clazz = AsmDecompilerTestData) { + def classFileName = clazz.name.replace('.', '/') + '.class' def resource = AsmDecompilerTest.classLoader.getResource(classFileName) def stub = AsmDecompiler.parseClass(resource)