aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar kmb <kmb@google.com>2017-10-23 21:35:37 +0200
committerGravatar Dmitry Lomov <dslomov@google.com>2017-10-24 10:39:48 +0200
commita01493b751fa1a31e1cef929b36ee030402909fa (patch)
treeb895cc3644c749930e578f49f2a01cc9bfef1897 /src
parentcbb33478b223a424edfe95fca329e5ab9afa8127 (diff)
Record dependencies when directly calling moved interface methods.
RELNOTES: None. PiperOrigin-RevId: 173154512
Diffstat (limited to 'src')
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethod.java21
-rw-r--r--src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethodCaller.java21
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java20
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/InterfaceDesugaring.java23
4 files changed, 72 insertions, 13 deletions
diff --git a/src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethod.java b/src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethod.java
new file mode 100644
index 0000000000..7815a73657
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethod.java
@@ -0,0 +1,21 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.android.desugar.testdata.b68049457;
+
+/** Interface declaring a static method for regression test for b/68049457. */
+public interface StaticInterfaceMethod {
+ static String never() {
+ throw new IllegalStateException("can't get here");
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethodCaller.java b/src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethodCaller.java
new file mode 100644
index 0000000000..f961d96750
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/desugar/testdata/b68049457/StaticInterfaceMethodCaller.java
@@ -0,0 +1,21 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.android.desugar.testdata.b68049457;
+
+/** Class calling static interface method for regression test for b/68049457. */
+public class StaticInterfaceMethodCaller {
+ public String callIt() {
+ return StaticInterfaceMethod.never();
+ }
+}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java b/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
index 2d89e8b2b1..cf904a49dd 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
@@ -385,7 +385,7 @@ public class DefaultMethodClassFixer extends ClassVisitor {
*/
private class DefaultMethodStubber extends ClassVisitor {
- private String interfaceName;
+ private String stubbedInterfaceName;
public DefaultMethodStubber() {
super(Opcodes.ASM5);
@@ -400,8 +400,8 @@ public class DefaultMethodClassFixer extends ClassVisitor {
String superName,
String[] interfaces) {
checkArgument(BitFlags.isSet(access, Opcodes.ACC_INTERFACE));
- checkState(interfaceName == null);
- interfaceName = name;
+ checkState(stubbedInterfaceName == null);
+ stubbedInterfaceName = name;
}
@Override
@@ -414,7 +414,7 @@ public class DefaultMethodClassFixer extends ClassVisitor {
// methods redefined in interfaces extending another.
recordIfInstanceMethod(access, name, desc);
depsCollector.assumeCompanionClass(
- internalName, InterfaceDesugaring.getCompanionClassName(interfaceName));
+ internalName, InterfaceDesugaring.getCompanionClassName(stubbedInterfaceName));
// Add this method to the class we're desugaring and stub in a body to call the default
// implementation in the interface's companion class. ijar omits these methods when setting
@@ -433,9 +433,9 @@ public class DefaultMethodClassFixer extends ClassVisitor {
}
stubMethod.visitMethodInsn(
Opcodes.INVOKESTATIC,
- InterfaceDesugaring.getCompanionClassName(interfaceName),
+ InterfaceDesugaring.getCompanionClassName(stubbedInterfaceName),
name,
- InterfaceDesugaring.companionDefaultMethodDescriptor(interfaceName, desc),
+ InterfaceDesugaring.companionDefaultMethodDescriptor(stubbedInterfaceName, desc),
/*itf*/ false);
stubMethod.visitInsn(neededType.getReturnType().getOpcode(Opcodes.IRETURN));
@@ -444,15 +444,15 @@ public class DefaultMethodClassFixer extends ClassVisitor {
return null;
} else if (shouldStubAsBridgeDefaultMethod(access, name, desc)) {
recordIfInstanceMethod(access, name, desc);
- depsCollector.assumeCompanionClass(
- internalName, InterfaceDesugaring.getCompanionClassName(interfaceName));
// For bridges we just copy their bodies instead of going through the companion class.
// Meanwhile, we also need to desugar the copied method bodies, so that any calls to
// interface methods are correctly handled.
return new InterfaceDesugaring.InterfaceInvocationRewriter(
DefaultMethodClassFixer.this.visitMethod(access, name, desc, (String) null, exceptions),
- interfaceName,
- bootclasspath);
+ stubbedInterfaceName,
+ bootclasspath,
+ depsCollector,
+ internalName);
} else {
return null; // we don't care about the actual code in these methods
}
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 9371d60f51..d7e3886641 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
@@ -160,6 +160,7 @@ class InterfaceDesugaring extends ClassVisitor {
@Override
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
+ String codeOwner = internalName;
MethodVisitor result;
if (isInterface() && isStaticInitializer(name)) {
result =
@@ -180,6 +181,8 @@ class InterfaceDesugaring extends ClassVisitor {
name =
normalizeInterfaceMethodName(
name, isLambdaBody, BitFlags.isSet(access, Opcodes.ACC_STATIC));
+ codeOwner = getCompanionClassName(internalName);
+
if (BitFlags.isSet(access, Opcodes.ACC_STATIC)) {
// Completely move static interface methods, which requires rewriting call sites
result =
@@ -226,7 +229,7 @@ class InterfaceDesugaring extends ClassVisitor {
}
return result != null
? new InterfaceInvocationRewriter(
- result, isInterface() ? internalName : null, bootclasspath)
+ result, isInterface() ? internalName : null, bootclasspath, depsCollector, codeOwner)
: null;
}
@@ -330,12 +333,21 @@ class InterfaceDesugaring extends ClassVisitor {
@Nullable private final String interfaceName;
private final ClassReaderFactory bootclasspath;
+ private final DependencyCollector depsCollector;
+ /** Internal name that'll be used to record any dependencies on interface methods. */
+ private final String declaringClass;
public InterfaceInvocationRewriter(
- MethodVisitor dest, @Nullable String knownInterfaceName, ClassReaderFactory bootclasspath) {
+ MethodVisitor dest,
+ @Nullable String knownInterfaceName,
+ ClassReaderFactory bootclasspath,
+ DependencyCollector depsCollector,
+ String declaringClass) {
super(Opcodes.ASM5, dest);
this.interfaceName = knownInterfaceName;
this.bootclasspath = bootclasspath;
+ this.depsCollector = depsCollector;
+ this.declaringClass = declaringClass;
}
@Override
@@ -361,6 +373,10 @@ class InterfaceDesugaring extends ClassVisitor {
}
// Reflect that InterfaceDesugaring moves and renames the lambda body method
owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
+ itf = false;
+ // Record dependency on companion class
+ depsCollector.assumeCompanionClass(declaringClass, owner);
+
String expectedLambdaMethodName = LambdaDesugaring.uniqueInPackage(owner, name);
checkState(
name.equals(expectedLambdaMethodName),
@@ -368,7 +384,6 @@ class InterfaceDesugaring extends ClassVisitor {
owner,
name,
expectedLambdaMethodName);
- itf = false;
} else if ((opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL)) {
checkArgument(!owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
"shouldn't consider %s an interface", owner);
@@ -379,6 +394,8 @@ class InterfaceDesugaring extends ClassVisitor {
}
owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
itf = false;
+ // Record dependency on companion class
+ depsCollector.assumeCompanionClass(declaringClass, owner);
}
}
super.visitMethodInsn(opcode, owner, name, desc, itf);