aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
diff options
context:
space:
mode:
authorGravatar kmb <kmb@google.com>2017-10-03 02:14:25 +0200
committerGravatar Klaus Aehlig <aehlig@google.com>2017-10-06 19:42:37 +0200
commitbdb12ceeb7c23d7d2293e8006d0aa7127a91b973 (patch)
tree6b2a83baa22f5a8523fe33fb3706932e5c37d0b2 /src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
parent36e2a1c80c0d2bd4455c960833c27b19c0cb6586 (diff)
add flags to desugar to emit metadata that can be used for double-checking correctness of default and static interface desugaring.
RELNOTES: none PiperOrigin-RevId: 170779637
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java40
1 files changed, 29 insertions, 11 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java b/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
index 6bac9edb26..0f03236e72 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
@@ -42,9 +42,9 @@ class InterfaceDesugaring extends ClassVisitor {
static final String COMPANION_METHOD_TO_TRIGGER_INTERFACE_CLINIT_NAME = "$$triggerInterfaceInit";
static final String COMPANION_METHOD_TO_TRIGGER_INTERFACE_CLINIT_DESC = "()V";
- static final String COMPANION_SUFFIX = "$$CC";
static final String INTERFACE_STATIC_COMPANION_METHOD_SUFFIX = "$$STATIC$$";
+ private final DependencyCollector depsCollector;
private final ClassReaderFactory bootclasspath;
private final GeneratedClassStore store;
private final boolean legacyJaCoCo;
@@ -52,13 +52,18 @@ class InterfaceDesugaring extends ClassVisitor {
private String internalName;
private int bytecodeVersion;
private int accessFlags;
+ private int numberOfDefaultMethods;
@Nullable private ClassVisitor companion;
@Nullable private FieldInfo interfaceFieldToAccessInCompanionMethodToTriggerInterfaceClinit;
public InterfaceDesugaring(
- ClassVisitor dest, ClassReaderFactory bootclasspath, GeneratedClassStore store,
+ ClassVisitor dest,
+ DependencyCollector depsCollector,
+ ClassReaderFactory bootclasspath,
+ GeneratedClassStore store,
boolean legacyJaCoCo) {
super(Opcodes.ASM5, dest);
+ this.depsCollector = depsCollector;
this.bootclasspath = bootclasspath;
this.store = store;
this.legacyJaCoCo = legacyJaCoCo;
@@ -73,15 +78,26 @@ class InterfaceDesugaring extends ClassVisitor {
String superName,
String[] interfaces) {
companion = null;
+ numberOfDefaultMethods = 0;
internalName = name;
bytecodeVersion = version;
accessFlags = access;
+ if (isInterface()) {
+ // Record interface hierarchy. This helps avoid parsing .class files when double-checking
+ // desugaring results later using collected dependency information.
+ depsCollector.recordExtendedInterfaces(name, interfaces);
+ }
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitEnd() {
if (companion != null) {
+ // Record classes with default methods. This increases precision when double-checking
+ // desugaring results later, without parsing .class files again, compared to just looking
+ // for companion classes in a given desugared Jar which may only contain static methods.
+ depsCollector.recordDefaultMethods(internalName, numberOfDefaultMethods);
+
// Emit a method to access the fields of the interfaces that need initialization.
emitInterfaceFieldAccessInCompanionMethodToTriggerInterfaceClinit();
companion.visitEnd();
@@ -185,6 +201,7 @@ class InterfaceDesugaring extends ClassVisitor {
name,
internalName,
desc);
+ ++numberOfDefaultMethods;
abstractDest =
super.visitMethod(access | Opcodes.ACC_ABSTRACT, name, desc, signature, exceptions);
}
@@ -228,7 +245,7 @@ class InterfaceDesugaring extends ClassVisitor {
// Rename lambda method to reflect the new owner. Not doing so confuses LambdaDesugaring
// if it's run over this class again. LambdaDesugaring has already renamed the method from
// its original name to include the interface name at this point.
- suffix = COMPANION_SUFFIX;
+ suffix = DependencyCollector.INTERFACE_COMPANION_SUFFIX;
} else if (isStatic) {
suffix = INTERFACE_STATIC_COMPANION_METHOD_SUFFIX;
} else {
@@ -238,7 +255,7 @@ class InterfaceDesugaring extends ClassVisitor {
}
static String getCompanionClassName(String interfaceName) {
- return interfaceName + COMPANION_SUFFIX;
+ return interfaceName + DependencyCollector.INTERFACE_COMPANION_SUFFIX;
}
/**
@@ -329,8 +346,8 @@ class InterfaceDesugaring extends ClassVisitor {
name = normalizeInterfaceMethodName(name, isLambda, opcode == Opcodes.INVOKESTATIC);
if (isLambda) {
// Redirect lambda invocations to completely remove all lambda methods from interfaces.
- checkArgument(
- !owner.endsWith(COMPANION_SUFFIX), "shouldn't consider %s an interface", owner);
+ checkArgument(!owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
+ "shouldn't consider %s an interface", owner);
checkArgument(!bootclasspath.isKnown(owner)); // must be in current input
if (opcode == Opcodes.INVOKEINTERFACE) {
opcode = Opcodes.INVOKESTATIC;
@@ -344,7 +361,7 @@ class InterfaceDesugaring extends ClassVisitor {
name);
}
// Reflect that InterfaceDesugaring moves and renames the lambda body method
- owner += COMPANION_SUFFIX;
+ owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
String expectedLambdaMethodName = LambdaDesugaring.uniqueInPackage(owner, name);
checkState(
name.equals(expectedLambdaMethodName),
@@ -355,14 +372,14 @@ class InterfaceDesugaring extends ClassVisitor {
itf = false;
} else if ((opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL)
&& !bootclasspath.isKnown(owner)) {
- checkArgument(
- !owner.endsWith(COMPANION_SUFFIX), "shouldn't consider %s an interface", owner);
+ checkArgument(!owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
+ "shouldn't consider %s an interface", owner);
if (opcode == Opcodes.INVOKESPECIAL) {
// Turn Interface.super.m() into Interface$$CC.m(receiver)
opcode = Opcodes.INVOKESTATIC;
desc = companionDefaultMethodDescriptor(owner, desc);
}
- owner += COMPANION_SUFFIX;
+ owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
itf = false;
}
}
@@ -384,7 +401,8 @@ class InterfaceDesugaring extends ClassVisitor {
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if ("$jacocoData".equals(name)) {
- checkState(!owner.endsWith(COMPANION_SUFFIX), "Expected interface: %s", owner);
+ checkState(!owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
+ "Expected interface: %s", owner);
owner = getCompanionClassName(owner);
}
super.visitFieldInsn(opcode, owner, name, desc);