diff options
author | kmb <kmb@google.com> | 2017-04-27 21:02:32 +0200 |
---|---|---|
committer | Vladimir Moskva <vladmos@google.com> | 2017-04-28 01:03:04 +0200 |
commit | 11e976972c4f35829e630cf69c7563ca40b7b9bf (patch) | |
tree | 1611a9c848cfdace1c4fd454c3de6e1002507880 /src/tools/android/java/com/google | |
parent | 8e753330168250677f63d07aa6395276c8e097ab (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')
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/desugar/DefaultMethodClassFixer.java | 22 |
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; |