Skip to content

Commit

Permalink
Walking skeleton for handling instance lambda impl methods in interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
luontola committed Apr 14, 2015
1 parent fe6c8e5 commit 8ce0fff
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
c.enableCompanionClass();
c.addMethod(method, new MethodKind.Default(defaultImpl));

} else if (isInstanceLambdaImplMethod(access)) {
relocatedMethods.put(method, new MethodRef(companion, name, Bytecode.prependArgumentType(desc, Type.getObjectType(owner))));
c.enableCompanionClass();

} else if (isStaticMethod(access)) {
relocatedMethods.put(method, new MethodRef(companion, name, desc));
c.enableCompanionClass();
Expand All @@ -99,7 +103,22 @@ private static boolean isStaticMethod(int access) {

private static boolean isDefaultMethod(int access) {
return !isAbstractMethod(access)
&& !isStaticMethod(access);
&& !isStaticMethod(access)
&& isPublicMethod(access);
}

private static boolean isInstanceLambdaImplMethod(int access) {
return !isAbstractMethod(access)
&& !isStaticMethod(access)
&& isPrivateMethod(access);
}

private static boolean isPublicMethod(int access) {
return Flags.hasFlag(access, ACC_PUBLIC);
}

private static boolean isPrivateMethod(int access) {
return Flags.hasFlag(access, ACC_PRIVATE);
}

public List<ClassInfo> getInterfaces() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
opcode = Opcodes.INVOKESTATIC;
method = impl;
}
if (name.startsWith("lambda$captureThis$")) { // FIXME: remove me
opcode = Opcodes.INVOKESTATIC;
}
}

method = analyzer.getMethodCallTarget(method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import java.io.*;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Stream;

import static java.util.Arrays.asList;
Expand Down Expand Up @@ -357,6 +358,38 @@ private class ExtendsImplementsOriginalAndImplementsOverriddenDefault extends Im
}


@Test
public void default_methods_with_lambdas() {
analyze(UsesLambdas.class,
ImplementsUsesLambdas.class);

MethodInfo stateless = new MethodInfo("stateless", "()Ljava/util/concurrent/Callable;", UsesLambdas.class, new MethodKind.Default(
new MethodRef(UsesLambdas$.class, "stateless", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$UsesLambdas;)Ljava/util/concurrent/Callable;")));
MethodInfo captureThis = new MethodInfo("captureThis", "()Ljava/util/concurrent/Callable;", UsesLambdas.class, new MethodKind.Default(
new MethodRef(UsesLambdas$.class, "captureThis", "(Lnet/orfjackal/retrolambda/ClassHierarchyAnalyzerTest$UsesLambdas;)Ljava/util/concurrent/Callable;")));

assertThat("does not copy instance lambda impl methods to implementers",
analyzer.getMethods(Type.getType(ImplementsUsesLambdas.class)),
containsInAnyOrder(stateless, captureThis));
}

private interface UsesLambdas {
default Callable<String> stateless() {
return () -> "foo";
}

default Callable<String> captureThis() {
return () -> stateless().call();
}
}

private interface UsesLambdas$ {
}

private class ImplementsUsesLambdas implements UsesLambdas {
}


// Method relocations

@Test
Expand Down

0 comments on commit 8ce0fff

Please sign in to comment.