Add a test about optimizing unused Kotlin singleton.
Bug: 110196118
Change-Id: Ia7d20d23e4df66c0b644c56778afe8115c54950d
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedSingletonTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedSingletonTest.java
new file mode 100644
index 0000000..5de6fd9be
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinUnusedSingletonTest.java
@@ -0,0 +1,70 @@
+// 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.kotlin;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.utils.InternalOptions;
+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.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject.JumboStringMode;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import org.junit.Test;
+
+public class KotlinUnusedSingletonTest extends AbstractR8KotlinTestBase {
+ private Consumer<InternalOptions> optionsModifier =
+ o -> {
+ o.enableTreeShaking = true;
+ o.enableMinification = false;
+ };
+
+ public KotlinUnusedSingletonTest(
+ KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+ super(targetVersion, allowAccessModification);
+ }
+
+ @Test
+ public void b110196118() throws Exception {
+ final String mainClassName = "unused_singleton.MainKt";
+ final String moduleName = "unused_singleton.TestModule";
+ runTest("unused_singleton", mainClassName, optionsModifier, app -> {
+ CodeInspector inspector = new CodeInspector(app);
+ ClassSubject main = inspector.clazz(mainClassName);
+ assertThat(main, isPresent());
+ MethodSubject mainMethod = main.mainMethod();
+ assertThat(mainMethod, isPresent());
+ // const-string of provideGreeting() is propagated.
+ Iterator<InstructionSubject> it =
+ mainMethod.iterateInstructions(i -> i.isConstString("Hello", JumboStringMode.ALLOW));
+ assertTrue(it.hasNext());
+ // But, static call is still there, since it may trigger class initialization.
+ ClassSubject module = inspector.clazz(moduleName);
+ assertThat(main, isPresent());
+ MethodSubject provideGreetingMethod = module.uniqueMethodWithName("provideGreeting");
+ assertThat(mainMethod, invokesMethod(provideGreetingMethod));
+
+ // field `INSTANCE` is shrunk.
+ FieldSubject instance = module.uniqueFieldWithName("INSTANCE");
+ assertThat(instance, not(isPresent()));
+ // TODO(b/110196118): remaining new-instance and invoke-direct <init> could be shrunk.
+ // TODO(b/110196118): then, trivial---empty---<clinit> could be shrunk.
+ MethodSubject clinit = module.clinit();
+ assertThat(clinit, isPresent());
+ // TODO(b/110196118): if the instantiation in <clinit> is gone, <init> is unreachable and can
+ // be removed by TreePruner.
+ MethodSubject init = module.init(ImmutableList.of());
+ assertThat(init, isPresent());
+ });
+ }
+}
diff --git a/src/test/kotlinR8TestResources/unused_singleton/main.kt b/src/test/kotlinR8TestResources/unused_singleton/main.kt
new file mode 100644
index 0000000..213acb1
--- /dev/null
+++ b/src/test/kotlinR8TestResources/unused_singleton/main.kt
@@ -0,0 +1,15 @@
+// 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 unused_singleton
+
+import unused_singleton.TestModule.provideGreeting
+
+internal object TestModule {
+ @JvmStatic
+ fun provideGreeting() = "Hello"
+}
+
+fun main(args: Array<String>) {
+ println(provideGreeting())
+}