Version 1.4.71 Don't use qualified entries in apply-mapping. Fix and regressions tests added directly to 1.4, to be picked to master. Bug: 121042934 Change-Id: I610b13ad5ac46c70a5a9624db80fd9ccc1c1f79c
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java index 30d9b3b..2f7ec60 100644 --- a/src/main/java/com/android/tools/r8/Version.java +++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@ // This field is accessed from release scripts using simple pattern matching. // Therefore, changing this field could break our release scripts. - public static final String LABEL = "1.4.70"; + public static final String LABEL = "1.4.71"; private Version() { }
diff --git a/src/main/java/com/android/tools/r8/naming/MemberNaming.java b/src/main/java/com/android/tools/r8/naming/MemberNaming.java index 094dcaf..c76b422 100644 --- a/src/main/java/com/android/tools/r8/naming/MemberNaming.java +++ b/src/main/java/com/android/tools/r8/naming/MemberNaming.java
@@ -106,6 +106,8 @@ abstract void write(Writer builder) throws IOException; + boolean isQualified() { return name.contains("."); } + @Override public String toString() { try {
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapApplier.java b/src/main/java/com/android/tools/r8/naming/ProguardMapApplier.java index d95f299..a447e37 100644 --- a/src/main/java/com/android/tools/r8/naming/ProguardMapApplier.java +++ b/src/main/java/com/android/tools/r8/naming/ProguardMapApplier.java
@@ -191,7 +191,7 @@ // e.g., private methods with same names, could be mapped to a wrong renamed name. classNaming.forAllFieldNaming(memberNaming -> { FieldSignature signature = (FieldSignature) memberNaming.getOriginalSignature(); - if (!appliedMemberSignature.contains(signature)) { + if (!signature.isQualified() && !appliedMemberSignature.contains(signature)) { DexField pretendedOriginalField = signature.toDexField(appInfo.dexItemFactory, from); if (appInfo.definitionFor(pretendedOriginalField) == null) { applyFieldMapping(pretendedOriginalField, memberNaming); @@ -200,7 +200,7 @@ }); classNaming.forAllMethodNaming(memberNaming -> { MethodSignature signature = (MethodSignature) memberNaming.getOriginalSignature(); - if (!appliedMemberSignature.contains(signature)) { + if (!signature.isQualified() && !appliedMemberSignature.contains(signature)) { DexMethod pretendedOriginalMethod = signature.toDexMethod(appInfo.dexItemFactory, from); if (appInfo.definitionFor(pretendedOriginalMethod) == null) { applyMethodMapping(pretendedOriginalMethod, memberNaming);
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java index e8555d7..7f06ea2 100644 --- a/src/test/java/com/android/tools/r8/R8TestBuilder.java +++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -12,11 +12,14 @@ import com.android.tools.r8.shaking.ProguardConfiguration; import com.android.tools.r8.shaking.ProguardConfigurationRule; import com.android.tools.r8.utils.AndroidApp; +import com.android.tools.r8.utils.FileUtils; import com.android.tools.r8.utils.InternalOptions; +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; import java.util.function.Supplier; @@ -45,6 +48,7 @@ private boolean enableUnusedArgumentAnnotations = false; private CollectingGraphConsumer graphConsumer = null; private List<String> keepRules = new ArrayList<>(); + private List<String> applyMappingMaps = new ArrayList<>(); @Override R8TestBuilder self() { @@ -70,6 +74,21 @@ builder.setDisableMinification(!enableMinification); builder.setProguardMapConsumer((string, ignore) -> proguardMapBuilder.append(string)); + if (!applyMappingMaps.isEmpty()) { + try { + Path mappingsDir = getState().getNewTempFolder(); + for (int i = 0; i < applyMappingMaps.size(); i++) { + String mapContent = applyMappingMaps.get(i); + Path mapPath = mappingsDir.resolve("mapping" + i + ".map"); + FileUtils.writeTextFile(mapPath, mapContent); + builder.addProguardConfiguration( + Collections.singletonList("-applymapping " + mapPath.toString()), Origin.unknown()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + class Box { private List<ProguardConfigurationRule> syntheticProguardRules; private ProguardConfiguration proguardConfiguration; @@ -208,6 +227,11 @@ return self(); } + public R8TestBuilder addApplyMapping(String proguardMap) { + applyMappingMaps.add(proguardMap); + return self(); + } + private void addInternalKeepRules(String... rules) { // We don't add these to the keep-rule set for other test provided rules. builder.addProguardConfiguration(Arrays.asList(rules), Origin.unknown());
diff --git a/src/test/java/com/android/tools/r8/R8TestCompileResult.java b/src/test/java/com/android/tools/r8/R8TestCompileResult.java index ecb0a92..95ec572 100644 --- a/src/test/java/com/android/tools/r8/R8TestCompileResult.java +++ b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
@@ -94,4 +94,8 @@ public R8TestRunResult createRunResult(ProcessResult result) { return new R8TestRunResult(app, result, proguardMap, this::graphInspector); } + + public String getProguardMap() { + return proguardMap; + } }
diff --git a/src/test/java/com/android/tools/r8/TestBaseBuilder.java b/src/test/java/com/android/tools/r8/TestBaseBuilder.java index 5fcd1b5..1304357 100644 --- a/src/test/java/com/android/tools/r8/TestBaseBuilder.java +++ b/src/test/java/com/android/tools/r8/TestBaseBuilder.java
@@ -4,9 +4,14 @@ package com.android.tools.r8; +import com.android.tools.r8.ProgramResource.Kind; import com.android.tools.r8.origin.Origin; +import com.android.tools.r8.utils.DescriptorUtils; +import com.google.common.collect.ImmutableMap; import java.nio.file.Path; import java.util.Collection; +import java.util.Map; +import java.util.Set; public abstract class TestBaseBuilder< C extends BaseCommand, @@ -43,6 +48,35 @@ return self(); } + @Override + public T addLibraryClasses(Collection<Class<?>> classes) { + builder.addLibraryResourceProvider( + new ClassFileResourceProvider() { + final Map<String, ProgramResource> resources; + + { + ImmutableMap.Builder<String, ProgramResource> builder = ImmutableMap.builder(); + classes.forEach( + c -> + builder.put( + DescriptorUtils.javaTypeToDescriptor(c.getTypeName()), + ProgramResource.fromFile(Kind.CF, ToolHelper.getClassFileForTestClass(c)))); + resources = builder.build(); + } + + @Override + public Set<String> getClassDescriptors() { + return resources.keySet(); + } + + @Override + public ProgramResource getProgramResource(String descriptor) { + return resources.get(descriptor); + } + }); + return self(); + } + public T addMainDexListFiles(Collection<Path> files) { builder.addMainDexListFiles(files); return self();
diff --git a/src/test/java/com/android/tools/r8/TestBuilder.java b/src/test/java/com/android/tools/r8/TestBuilder.java index cee2519..30159d3 100644 --- a/src/test/java/com/android/tools/r8/TestBuilder.java +++ b/src/test/java/com/android/tools/r8/TestBuilder.java
@@ -4,6 +4,7 @@ package com.android.tools.r8; import com.android.tools.r8.debug.DebugTestConfig; +import com.android.tools.r8.errors.Unimplemented; import com.android.tools.r8.utils.ListUtils; import java.io.IOException; import java.nio.file.Path; @@ -85,7 +86,7 @@ } public T addLibraryClasses(Collection<Class<?>> classes) { - return addLibraryFiles(getFilesForClasses(classes)); + throw new Unimplemented("Unsupported addLibraryClasses"); } public T addLibraryFiles(Path... files) {
diff --git a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java index a17ab09..cbf8e81 100644 --- a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java +++ b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
@@ -82,6 +82,13 @@ return self(); } + public T addKeepClassAndDefaultConstructor(Class<?>... classes) { + for (Class<?> clazz : classes) { + addKeepRules("-keep class " + clazz.getTypeName() + " { <init>(); }"); + } + return self(); + } + public T addKeepPackageRules(Package pkg) { return addKeepRules("-keep class " + pkg.getName() + ".*"); }
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingFieldTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingFieldTest.java new file mode 100644 index 0000000..bae227f --- /dev/null +++ b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingFieldTest.java
@@ -0,0 +1,116 @@ +// Copyright (c) 2019, 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.applymapping; + +import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertTrue; + +import com.android.tools.r8.NeverInline; +import com.android.tools.r8.R8TestCompileResult; +import com.android.tools.r8.TestBase; +import com.android.tools.r8.utils.StringUtils; +import com.android.tools.r8.utils.codeinspector.CodeInspector; +import java.nio.file.Path; +import java.util.Collections; +import org.junit.Assume; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class ApplyMappingAfterHorizontalMergingFieldTest extends TestBase { + + // Will merge with B. + public static class LibraryA { + + public static boolean bar; + } + + // Will merge with A. + public static class LibraryB { + + public static boolean foo; + } + + // Ensure kept entry hitting the merged classes. + public static class LibraryMain { + + public static void main(String[] args) { + LibraryA.bar = System.nanoTime() > 0; + LibraryB.foo = args.length < 123; + System.out.println(LibraryA.bar && LibraryB.foo); + } + } + + // Program class simply calling library main. + public static class ProgramClass { + + public static void main(String[] args) { + LibraryMain.main(args); + } + } + + // Test runner code follows. + + private static final Class<?>[] LIBRARY_CLASSES = { + NeverInline.class, + LibraryA.class, + LibraryB.class, + LibraryMain.class + }; + + private static final Class<?>[] PROGRAM_CLASSES = { + ProgramClass.class + }; + + private Backend backend; + + @Parameterized.Parameters(name = "{0}") + public static Backend[] data() { + return Backend.values(); + } + + public ApplyMappingAfterHorizontalMergingFieldTest(Backend backend) { + this.backend = backend; + } + + @Test + public void runOnJvm() throws Throwable { + Assume.assumeTrue(backend == Backend.CF); + testForJvm() + .addProgramClasses(LIBRARY_CLASSES) + .addProgramClasses(PROGRAM_CLASSES) + .run(ProgramClass.class) + .assertSuccessWithOutput(StringUtils.lines("true")); + } + + @Test + public void b121042934() throws Exception { + R8TestCompileResult libraryResult = testForR8(backend) + .enableInliningAnnotations() + .addProgramClasses(LIBRARY_CLASSES) + .addKeepMainRule(LibraryMain.class) + .compile(); + + CodeInspector inspector = libraryResult.inspector(); + assertThat(inspector.clazz(LibraryMain.class), isPresent()); + // Classes A and B have been merged, check only one remains. + assertTrue(inspector.clazz(LibraryA.class).isPresent() + != inspector.clazz(LibraryB.class).isPresent()); + + Path libraryOut = temp.newFolder().toPath().resolve("out.jar"); + libraryResult.writeToZip(libraryOut); + testForR8(backend) + .noTreeShaking() + .noMinification() + .addProgramClasses(PROGRAM_CLASSES) + .addApplyMapping(libraryResult.getProguardMap()) + .addLibraryClasses(LIBRARY_CLASSES) + .compile() + .addRunClasspath(Collections.singletonList(libraryOut)) + .run(ProgramClass.class) + .assertSuccessWithOutput(StringUtils.lines("true")); + } +}
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingMethodTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingMethodTest.java new file mode 100644 index 0000000..88cb16a --- /dev/null +++ b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingMethodTest.java
@@ -0,0 +1,120 @@ +// Copyright (c) 2019, 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.applymapping; + +import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertTrue; + +import com.android.tools.r8.NeverInline; +import com.android.tools.r8.R8TestCompileResult; +import com.android.tools.r8.TestBase; +import com.android.tools.r8.utils.StringUtils; +import com.android.tools.r8.utils.codeinspector.CodeInspector; +import java.nio.file.Path; +import java.util.Collections; +import org.junit.Assume; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class ApplyMappingAfterHorizontalMergingMethodTest extends TestBase { + + // Will merge with B. + public static class LibraryA { + + @NeverInline + public static String bar() { + return "LibraryA::foo"; + } + } + + // Will merge with A. + public static class LibraryB { + + @NeverInline + public static String foo() { + return LibraryA.bar(); + } + } + + // Ensure kept entry hitting the merged classes. + public static class LibraryMain { + + public static void main(String[] args) { + System.out.println(LibraryB.foo()); + } + } + + // Program class simply calling library main. + public static class ProgramClass { + + public static void main(String[] args) { + LibraryMain.main(args); + } + } + + // Test runner code follows. + + private static final Class<?>[] LIBRARY_CLASSES = { + NeverInline.class, + LibraryA.class, + LibraryB.class, + LibraryMain.class + }; + + private static final Class<?>[] PROGRAM_CLASSES = { + ProgramClass.class + }; + + private Backend backend; + + @Parameterized.Parameters(name = "{0}") + public static Backend[] data() { + return Backend.values(); + } + + public ApplyMappingAfterHorizontalMergingMethodTest(Backend backend) { + this.backend = backend; + } + + @Test + public void runOnJvm() throws Throwable { + Assume.assumeTrue(backend == Backend.CF); + testForJvm() + .addProgramClasses(LIBRARY_CLASSES) + .addProgramClasses(PROGRAM_CLASSES) + .run(ProgramClass.class) + .assertSuccessWithOutput(StringUtils.lines("LibraryA::foo")); + } + + @Test + public void b121042934() throws Exception { + R8TestCompileResult libraryResult = testForR8(backend) + .enableInliningAnnotations() + .addProgramClasses(LIBRARY_CLASSES) + .addKeepMainRule(LibraryMain.class) + .compile(); + + CodeInspector inspector = libraryResult.inspector(); + assertThat(inspector.clazz(LibraryMain.class), isPresent()); + // Classes A and B have been merged, check only one remains. + assertTrue(inspector.clazz(LibraryA.class).isPresent() + != inspector.clazz(LibraryB.class).isPresent()); + + Path libraryOut = temp.newFolder().toPath().resolve("out.jar"); + libraryResult.writeToZip(libraryOut); + testForR8(backend) + .noTreeShaking() + .noMinification() + .addProgramClasses(PROGRAM_CLASSES) + .addApplyMapping(libraryResult.getProguardMap()) + .addLibraryClasses(LIBRARY_CLASSES) + .compile() + .addRunClasspath(Collections.singletonList(libraryOut)) + .run(ProgramClass.class) + .assertSuccessWithOutput(StringUtils.lines("LibraryA::foo")); + } +}
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingFieldTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingFieldTest.java new file mode 100644 index 0000000..2a35205 --- /dev/null +++ b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingFieldTest.java
@@ -0,0 +1,107 @@ +// Copyright (c) 2018, 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.applymapping; + +import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; + +import com.android.tools.r8.NeverInline; +import com.android.tools.r8.NeverMerge; +import com.android.tools.r8.R8TestCompileResult; +import com.android.tools.r8.TestBase; +import com.android.tools.r8.utils.StringUtils; +import com.android.tools.r8.utils.codeinspector.CodeInspector; +import java.nio.file.Path; +import java.util.Collections; +import org.junit.Assume; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class ApplyMappingAfterVerticalMergingFieldTest extends TestBase { + + // Base class will be vertical class merged into subclass + public static class LibraryBase { + + public boolean foo = System.nanoTime() > 0; + } + + // Subclass targeted via vertical class merging. The main method ensures a reference to foo. + public static class LibrarySubclass extends LibraryBase { + + public static void main(String[] args) { + System.out.println(new LibrarySubclass().foo); + } + } + + // Program class that uses LibrarySubclass but the library does not explicitly keep foo and + // should thus fail at runtime. + public static class ProgramClass extends LibrarySubclass { + + public static void main(String[] args) { + System.out.println(new ProgramClass().foo); + } + } + + // Test runner code follows. + + private static final Class<?>[] LIBRARY_CLASSES = { + NeverMerge.class, LibraryBase.class, LibrarySubclass.class + }; + + private static final Class<?>[] PROGRAM_CLASSES = { + ProgramClass.class + }; + + private Backend backend; + + @Parameterized.Parameters(name = "{0}") + public static Backend[] data() { + return Backend.values(); + } + + public ApplyMappingAfterVerticalMergingFieldTest(Backend backend) { + this.backend = backend; + } + + @Test + public void runOnJvm() throws Throwable { + Assume.assumeTrue(backend == Backend.CF); + testForJvm() + .addProgramClasses(LIBRARY_CLASSES) + .addProgramClasses(PROGRAM_CLASSES) + .run(ProgramClass.class) + .assertSuccessWithOutput(StringUtils.lines("true")); + } + + @Test + public void b121042934() throws Exception { + R8TestCompileResult libraryResult = testForR8(backend) + .enableInliningAnnotations() + .addProgramClasses(LIBRARY_CLASSES) + .addKeepMainRule(LibrarySubclass.class) + .addKeepClassAndDefaultConstructor(LibrarySubclass.class) + .compile(); + + CodeInspector inspector = libraryResult.inspector(); + assertThat(inspector.clazz(LibraryBase.class), not(isPresent())); + assertThat(inspector.clazz(LibrarySubclass.class), isPresent()); + + Path libraryOut = temp.newFolder().toPath().resolve("out.jar"); + libraryResult.writeToZip(libraryOut); + testForR8(backend) + .noTreeShaking() + .noMinification() + .addProgramClasses(PROGRAM_CLASSES) + .addApplyMapping(libraryResult.getProguardMap()) + .addLibraryClasses(LIBRARY_CLASSES) + .compile() + .addRunClasspath(Collections.singletonList(libraryOut)) + .run(ProgramClass.class) + .assertFailureWithErrorThatMatches(containsString("NoSuchFieldError")); + } +}
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingMethodTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingMethodTest.java new file mode 100644 index 0000000..9d2000e --- /dev/null +++ b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingMethodTest.java
@@ -0,0 +1,110 @@ +// Copyright (c) 2018, 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.applymapping; + +import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; + +import com.android.tools.r8.NeverInline; +import com.android.tools.r8.NeverMerge; +import com.android.tools.r8.R8TestCompileResult; +import com.android.tools.r8.TestBase; +import com.android.tools.r8.utils.StringUtils; +import com.android.tools.r8.utils.codeinspector.CodeInspector; +import java.nio.file.Path; +import java.util.Collections; +import org.junit.Assume; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class ApplyMappingAfterVerticalMergingMethodTest extends TestBase { + + // Base class will be vertical class merged into subclass + public static class LibraryBase { + + @NeverInline + public String foo() { + return "LibraryBase::foo"; + } + } + + // Subclass targeted via vertical class merging. The main method ensures a reference to foo. + public static class LibrarySubclass extends LibraryBase { + + public static void main(String[] args) { + System.out.println(new LibrarySubclass().foo()); + } + } + + // Program class that uses LibrarySubclass but the library does not explicitly keep foo and + // should thus fail at runtime. + public static class ProgramClass extends LibrarySubclass { + + public static void main(String[] args) { + System.out.println(new ProgramClass().foo()); + } + } + + // Test runner code follows. + + private static final Class<?>[] LIBRARY_CLASSES = { + NeverMerge.class, LibraryBase.class, LibrarySubclass.class + }; + + private static final Class<?>[] PROGRAM_CLASSES = { + ProgramClass.class + }; + + private Backend backend; + + @Parameterized.Parameters(name = "{0}") + public static Backend[] data() { + return Backend.values(); + } + + public ApplyMappingAfterVerticalMergingMethodTest(Backend backend) { + this.backend = backend; + } + + @Test + public void runOnJvm() throws Throwable { + Assume.assumeTrue(backend == Backend.CF); + testForJvm() + .addProgramClasses(LIBRARY_CLASSES) + .addProgramClasses(PROGRAM_CLASSES) + .run(ProgramClass.class) + .assertSuccessWithOutput(StringUtils.lines("LibraryBase::foo")); + } + + @Test + public void b121042934() throws Exception { + R8TestCompileResult libraryResult = testForR8(backend) + .enableInliningAnnotations() + .addProgramClasses(LIBRARY_CLASSES) + .addKeepMainRule(LibrarySubclass.class) + .addKeepClassAndDefaultConstructor(LibrarySubclass.class) + .compile(); + + CodeInspector inspector = libraryResult.inspector(); + assertThat(inspector.clazz(LibraryBase.class), not(isPresent())); + assertThat(inspector.clazz(LibrarySubclass.class), isPresent()); + + Path libraryOut = temp.newFolder().toPath().resolve("out.jar"); + libraryResult.writeToZip(libraryOut); + testForR8(backend) + .noTreeShaking() + .noMinification() + .addProgramClasses(PROGRAM_CLASSES) + .addApplyMapping(libraryResult.getProguardMap()) + .addLibraryClasses(LIBRARY_CLASSES) + .compile() + .addRunClasspath(Collections.singletonList(libraryOut)) + .run(ProgramClass.class) + .assertFailureWithErrorThatMatches(containsString("NoSuchMethodError")); + } +}
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingTest.java deleted file mode 100644 index 8856f47..0000000 --- a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterVerticalMergingTest.java +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright (c) 2018, 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.applymapping; - -import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; -import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - -import com.android.tools.r8.NeverMerge; -import com.android.tools.r8.TestBase; -import com.android.tools.r8.utils.DescriptorUtils; -import com.android.tools.r8.utils.codeinspector.ClassSubject; -import com.android.tools.r8.utils.codeinspector.CodeInspector; -import com.android.tools.r8.utils.codeinspector.FieldSubject; -import com.android.tools.r8.utils.codeinspector.MethodSubject; -import java.lang.ref.WeakReference; -import java.nio.file.Path; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -class Resources { -} - -@NeverMerge -class ResourceWrapper extends Resources { - // Will be merged down, and represented as: - // ...applymapping.Resources ...applymapping.ResourceWrapper.mResources -> a - private Resources mResources; - - ResourceWrapper(Resources resource) { - this.mResources = resource; - } - - // Will be merged down, and represented as: - // java.lang.String ...applymapping.ResourceWrapper.foo() -> a - String foo() { - return mResources.toString(); - } - - @Override - public String toString() { - return mResources.toString(); - } -} - -class TintResources extends ResourceWrapper { - private WeakReference<Resources> ref; - - TintResources(Resources resource) { - super(resource); - ref = new WeakReference<>(resource); - } - - public static void main(String[] args) { - TintResources t = new TintResources(new Resources()); - System.out.println(t.foo()); - } -} - -@RunWith(Parameterized.class) -public class ApplyMappingAfterVerticalMergingTest extends TestBase { - private final static Class<?>[] CLASSES = { - NeverMerge.class, Resources.class, ResourceWrapper.class, TintResources.class - }; - private final static Class<?> MAIN = TintResources.class; - - private Backend backend; - - @Parameterized.Parameters(name = "Backend: {0}") - public static Backend[] data() { - return Backend.values(); - } - - public ApplyMappingAfterVerticalMergingTest(Backend backend) { - this.backend = backend; - } - - @Ignore("b/12042934") - @Test - public void b121042934() throws Exception { - Path mapPath = temp.newFile("test-mapping.txt").toPath(); - CodeInspector inspector1 = testForR8(backend) - .addProgramClasses(CLASSES) - .addKeepMainRule(MAIN) - .addKeepRules("-printmapping " + mapPath.toAbsolutePath()) - .compile() - .inspector(); - CodeInspector inspector2 = testForR8(backend) - .addProgramClasses(CLASSES) - .addKeepMainRule(MAIN) - .addKeepRules("-applymapping " + mapPath.toAbsolutePath()) - .compile() - .inspector(); - - ClassSubject classSubject1 = inspector1.clazz(MAIN); - assertThat(classSubject1, isPresent()); - assertThat(classSubject1, isRenamed()); - ClassSubject classSubject2 = inspector2.clazz( - DescriptorUtils.getClassNameFromDescriptor(classSubject1.getFinalDescriptor())); - assertThat(classSubject2, isPresent()); - assertThat(classSubject2, not(isRenamed())); - assertEquals(classSubject1.getFinalDescriptor(), classSubject2.getFinalDescriptor()); - - FieldSubject field1 = classSubject1.uniqueFieldWithName("mResources"); - assertThat(field1, isPresent()); - assertThat(field1, isRenamed()); - FieldSubject field2 = classSubject2.uniqueFieldWithName("mResources"); - assertThat(field2, isPresent()); - assertThat(field2, not(isRenamed())); - assertEquals(field1.getFinalSignature().toString(), field2.getFinalSignature().toString()); - - MethodSubject method1 = classSubject1.uniqueMethodWithName("foo"); - assertThat(method1, isPresent()); - assertThat(method1, isRenamed()); - MethodSubject method2 = classSubject2.uniqueMethodWithName("foo"); - assertThat(method2, isPresent()); - assertThat(method2, not(isRenamed())); - assertEquals(method1.getFinalSignature().toString(), method2.getFinalSignature().toString()); - } - -}