Reland "Do not rewrite generic signatures in target of merged classes"
This reverts commit ceac696c81a3a23a960ebd0acb4992019c29e053.
Bug: 147386014
Change-Id: I55e5b7a6ffcc23188e7c631d577f0ca824cd093e
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index d0240e9..d13cc3b 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
@@ -24,12 +25,14 @@
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
+import com.android.tools.r8.utils.IteratorUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -132,7 +135,15 @@
timing.end();
timing.begin("rename-generic");
- new GenericSignatureRewriter(appView, renaming).run(classes);
+ new GenericSignatureRewriter(appView, renaming)
+ .run(
+ new Iterable<DexProgramClass>() {
+ @Override
+ public Iterator<DexProgramClass> iterator() {
+ return IteratorUtils.<DexClass, DexProgramClass>filter(
+ classes.iterator(), DexClass::isProgramClass);
+ }
+ });
timing.end();
timing.begin("rename-arrays");
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureAction.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureAction.java
index 6753e06..7cb3506 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureAction.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureAction.java
@@ -9,11 +9,17 @@
*/
public interface GenericSignatureAction<T> {
+ enum ParserPosition {
+ CLASS_SUPER_OR_INTERFACE_ANNOTATION,
+ ENCLOSING_INNER_OR_TYPE_ANNOTATION,
+ MEMBER_ANNOTATION
+ }
+
public void parsedSymbol(char symbol);
public void parsedIdentifier(String identifier);
- public T parsedTypeName(String name);
+ public T parsedTypeName(String name, ParserPosition isTopLevel);
public T parsedInnerTypeName(T enclosingType, String name);
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
index c1f6a7d..dc0aa8c 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.naming.signature;
+import com.android.tools.r8.naming.signature.GenericSignatureAction.ParserPosition;
import java.lang.reflect.GenericSignatureFormatError;
import java.nio.CharBuffer;
@@ -50,7 +51,7 @@
*/
public class GenericSignatureParser<T> {
- private final GenericSignatureAction<T> actions;
+ private GenericSignatureAction<T> actions;
/*
* Parser:
@@ -110,7 +111,7 @@
try {
actions.start();
setInput(signature);
- parseFieldTypeSignature();
+ parseFieldTypeSignature(ParserPosition.MEMBER_ANNOTATION);
actions.stop();
} catch (GenericSignatureFormatError e) {
throw e;
@@ -141,11 +142,11 @@
parseOptFormalTypeParameters();
// SuperclassSignature ::= ClassTypeSignature.
- parseClassTypeSignature();
+ parseClassTypeSignature(ParserPosition.CLASS_SUPER_OR_INTERFACE_ANNOTATION);
while (symbol > 0) {
// SuperinterfaceSignature ::= ClassTypeSignature.
- parseClassTypeSignature();
+ parseClassTypeSignature(ParserPosition.CLASS_SUPER_OR_INTERFACE_ANNOTATION);
}
}
@@ -178,28 +179,28 @@
expect(':');
if (symbol == 'L' || symbol == '[' || symbol == 'T') {
- parseFieldTypeSignature();
+ parseFieldTypeSignature(ParserPosition.MEMBER_ANNOTATION);
}
while (symbol == ':') {
// InterfaceBound ::= ":" FieldTypeSignature.
actions.parsedSymbol(symbol);
scanSymbol();
- parseFieldTypeSignature();
+ parseFieldTypeSignature(ParserPosition.MEMBER_ANNOTATION);
}
}
- private void parseFieldTypeSignature() {
+ private void parseFieldTypeSignature(ParserPosition parserPosition) {
// FieldTypeSignature ::= ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature.
switch (symbol) {
case 'L':
- parseClassTypeSignature();
+ parseClassTypeSignature(parserPosition);
break;
case '[':
- // ArrayTypeSignature ::= "[" TypSignature.
+ // ArrayTypeSignature ::= "[" TypeSignature.
actions.parsedSymbol(symbol);
scanSymbol();
- updateTypeSignature();
+ updateTypeSignature(parserPosition);
break;
case 'T':
updateTypeVariableSignature();
@@ -209,7 +210,7 @@
}
}
- private void parseClassTypeSignature() {
+ private void parseClassTypeSignature(ParserPosition parserPosition) {
// ClassTypeSignature ::= "L" {Ident "/"} Ident OptTypeArguments {"." Ident OptTypeArguments}
// ";".
actions.parsedSymbol(symbol);
@@ -226,18 +227,22 @@
}
qualIdent.append(this.identifier);
- T parsedEnclosingType = actions.parsedTypeName(qualIdent.toString());
+ T parsedEnclosingType = actions.parsedTypeName(qualIdent.toString(), parserPosition);
- updateOptTypeArguments();
-
- while (symbol == '.') {
- // Deal with Member Classes:
- actions.parsedSymbol(symbol);
- scanSymbol();
- scanIdentifier();
- assert identifier != null;
- parsedEnclosingType = actions.parsedInnerTypeName(parsedEnclosingType, identifier);
+ if (parsedEnclosingType != null) {
+ // We should only parse any optional type arguments and member classes if we have not merged
+ // the class into the current subtype.
updateOptTypeArguments();
+
+ while (symbol == '.') {
+ // Deal with Member Classes.
+ actions.parsedSymbol(symbol);
+ scanSymbol();
+ scanIdentifier();
+ assert identifier != null;
+ parsedEnclosingType = actions.parsedInnerTypeName(parsedEnclosingType, identifier);
+ updateOptTypeArguments();
+ }
}
actions.parsedSymbol(symbol);
@@ -268,13 +273,13 @@
} else if (symbol == '+') {
actions.parsedSymbol(symbol);
scanSymbol();
- parseFieldTypeSignature();
+ parseFieldTypeSignature(ParserPosition.ENCLOSING_INNER_OR_TYPE_ANNOTATION);
} else if (symbol == '-') {
actions.parsedSymbol(symbol);
scanSymbol();
- parseFieldTypeSignature();
+ parseFieldTypeSignature(ParserPosition.ENCLOSING_INNER_OR_TYPE_ANNOTATION);
} else {
- parseFieldTypeSignature();
+ parseFieldTypeSignature(ParserPosition.ENCLOSING_INNER_OR_TYPE_ANNOTATION);
}
}
@@ -291,7 +296,7 @@
expect(';');
}
- private void updateTypeSignature() {
+ private void updateTypeSignature(ParserPosition parserPosition) {
switch (symbol) {
case 'B':
case 'C':
@@ -306,7 +311,7 @@
break;
default:
// Not an elementary type, but a FieldTypeSignature.
- parseFieldTypeSignature();
+ parseFieldTypeSignature(parserPosition);
}
}
@@ -319,7 +324,7 @@
expect('(');
while (symbol != ')' && (symbol > 0)) {
- updateTypeSignature();
+ updateTypeSignature(ParserPosition.MEMBER_ANNOTATION);
}
actions.parsedSymbol(symbol);
@@ -336,7 +341,7 @@
if (symbol == 'T') {
updateTypeVariableSignature();
} else {
- parseClassTypeSignature();
+ parseClassTypeSignature(ParserPosition.MEMBER_ANNOTATION);
}
} while (symbol == '^');
}
@@ -345,7 +350,7 @@
private void updateReturnType() {
// ReturnType ::= TypeSignature | "V".
if (symbol != 'V') {
- updateTypeSignature();
+ updateTypeSignature(ParserPosition.MEMBER_ANNOTATION);
} else {
actions.parsedSymbol(symbol);
scanSymbol();
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
index c3b7188..13c2c43 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
@@ -10,8 +10,8 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinition;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.origin.Origin;
@@ -43,15 +43,16 @@
this.reporter = appView.options().reporter;
}
- public void run(Iterable<? extends DexClass> classes) {
+ public void run(Iterable<? extends DexProgramClass> classes) {
final GenericSignatureCollector genericSignatureCollector = new GenericSignatureCollector();
final GenericSignatureParser<DexType> genericSignatureParser =
new GenericSignatureParser<>(genericSignatureCollector);
- // classes may not be the same as appInfo().classes() if applymapping is used on classpath
+ // Classes may not be the same as appInfo().classes() if applymapping is used on classpath
// arguments. If that is the case, the ProguardMapMinifier will pass in all classes that is
// either ProgramClass or has a mapping. This is then transitively called inside the
// ClassNameMinifier.
- for (DexClass clazz : classes) {
+ for (DexProgramClass clazz : classes) {
+ genericSignatureCollector.setCurrentClassContext(clazz);
clazz.annotations =
rewriteGenericSignatures(
clazz.annotations,
@@ -152,13 +153,22 @@
private class GenericSignatureCollector implements GenericSignatureAction<DexType> {
private StringBuilder renamedSignature;
+ private DexProgramClass currentClassContext;
- public String getRenamedSignature() {
+ String getRenamedSignature() {
return renamedSignature.toString();
}
+ void setCurrentClassContext(DexProgramClass clazz) {
+ currentClassContext = clazz;
+ }
+
@Override
public void parsedSymbol(char symbol) {
+ if (symbol == ';' && renamedSignature.charAt(renamedSignature.length() - 1) == ';') {
+ // The type was never written (maybe because it was merged with it's subtype)
+ return;
+ }
renamedSignature.append(symbol);
}
@@ -168,13 +178,24 @@
}
@Override
- public DexType parsedTypeName(String name) {
- DexType type = appView.dexItemFactory().createType(getDescriptorFromClassBinaryName(name));
- type = appView.graphLense().lookupType(type);
+ public DexType parsedTypeName(String name, ParserPosition parserPosition) {
+ String originalDescriptor = getDescriptorFromClassBinaryName(name);
+ DexType type =
+ appView.graphLense().lookupType(appView.dexItemFactory().createType(originalDescriptor));
if (appView.appInfo().wasPruned(type)) {
type = appView.dexItemFactory().objectType;
}
DexString renamedDescriptor = renaming.getOrDefault(type, type.descriptor);
+ if (parserPosition == ParserPosition.CLASS_SUPER_OR_INTERFACE_ANNOTATION
+ && currentClassContext != null) {
+ // We may have merged the type down to the current class type.
+ DexString classDescriptor = currentClassContext.type.descriptor;
+ if (!originalDescriptor.equals(classDescriptor.toString())
+ && renamedDescriptor.equals(classDescriptor)) {
+ renamedSignature.deleteCharAt(renamedSignature.length() - 1);
+ return null;
+ }
+ }
renamedSignature.append(getClassBinaryNameFromDescriptor(renamedDescriptor.toString()));
return type;
}
@@ -197,6 +218,7 @@
type = appView.graphLense().lookupType(type);
DexString renamedDescriptor = renaming.get(type);
if (renamedDescriptor != null) {
+ // TODO(b/147504070): If this is a merged class equal to the class context, do not add.
// Pick the renamed inner class from the fully renamed binary name.
String fullRenamedBinaryName =
getClassBinaryNameFromDescriptor(renamedDescriptor.toString());
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 69b77cd..62241d5 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -383,7 +383,7 @@
}
}
if (clazz.getEnclosingMethod() != null || !clazz.getInnerClasses().isEmpty()) {
- // TODO(herhut): Consider supporting merging of enclosing-method and inner-class attributes.
+ // TODO(b/147504070): Consider merging of enclosing-method and inner-class attributes.
if (Log.ENABLED) {
AbortReason.UNSUPPORTED_ATTRIBUTES.printLogMessageForClass(clazz);
}
@@ -440,7 +440,7 @@
return false;
}
if (targetClass.getEnclosingMethod() != null || !targetClass.getInnerClasses().isEmpty()) {
- // TODO(herhut): Consider supporting merging of enclosing-method and inner-class attributes.
+ // TODO(b/147504070): Consider merging of enclosing-method and inner-class attributes.
if (Log.ENABLED) {
AbortReason.UNSUPPORTED_ATTRIBUTES.printLogMessageForClass(clazz);
}
diff --git a/src/main/java/com/android/tools/r8/utils/IteratorUtils.java b/src/main/java/com/android/tools/r8/utils/IteratorUtils.java
index 7ffce35..f38c02a 100644
--- a/src/main/java/com/android/tools/r8/utils/IteratorUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/IteratorUtils.java
@@ -16,7 +16,8 @@
public class IteratorUtils {
- public static <T, S extends T> Iterator<S> filter(Iterator<T> iterator, Predicate<T> predicate) {
+ public static <T, S extends T> Iterator<S> filter(
+ Iterator<? extends T> iterator, Predicate<T> predicate) {
return new Iterator<S>() {
private S next = advance();
diff --git a/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java b/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
index b264ef5..4489b75 100644
--- a/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
+++ b/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
@@ -22,6 +22,7 @@
import org.junit.Test;
public class GenericSignatureParserTest extends TestBase {
+
private static class ReGenerateGenericSignatureRewriter
implements GenericSignatureAction<String> {
@@ -42,7 +43,7 @@
}
@Override
- public String parsedTypeName(String name) {
+ public String parsedTypeName(String name, ParserPosition parserPosition) {
renamedSignature.append(name);
return name;
}
@@ -389,7 +390,7 @@
}
@Override
- public String parsedTypeName(String name) {
+ public String parsedTypeName(String name, ParserPosition parserPosition) {
throw exceptionSupplier.get();
}
}
diff --git a/src/test/java/com/android/tools/r8/naming/signature/SignatureOfMergedClassesTest.java b/src/test/java/com/android/tools/r8/naming/signature/SignatureOfMergedClassesTest.java
new file mode 100644
index 0000000..a9fc20f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/signature/SignatureOfMergedClassesTest.java
@@ -0,0 +1,122 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.signature;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.naming.signature.merging.I;
+import com.android.tools.r8.naming.signature.merging.ImplI;
+import com.android.tools.r8.naming.signature.merging.ImplK;
+import com.android.tools.r8.naming.signature.merging.InterfaceToKeep;
+import com.android.tools.r8.naming.signature.merging.J;
+import com.android.tools.r8.naming.signature.merging.K;
+import java.io.IOException;
+import java.lang.invoke.LambdaConversionException;
+import java.lang.reflect.Type;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class SignatureOfMergedClassesTest extends TestBase {
+
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ public SignatureOfMergedClassesTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testRemovalOfMergedInterfaceOnSameClass()
+ throws IOException, CompilationFailedException, ExecutionException,
+ LambdaConversionException {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(
+ ImplI.class, ImplK.class, I.class, J.class, InterfaceToKeep.class, K.class, Main.class)
+ .addKeepMainRule(Main.class)
+ .addKeepClassRules(InterfaceToKeep.class)
+ .addKeepAttributes("Signature, InnerClasses, EnclosingMethod, *Annotation*")
+ .setMinApi(parameters.getApiLevel())
+ .noMinification()
+ .addOptionsModification(
+ internalOptions -> {
+ internalOptions.enableUnusedInterfaceRemoval = false;
+ })
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(
+ "ImplI.foo",
+ "ImplI: com.android.tools.r8.naming.signature.merging.InterfaceToKeep<java.lang.Void>",
+ "K: com.android.tools.r8.naming.signature.merging.InterfaceToKeep<java.lang.Void>",
+ "ImplK.foo",
+ "ImplK.bar",
+ "ImplK: interface com.android.tools.r8.naming.signature.merging.K")
+ .inspect(
+ codeInspector -> {
+ assertThat(codeInspector.clazz(I.class), not(isPresent()));
+ assertThat(codeInspector.clazz(J.class), not(isPresent()));
+ });
+ }
+
+ @Test
+ public void testKeepingOneSelfOnInterface()
+ throws ExecutionException, CompilationFailedException, IOException {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(Foo.class, InterfaceToKeep.class)
+ .addKeepMainRule(Foo.class)
+ .addKeepClassRules(InterfaceToKeep.class)
+ .addKeepAttributes("Signature, InnerClasses, EnclosingMethod, *Annotation*")
+ .setMinApi(parameters.getApiLevel())
+ .noMinification()
+ .addOptionsModification(
+ internalOptions -> {
+ internalOptions.enableUnusedInterfaceRemoval = false;
+ })
+ .run(parameters.getRuntime(), Foo.class)
+ .assertSuccessWithOutputLines(
+ "com.android.tools.r8.naming.signature.merging.InterfaceToKeep"
+ + "<com.android.tools.r8.naming.signature.SignatureOfMergedClassesTest$Foo>");
+ }
+
+ public static class Foo implements InterfaceToKeep<Foo> {
+
+ public static void main(String[] args) {
+ for (Type genericInterface : Foo.class.getGenericInterfaces()) {
+ System.out.println(genericInterface);
+ }
+ }
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) {
+ new ImplI().foo();
+ for (Type genericInterface : ImplI.class.getGenericInterfaces()) {
+ System.out.println("ImplI: " + genericInterface);
+ }
+ for (Type genericInterface : K.class.getGenericInterfaces()) {
+ System.out.println("K: " + genericInterface);
+ }
+ K k = new ImplK();
+ k.foo();
+ k.bar();
+ for (Type genericInterface : ImplK.class.getGenericInterfaces()) {
+ System.out.println("ImplK: " + genericInterface);
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/signature/merging/I.java b/src/test/java/com/android/tools/r8/naming/signature/merging/I.java
new file mode 100644
index 0000000..237786c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/signature/merging/I.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.signature.merging;
+
+public interface I {
+ void foo();
+}
diff --git a/src/test/java/com/android/tools/r8/naming/signature/merging/ImplI.java b/src/test/java/com/android/tools/r8/naming/signature/merging/ImplI.java
new file mode 100644
index 0000000..b842386
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/signature/merging/ImplI.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.signature.merging;
+
+public class ImplI implements InterfaceToKeep<Void>, I {
+
+ @Override
+ public void foo() {
+ System.out.println("ImplI.foo");
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/signature/merging/ImplK.java b/src/test/java/com/android/tools/r8/naming/signature/merging/ImplK.java
new file mode 100644
index 0000000..3c23d56
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/signature/merging/ImplK.java
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.signature.merging;
+
+public class ImplK implements K {
+
+ @Override
+ public void foo() {
+ System.out.println("ImplK.foo");
+ }
+
+ @Override
+ public void bar() {
+ System.out.println("ImplK.bar");
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/signature/merging/InterfaceToKeep.java b/src/test/java/com/android/tools/r8/naming/signature/merging/InterfaceToKeep.java
new file mode 100644
index 0000000..6bebcd0
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/signature/merging/InterfaceToKeep.java
@@ -0,0 +1,7 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.signature.merging;
+
+public interface InterfaceToKeep<T> {}
diff --git a/src/test/java/com/android/tools/r8/naming/signature/merging/J.java b/src/test/java/com/android/tools/r8/naming/signature/merging/J.java
new file mode 100644
index 0000000..444a5e8
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/signature/merging/J.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.signature.merging;
+
+public interface J {
+ void foo();
+}
diff --git a/src/test/java/com/android/tools/r8/naming/signature/merging/K.java b/src/test/java/com/android/tools/r8/naming/signature/merging/K.java
new file mode 100644
index 0000000..4b8ed50
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/signature/merging/K.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.signature.merging;
+
+public interface K extends InterfaceToKeep<Void>, J {
+ void bar();
+}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 4aec544..1a4dcc16 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -423,7 +423,7 @@
}
@Override
- public String parsedTypeName(String name) {
+ public String parsedTypeName(String name, ParserPosition parserPosition) {
String type = name;
if (obfuscatedToOriginalMapping != null) {
String original = mapType(obfuscatedToOriginalMapping, name);