From c06dc849ee5ee823965092297f4163909ab91fc7 Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Sun, 10 Jan 2016 21:43:03 -0800 Subject: [PATCH] Alter when accessor methods are generated. For owned, non-private methods, omit the accessor since the generated class can access the method directly. For non-owned methods, generate the accessor when the method is protected since the generated class will not have access. --- .../retrolambda/test/LambdaTest.java | 14 ++++ .../anotherpackage/DifferentPackageBase.java | 11 +++ .../orfjackal/retrolambda/Retrolambda.java | 2 +- .../orfjackal/retrolambda/Transformers.java | 8 +-- .../AddMethodDefaultImplementations.java | 4 +- ...rarchyAnalyzer.java => ClassAnalyzer.java} | 18 +++-- .../retrolambda/interfaces/ClassInfo.java | 4 +- .../retrolambda/interfaces/MethodInfo.java | 11 +-- .../UpdateRelocatedMethodInvocations.java | 4 +- .../lambdas/BackportLambdaInvocations.java | 49 +++++++++++-- ...alyzerTest.java => ClassAnalyzerTest.java} | 68 +++++++++---------- 11 files changed, 131 insertions(+), 62 deletions(-) create mode 100644 end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/anotherpackage/DifferentPackageBase.java rename retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/{ClassHierarchyAnalyzer.java => ClassAnalyzer.java} (92%) rename retrolambda/src/test/java/net/orfjackal/retrolambda/{ClassHierarchyAnalyzerTest.java => ClassAnalyzerTest.java} (89%) diff --git a/end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/LambdaTest.java b/end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/LambdaTest.java index 0f0f19c9..b2184dca 100644 --- a/end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/LambdaTest.java +++ b/end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/LambdaTest.java @@ -4,6 +4,7 @@ package net.orfjackal.retrolambda.test; +import net.orfjackal.retrolambda.test.anotherpackage.DifferentPackageBase; import org.apache.commons.lang.SystemUtils; import org.junit.Test; import org.objectweb.asm.*; @@ -150,6 +151,19 @@ public void method_references_to_constructors() throws Exception { assertThat(ref.call(), is(instanceOf(ArrayList.class))); } + @Test + public void method_references_to_protected_supertype_methods() throws Exception { + Callable ref = new SubclassInMyPackage().thing(); + + Assert.assertThat(ref.call(), equalTo("Hello")); + } + + public static class SubclassInMyPackage extends DifferentPackageBase { + public Callable thing() { + return DifferentPackageBase::value; + } + } + /** * Because the constructor is private, an access method must be generated for it * and also the NEW instruction must be done inside the access method. diff --git a/end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/anotherpackage/DifferentPackageBase.java b/end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/anotherpackage/DifferentPackageBase.java new file mode 100644 index 00000000..8b482a6b --- /dev/null +++ b/end-to-end-tests/src/test/java/net/orfjackal/retrolambda/test/anotherpackage/DifferentPackageBase.java @@ -0,0 +1,11 @@ +// Copyright © 2013-2016 Esko Luontola +// This software is released under the Apache License 2.0. +// The license text is at http://www.apache.org/licenses/LICENSE-2.0 + +package net.orfjackal.retrolambda.test.anotherpackage; + +public class DifferentPackageBase { + protected static String value() { + return "Hello"; + } +} diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java index 42276b6e..e03da2b8 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/Retrolambda.java @@ -38,7 +38,7 @@ public static void run(Config config) throws Throwable { Thread.currentThread().setContextClassLoader(new NonDelegatingClassLoader(asUrls(classpath))); - ClassHierarchyAnalyzer analyzer = new ClassHierarchyAnalyzer(); + ClassAnalyzer analyzer = new ClassAnalyzer(); OutputDirectory outputDirectory = new OutputDirectory(outputDir); Transformers transformers = new Transformers(bytecodeVersion, defaultMethodsEnabled, analyzer); LambdaClassSaver lambdaClassSaver = new LambdaClassSaver(outputDirectory, transformers); diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java index 425b9931..af995e68 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/Transformers.java @@ -17,9 +17,9 @@ public class Transformers { private final int targetVersion; private final boolean defaultMethodsEnabled; - private final ClassHierarchyAnalyzer analyzer; + private final ClassAnalyzer analyzer; - public Transformers(int targetVersion, boolean defaultMethodsEnabled, ClassHierarchyAnalyzer analyzer) { + public Transformers(int targetVersion, boolean defaultMethodsEnabled, ClassAnalyzer analyzer) { this.targetVersion = targetVersion; this.defaultMethodsEnabled = defaultMethodsEnabled; this.analyzer = analyzer; @@ -48,7 +48,7 @@ public byte[] backportClass(ClassReader reader) { next = new UpdateRelocatedMethodInvocations(next, analyzer); next = new AddMethodDefaultImplementations(next, analyzer); } - next = new BackportLambdaInvocations(next); + next = new BackportLambdaInvocations(next, analyzer); return next; }); } @@ -59,7 +59,7 @@ public List backportInterface(ClassReader reader) { // the wrong one of them is written to disk last. ClassNode lambdasBackported = new ClassNode(); ClassVisitor next = lambdasBackported; - next = new BackportLambdaInvocations(next); + next = new BackportLambdaInvocations(next, analyzer); reader.accept(next, 0); List results = new ArrayList<>(); diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/AddMethodDefaultImplementations.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/AddMethodDefaultImplementations.java index 11c147b7..ed646935 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/AddMethodDefaultImplementations.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/AddMethodDefaultImplementations.java @@ -11,10 +11,10 @@ public class AddMethodDefaultImplementations extends ClassVisitor { - private final ClassHierarchyAnalyzer analyzer; + private final ClassAnalyzer analyzer; private String className; - public AddMethodDefaultImplementations(ClassVisitor next, ClassHierarchyAnalyzer analyzer) { + public AddMethodDefaultImplementations(ClassVisitor next, ClassAnalyzer analyzer) { super(ASM5, next); this.analyzer = analyzer; } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassHierarchyAnalyzer.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassAnalyzer.java similarity index 92% rename from retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassHierarchyAnalyzer.java rename to retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassAnalyzer.java index a41e27a9..f667dbb1 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassHierarchyAnalyzer.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassAnalyzer.java @@ -14,7 +14,7 @@ import static net.orfjackal.retrolambda.util.Flags.*; import static org.objectweb.asm.Opcodes.*; -public class ClassHierarchyAnalyzer { +public class ClassAnalyzer { private final Map classes = new HashMap<>(); private final Map relocatedMethods = new HashMap<>(); @@ -45,10 +45,16 @@ public void visit(int version, int access, String name, String signature, String @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - if (isConstructor(name) || isStaticMethod(access)) { - return null; + int tag; + if (isConstructor(name)) { + tag = H_INVOKESPECIAL; + } else if (isStaticMethod(access)) { + tag = H_INVOKESTATIC; + } else { + tag = H_INVOKEVIRTUAL; } - c.addMethod(new MethodRef(H_INVOKEVIRTUAL, owner, name, desc), new MethodKind.Implemented()); + + c.addMethod(access, new MethodRef(tag, owner, name, desc), new MethodKind.Implemented()); return null; } @@ -71,12 +77,12 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si MethodRef method = new MethodRef(Handles.accessToTag(access, true), owner, name, desc); if (isAbstractMethod(access)) { - c.addMethod(method, new MethodKind.Abstract()); + c.addMethod(access, method, new MethodKind.Abstract()); } else if (isDefaultMethod(access)) { MethodRef defaultImpl = new MethodRef(H_INVOKESTATIC, companion, name, Bytecode.prependArgumentType(desc, Type.getObjectType(owner))); c.enableCompanionClass(); - c.addMethod(method, new MethodKind.Default(defaultImpl)); + c.addMethod(access, method, new MethodKind.Default(defaultImpl)); } else if (isInstanceLambdaImplMethod(access)) { relocatedMethods.put(method, new MethodRef(H_INVOKESTATIC, companion, name, Bytecode.prependArgumentType(desc, Type.getObjectType(owner)))); diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java index 42a9d866..a87c9065 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/ClassInfo.java @@ -44,8 +44,8 @@ public List getMethods() { return Collections.unmodifiableList(methods); } - public void addMethod(MethodRef method, MethodKind kind) { - methods.add(new MethodInfo(method.tag, method.getSignature(), Type.getObjectType(method.owner), kind)); + public void addMethod(int access, MethodRef method, MethodKind kind) { + methods.add(new MethodInfo(access, method.tag, method.getSignature(), Type.getObjectType(method.owner), kind)); } public Optional getCompanionClass() { diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/MethodInfo.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/MethodInfo.java index 9e54789a..0ef55cea 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/MethodInfo.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/MethodInfo.java @@ -11,16 +11,19 @@ public class MethodInfo { + public final int access; public final int tag; public final MethodSignature signature; public final Type owner; public final MethodKind kind; - public MethodInfo(String name, String desc, Class owner, MethodKind kind) { // only for tests, so we can ignore the tag - this(-1, new MethodSignature(name, desc), Type.getType(owner), kind); + public MethodInfo(String name, String desc, Class owner, MethodKind kind) { + // only for tests, so we can ignore the tag and access + this(0, -1, new MethodSignature(name, desc), Type.getType(owner), kind); } - public MethodInfo(int tag, MethodSignature signature, Type owner, MethodKind kind) { + public MethodInfo(int access, int tag, MethodSignature signature, Type owner, MethodKind kind) { + this.access = access; this.tag = tag; this.signature = signature; this.owner = owner; @@ -58,7 +61,7 @@ public String toString() { .addValue(signature) .addValue(owner) .addValue(kind) - .addValue("(" + tag + ")") + .addValue("(tag=" + tag + ", access=" + access + ")") .toString(); } } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/UpdateRelocatedMethodInvocations.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/UpdateRelocatedMethodInvocations.java index 6189e4fd..156e4a10 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/UpdateRelocatedMethodInvocations.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/UpdateRelocatedMethodInvocations.java @@ -11,9 +11,9 @@ public class UpdateRelocatedMethodInvocations extends ClassVisitor { - private final ClassHierarchyAnalyzer analyzer; + private final ClassAnalyzer analyzer; - public UpdateRelocatedMethodInvocations(ClassVisitor next, ClassHierarchyAnalyzer analyzer) { + public UpdateRelocatedMethodInvocations(ClassVisitor next, ClassAnalyzer analyzer) { super(ASM5, next); this.analyzer = analyzer; } diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/BackportLambdaInvocations.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/BackportLambdaInvocations.java index 17ee2cd6..c9e6c639 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/BackportLambdaInvocations.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/BackportLambdaInvocations.java @@ -4,6 +4,7 @@ package net.orfjackal.retrolambda.lambdas; +import net.orfjackal.retrolambda.interfaces.*; import net.orfjackal.retrolambda.util.Bytecode; import org.objectweb.asm.*; @@ -18,10 +19,12 @@ public class BackportLambdaInvocations extends ClassVisitor { private int classAccess; private String className; + private final ClassAnalyzer analyzer; private final Map lambdaAccessToImplMethods = new LinkedHashMap<>(); - public BackportLambdaInvocations(ClassVisitor next) { + public BackportLambdaInvocations(ClassVisitor next, ClassAnalyzer analyzer) { super(ASM5, next); + this.analyzer = analyzer; } @Override @@ -56,13 +59,19 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si Handle getLambdaAccessMethod(Handle implMethod) { if (!implMethod.getOwner().equals(className)) { - return implMethod; - } - if (isInterface(classAccess)) { - // the method will be relocated to a companion class - return implMethod; + if (isNonOwnedMethodVisible(implMethod)) { + return implMethod; + } + } else { + if (isInterface(classAccess)) { + // the method will be relocated to a companion class + return implMethod; + } + if (isOwnedMethodVisible(implMethod)) { + // The method is visible to the companion class and therefore doesn't need an accessor. + return implMethod; + } } - // TODO: do not generate an access method if the impl method is not private (probably not implementable with a single pass) String name = "access$lambda$" + lambdaAccessToImplMethods.size(); String desc = getLambdaAccessMethodDesc(implMethod); Handle accessMethod = new Handle(H_INVOKESTATIC, className, name, desc); @@ -70,6 +79,32 @@ Handle getLambdaAccessMethod(Handle implMethod) { return accessMethod; } + private boolean isOwnedMethodVisible(Handle implMethod) { + MethodSignature implSignature = new MethodSignature(implMethod.getName(), implMethod.getDesc()); + + Collection methods = analyzer.getMethods(Type.getObjectType(implMethod.getOwner())); + for (MethodInfo method : methods) { + if (method.signature.equals(implSignature)) { + // The method will be visible to the companion class if the private flag is absent. + return (method.access & ACC_PRIVATE) == 0; + } + } + throw new IllegalStateException("Non-analyzed method " + implMethod + ". Report this as a bug."); + } + + private boolean isNonOwnedMethodVisible(Handle implMethod) { + MethodSignature implSignature = new MethodSignature(implMethod.getName(), implMethod.getDesc()); + + Collection methods = analyzer.getMethods(Type.getObjectType(implMethod.getOwner())); + for (MethodInfo method : methods) { + if (method.signature.equals(implSignature)) { + // The method will be visible to the companion class if the protected flag is absent. + return (method.access & ACC_PROTECTED) == 0; + } + } + return true; + } + private String getLambdaAccessMethodDesc(Handle implMethod) { if (implMethod.getTag() == H_INVOKESTATIC) { // static method call -> keep as-is diff --git a/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassHierarchyAnalyzerTest.java b/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassAnalyzerTest.java similarity index 89% rename from retrolambda/src/test/java/net/orfjackal/retrolambda/ClassHierarchyAnalyzerTest.java rename to retrolambda/src/test/java/net/orfjackal/retrolambda/ClassAnalyzerTest.java index 79993c74..0b70f713 100644 --- a/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassHierarchyAnalyzerTest.java +++ b/retrolambda/src/test/java/net/orfjackal/retrolambda/ClassAnalyzerTest.java @@ -6,7 +6,7 @@ import com.google.common.io.ByteStreams; import net.orfjackal.retrolambda.interfaces.*; -import org.junit.Test; +import org.junit.*; import org.objectweb.asm.Type; import java.io.*; @@ -21,9 +21,9 @@ import static org.objectweb.asm.Opcodes.*; @SuppressWarnings("UnusedDeclaration") -public class ClassHierarchyAnalyzerTest { +public class ClassAnalyzerTest { - private final ClassHierarchyAnalyzer analyzer = new ClassHierarchyAnalyzer(); + private final ClassAnalyzer analyzer = new ClassAnalyzer(); @Test public void lists_interfaces_and_classes_separately() { @@ -44,13 +44,13 @@ public void abstract_interface_method_inherited_and_implemented() { InterfaceImplementer.class); assertThat("original", analyzer.getMethods(Type.getType(Interface.class)), - containsInAnyOrder(new MethodInfo("abstractMethod", "()V", Interface.class, new MethodKind.Abstract()))); + hasItem(new MethodInfo("abstractMethod", "()V", Interface.class, new MethodKind.Abstract()))); assertThat("inherits unchanged", analyzer.getMethods(Type.getType(ChildInterface.class)), - containsInAnyOrder(new MethodInfo("abstractMethod", "()V", Interface.class, new MethodKind.Abstract()))); + hasItem(new MethodInfo("abstractMethod", "()V", Interface.class, new MethodKind.Abstract()))); assertThat("implements", analyzer.getMethods(Type.getType(InterfaceImplementer.class)), - containsInAnyOrder(new MethodInfo("abstractMethod", "()V", InterfaceImplementer.class, new MethodKind.Implemented()))); + hasItem(new MethodInfo("abstractMethod", "()V", InterfaceImplementer.class, new MethodKind.Implemented()))); } private interface Interface { @@ -72,10 +72,10 @@ public void interface_method_types() { analyze(InterfaceMethodTypes.class); assertThat(analyzer.getMethods(Type.getType(InterfaceMethodTypes.class)), - containsInAnyOrder( + hasItems( new MethodInfo("abstractMethod", "()V", InterfaceMethodTypes.class, new MethodKind.Abstract()), new MethodInfo("defaultMethod", "()V", InterfaceMethodTypes.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, InterfaceMethodTypes$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$InterfaceMethodTypes;)V"))))); + new MethodRef(H_INVOKESTATIC, InterfaceMethodTypes$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$InterfaceMethodTypes;)V"))))); } @Test @@ -85,7 +85,7 @@ public void class_method_types() { // An abstract instance method takes precedence over a default method, // so we handle abstract instance methods the same way as concrete instance methods. assertThat(analyzer.getMethods(Type.getType(ClassMethodTypes.class)), - containsInAnyOrder( + hasItems( new MethodInfo("abstractMethod", "()V", ClassMethodTypes.class, new MethodKind.Implemented()), new MethodInfo("instanceMethod", "()V", ClassMethodTypes.class, new MethodKind.Implemented()))); } @@ -125,19 +125,19 @@ public void default_method_overridden_and_abstracted() { containsInAnyOrder( new MethodInfo("abstractMethod", "()V", HasDefaultMethods.class, new MethodKind.Abstract()), new MethodInfo("defaultMethod", "()V", HasDefaultMethods.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, HasDefaultMethods$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$HasDefaultMethods;)V"))))); + new MethodRef(H_INVOKESTATIC, HasDefaultMethods$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$HasDefaultMethods;)V"))))); assertThat("inherits unchanged", analyzer.getMethods(Type.getType(DoesNotOverrideDefaultMethods.class)), containsInAnyOrder( new MethodInfo("abstractMethod", "()V", HasDefaultMethods.class, new MethodKind.Abstract()), new MethodInfo("defaultMethod", "()V", HasDefaultMethods.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, HasDefaultMethods$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$HasDefaultMethods;)V"))))); + new MethodRef(H_INVOKESTATIC, HasDefaultMethods$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$HasDefaultMethods;)V"))))); assertThat("changes default impl", analyzer.getMethods(Type.getType(OverridesDefaultMethods.class)), containsInAnyOrder( new MethodInfo("abstractMethod", "()V", HasDefaultMethods.class, new MethodKind.Abstract()), new MethodInfo("defaultMethod", "()V", OverridesDefaultMethods.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, OverridesDefaultMethods$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$OverridesDefaultMethods;)V"))))); + new MethodRef(H_INVOKESTATIC, OverridesDefaultMethods$.class, "defaultMethod", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$OverridesDefaultMethods;)V"))))); assertThat("makes abstract", analyzer.getMethods(Type.getType(AbstractsDefaultMethods.class)), containsInAnyOrder( @@ -179,11 +179,11 @@ public void superclass_inheritance() { ChildClass.class); assertThat("original", analyzer.getMethods(Type.getType(BaseClass.class)), - containsInAnyOrder( + hasItem( new MethodInfo("baseMethod", "()V", BaseClass.class, new MethodKind.Implemented()))); assertThat("inherits unchanged", analyzer.getMethods(Type.getType(ChildClass.class)), - containsInAnyOrder( + hasItem( new MethodInfo("baseMethod", "()V", BaseClass.class, new MethodKind.Implemented()))); } @@ -205,25 +205,25 @@ public void overriding_default_methods() { InheritsOverridesDefaultAndDirectlyImplements.class); assertThat("original", analyzer.getMethods(Type.getType(DefaultMethods.class)), - containsInAnyOrder( + hasItem( new MethodInfo("foo", "()V", DefaultMethods.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, DefaultMethods$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$DefaultMethods;)V"))))); + new MethodRef(H_INVOKESTATIC, DefaultMethods$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$DefaultMethods;)V"))))); assertThat("inherits unchanged", analyzer.getMethods(Type.getType(InheritsDefault.class)), - containsInAnyOrder( + hasItem( new MethodInfo("foo", "()V", DefaultMethods.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, DefaultMethods$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$DefaultMethods;)V"))))); + new MethodRef(H_INVOKESTATIC, DefaultMethods$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$DefaultMethods;)V"))))); assertThat("overrides", analyzer.getMethods(Type.getType(OverridesDefault.class)), - containsInAnyOrder( + hasItem( new MethodInfo("foo", "()V", OverridesDefault.class, new MethodKind.Implemented()))); assertThat("inherits overridden", analyzer.getMethods(Type.getType(InheritsOverridesDefault.class)), - containsInAnyOrder( + hasItem( new MethodInfo("foo", "()V", OverridesDefault.class, new MethodKind.Implemented()))); assertThat("inherits overridden", analyzer.getMethods(Type.getType(InheritsOverridesDefaultAndDirectlyImplements.class)), - containsInAnyOrder( + hasItem( new MethodInfo("foo", "()V", OverridesDefault.class, new MethodKind.Implemented()))); } @@ -261,9 +261,9 @@ public void inheriting_same_default_methods_through_many_parent_interfaces() { InheritsOriginalAndOverridden.class); MethodInfo original = new MethodInfo("foo", "()V", SuperOriginal.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, SuperOriginal$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$SuperOriginal;)V"))); + new MethodRef(H_INVOKESTATIC, SuperOriginal$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$SuperOriginal;)V"))); MethodInfo overridden = new MethodInfo("foo", "()V", SuperOverridden.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, SuperOverridden$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$SuperOverridden;)V"))); + new MethodRef(H_INVOKESTATIC, SuperOverridden$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$SuperOverridden;)V"))); assertThat("inherits original", analyzer.getMethods(Type.getType(InheritsOriginal.class)), containsInAnyOrder(original)); @@ -315,18 +315,18 @@ public void implements_original_and_overridden_default_method() { ExtendsImplementsOriginalAndImplementsOverriddenDefault.class); MethodInfo original = new MethodInfo("foo", "()V", OriginalDefault.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, OriginalDefault$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$OriginalDefault;)V"))); + new MethodRef(H_INVOKESTATIC, OriginalDefault$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$OriginalDefault;)V"))); MethodInfo overridden = new MethodInfo("foo", "()V", OverriddenDefault.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, OverriddenDefault$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$OverriddenDefault;)V"))); + new MethodRef(H_INVOKESTATIC, OverriddenDefault$.class, "foo", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$OverriddenDefault;)V"))); assertThat("implements original", analyzer.getMethods(Type.getType(ImplementsOriginal.class)), - containsInAnyOrder(original)); + hasItem(original)); assertThat("implements original and overridden", analyzer.getMethods(Type.getType(ImplementsOriginalAndOverriddenDefault.class)), - containsInAnyOrder(overridden)); + hasItem(overridden)); assertThat("implements overridden and original", analyzer.getMethods(Type.getType(ImplementsOverriddenAndOriginalDefault.class)), - containsInAnyOrder(overridden)); + hasItem(overridden)); assertThat("extends implementor of original and implements overridden", analyzer.getMethods(Type.getType(ExtendsImplementsOriginalAndImplementsOverriddenDefault.class)), - containsInAnyOrder(overridden)); + hasItem(overridden)); } private interface OriginalDefault { @@ -365,13 +365,13 @@ public void default_methods_with_lambdas() { ImplementsUsesLambdas.class); MethodInfo stateless = new MethodInfo("stateless", "()Ljava/util/concurrent/Callable;", UsesLambdas.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, UsesLambdas$.class, "stateless", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$UsesLambdas;)Ljava/util/concurrent/Callable;"))); + new MethodRef(H_INVOKESTATIC, UsesLambdas$.class, "stateless", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$UsesLambdas;)Ljava/util/concurrent/Callable;"))); MethodInfo captureThis = new MethodInfo("captureThis", "()Ljava/util/concurrent/Callable;", UsesLambdas.class, new MethodKind.Default( - new MethodRef(H_INVOKESTATIC, UsesLambdas$.class, "captureThis", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$UsesLambdas;)Ljava/util/concurrent/Callable;"))); + new MethodRef(H_INVOKESTATIC, UsesLambdas$.class, "captureThis", "(Lnet/orfjackal/retrolambda/ClassAnalyzerTest$UsesLambdas;)Ljava/util/concurrent/Callable;"))); assertThat("does not copy instance lambda impl methods to implementers", analyzer.getMethods(Type.getType(ImplementsUsesLambdas.class)), - containsInAnyOrder(stateless, captureThis)); + hasItems(stateless, captureThis)); } private interface UsesLambdas { @@ -537,13 +537,13 @@ private static String voidMethod(Class... argumentTypes) { private static List> infosToClasses(List classes) { return classes.stream() - .map(ClassHierarchyAnalyzerTest::toClass) + .map(ClassAnalyzerTest::toClass) .collect(toList()); } private static List> typesToClasses(List types) { return types.stream() - .map(ClassHierarchyAnalyzerTest::toClass) + .map(ClassAnalyzerTest::toClass) .collect(toList()); }