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-08-02 23:48:22 +0200
committerGravatar Dmitry Lomov <dslomov@google.com>2017-08-03 12:10:01 +0200
commit78105ee42f9caf62492b69a8455bb42f7acef407 (patch)
tree3a58a5425accc6c5ca0d9c5795064a0ab47a6c45 /src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java
parentc13bb39f78de5e016c9ec1e3e20c43a92ea7d159 (diff)
Tolerate missing interface markers in method calls from interface methods to methods in that interface.
RELNOTES: none PiperOrigin-RevId: 164041648
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.java27
1 files changed, 14 insertions, 13 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 f7621dfcc0..97135cf2b4 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
@@ -180,7 +180,8 @@ class InterfaceDesugaring extends ClassVisitor {
result = super.visitMethod(access, name, desc, signature, exceptions);
}
return result != null
- ? new InterfaceInvocationRewriter(result, internalName, bootclasspath)
+ ? new InterfaceInvocationRewriter(
+ result, isInterface() ? internalName : null, bootclasspath)
: null;
}
@@ -277,29 +278,32 @@ class InterfaceDesugaring extends ClassVisitor {
*/
static class InterfaceInvocationRewriter extends MethodVisitor {
- private final String internalName;
+ /**
+ * If we're visiting a method declared in an interface, the internal name of that interface.
+ * That lets us rewrite invocations of other methods within that interface even if the bytecode
+ * fails to indicate them as interface method invocations, as older versions of JaCoCo failed to
+ * do (b/62623509).
+ */
+ @Nullable private final String interfaceName;
private final ClassReaderFactory bootclasspath;
public InterfaceInvocationRewriter(
- MethodVisitor dest, String internalName, ClassReaderFactory bootclasspath) {
+ MethodVisitor dest, @Nullable String knownInterfaceName, ClassReaderFactory bootclasspath) {
super(Opcodes.ASM5, dest);
- this.internalName = internalName;
+ this.interfaceName = knownInterfaceName;
this.bootclasspath = bootclasspath;
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
// Assume that any static interface methods on the classpath are moved
- if (itf) {
+ if (itf || owner.equals(interfaceName)) {
boolean isLambda = name.startsWith("lambda$");
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),
- "%s shouldn't consider %s an interface",
- internalName,
- owner);
+ !owner.endsWith(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;
@@ -325,10 +329,7 @@ class InterfaceDesugaring extends ClassVisitor {
} else if ((opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL)
&& !bootclasspath.isKnown(owner)) {
checkArgument(
- !owner.endsWith(COMPANION_SUFFIX),
- "%s shouldn't consider %s an interface",
- internalName,
- owner);
+ !owner.endsWith(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;