aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
diff options
context:
space:
mode:
authorGravatar kmb <kmb@google.com>2017-04-27 21:02:32 +0200
committerGravatar Vladimir Moskva <vladmos@google.com>2017-04-28 01:03:04 +0200
commit11e976972c4f35829e630cf69c7563ca40b7b9bf (patch)
tree1611a9c848cfdace1c4fd454c3de6e1002507880 /src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java
parent8e753330168250677f63d07aa6395276c8e097ab (diff)
Don't copy lambda bodies from interfaces into implementing classes.
RELNOTES: none PiperOrigin-RevId: 154452158
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java22
1 files changed, 16 insertions, 6 deletions
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 8ad5dc285b..732f064bf5 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
@@ -132,6 +132,19 @@ public class DefaultMethodClassFixer extends ClassVisitor {
return false;
}
+ /**
+ * Returns {@code true} for non-bridge default methods not in {@link #instanceMethods}.
+ */
+ private boolean shouldStub(int access, String name, String desc) {
+ // Ignore private methods, which technically aren't default methods and can only be called from
+ // other methods defined in the interface. This also ignores lambda body methods, which is fine
+ // as we don't want or need to stub those. Also ignore bridge methods as javac adds them to
+ // concrete classes as needed anyway and we handle them separately for generated lambda classes.
+ return BitFlags.noneSet(access,
+ Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_PRIVATE)
+ && !instanceMethods.contains(name + ":" + desc);
+ }
+
private void stubMissingDefaultMethods(ImmutableList<String> interfaces) {
for (String implemented : interfaces) {
if (!seenInterfaces.add(implemented)) {
@@ -183,12 +196,10 @@ public class DefaultMethodClassFixer extends ClassVisitor {
@Override
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
- if (BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE)
- && !instanceMethods.contains(name + ":" + desc)) {
+ if (shouldStub(access, name, desc)) {
// 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
- // ACC_SYNTHETIC modifier, so don't. Don't do this for bridge methods, which we handle
- // separately.
+ // ACC_SYNTHETIC modifier, so don't.
// Signatures can be wrong, e.g., when type variables are introduced, instantiated, or
// refined in the class we're processing, so drop them.
MethodVisitor stubMethod =
@@ -255,8 +266,7 @@ public class DefaultMethodClassFixer extends ClassVisitor {
@Override
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
- if (BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE)
- && !instanceMethods.contains(name + ":" + desc)) {
+ if (!found && shouldStub(access, name, desc)) {
// Found a default method we're not ignoring (instanceMethods at this point contains methods
// the top-level visited class implements itself).
found = true;