Refactor Kotlin tests.

* com.android.tools.r8.KotlinTestBase
- the top-level abstraction that defines where to load .kt/.java jar.

Some recently added tests that exercise high-level behavior,
such as stripping off @Metadata if not used, reprocessing lambda groups,
etc., have been using this.

* com.android.tools.r8.kotlin.AbstractR8KotlinTestBase
- with utils that check if certain items are kept, inlined, removed
as expected.

This existing base class has been used for testing expected behaviors
of Kotlin-specific optimizations, such as class inliner, staticizer,
Intrinsics inlining, etc.

* com.android.tools.r8.naming.AbstractR8KotlinNamingTestBase
- extends AbstractR8KotlinTestBase with renaming-related utils.

------

This CL also adds very basic renaming tests for Kotlin Intrinsics null
checks. While investigating b/126056766, observed some utils in
Intrinsics that receive class/member identifiers to check if known-to-
return-non-null methods indeed returned non-null values or if known-to-
be-non-null fields are indeed non-null. Those are added only for Java
libraries, which we don't rename. Thus, no need to rename such
identifiers. Only tested non-pinned items are all renamed as expected.

Change-Id: I282d03024d336941506703f171ef8695b9ca23eb
diff --git a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
index 19c931e..b722683 100644
--- a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
+++ b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
@@ -4,15 +4,18 @@
 
 package com.android.tools.r8.kotlin;
 
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import com.android.tools.r8.KotlinTestBase;
 import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.R8Command;
-import com.android.tools.r8.TestBase;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.graph.Code;
@@ -24,7 +27,6 @@
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -32,7 +34,6 @@
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import com.google.common.collect.ImmutableList;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -42,63 +43,65 @@
 import org.junit.Assume;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public abstract class AbstractR8KotlinTestBase extends TestBase {
+public abstract class AbstractR8KotlinTestBase extends KotlinTestBase {
 
   // This is the name of the Jasmin-generated class which contains the "main" method which will
   // invoke the tested method.
   private static final String JASMIN_MAIN_CLASS = "TestMain";
 
-  @Parameter(0) public boolean allowAccessModification;
-  @Parameter(1) public KotlinTargetVersion targetVersion;
+  protected final boolean allowAccessModification;
 
   private final List<Path> classpath = new ArrayList<>();
   private final List<Path> extraClasspath = new ArrayList<>();
 
-  @Parameters(name = "allowAccessModification: {0} target: {1}")
+  @Parameterized.Parameters(name = "target: {0}, allowAccessModification: {1}")
   public static Collection<Object[]> data() {
-    return buildParameters(BooleanUtils.values(), KotlinTargetVersion.values());
+    return buildParameters(KotlinTargetVersion.values(), BooleanUtils.values());
+  }
+
+  protected AbstractR8KotlinTestBase(
+      KotlinTargetVersion kotlinTargetVersion, boolean allowAccessModification) {
+    super(kotlinTargetVersion);
+    this.allowAccessModification = allowAccessModification;
   }
 
   protected void addExtraClasspath(Path path) {
     extraClasspath.add(path);
   }
 
-  protected static void checkMethodIsInvokedAtLeastOnce(DexCode dexCode,
-      MethodSignature... methodSignatures) {
+  protected static void checkMethodIsInvokedAtLeastOnce(
+      DexCode dexCode, MethodSignature... methodSignatures) {
     for (MethodSignature methodSignature : methodSignatures) {
       checkMethodIsInvokedAtLeastOnce(dexCode, methodSignature);
     }
   }
 
-  private static void checkMethodIsInvokedAtLeastOnce(DexCode dexCode,
-      MethodSignature methodSignature) {
+  private static void checkMethodIsInvokedAtLeastOnce(
+      DexCode dexCode, MethodSignature methodSignature) {
     assertTrue("No invoke to '" + methodSignature.toString() + "'",
         Arrays.stream(dexCode.instructions)
             .filter((instr) -> instr.getMethod() != null)
             .anyMatch((instr) -> instr.getMethod().name.toString().equals(methodSignature.name)));
   }
 
-  protected static void checkMethodIsNeverInvoked(DexCode dexCode,
-      MethodSignature... methodSignatures) {
+  protected static void checkMethodIsNeverInvoked(
+      DexCode dexCode, MethodSignature... methodSignatures) {
     for (MethodSignature methodSignature : methodSignatures) {
       checkMethodIsNeverInvoked(dexCode, methodSignature);
     }
   }
 
-  private static void checkMethodIsNeverInvoked(DexCode dexCode,
-      MethodSignature methodSignature) {
+  private static void checkMethodIsNeverInvoked(DexCode dexCode, MethodSignature methodSignature) {
     assertTrue("At least one invoke to '" + methodSignature.toString() + "'",
         Arrays.stream(dexCode.instructions)
             .filter((instr) -> instr.getMethod() != null)
             .noneMatch((instr) -> instr.getMethod().name.toString().equals(methodSignature.name)));
   }
 
-  protected static void checkMethodsPresence(ClassSubject classSubject,
-      Map<MethodSignature, Boolean> presenceMap) {
+  protected static void checkMethodsPresence(
+      ClassSubject classSubject, Map<MethodSignature, Boolean> presenceMap) {
     presenceMap.forEach(((methodSignature, isPresent) -> {
       MethodSubject methodSubject = classSubject.method(methodSignature);
       String methodDesc = methodSignature.toString();
@@ -118,8 +121,8 @@
     return classSubject;
   }
 
-  protected FieldSubject checkFieldIsKept(ClassSubject classSubject, String fieldType,
-      String fieldName) {
+  protected FieldSubject checkFieldIsKept(
+      ClassSubject classSubject, String fieldType, String fieldName) {
     // Field must exist in the input.
     checkFieldPresenceInInput(classSubject.getOriginalName(), fieldType, fieldName, true);
     FieldSubject fieldSubject = classSubject.field(fieldType, fieldName);
@@ -128,8 +131,13 @@
     return fieldSubject;
   }
 
-  protected void checkFieldIsAbsent(ClassSubject classSubject, String fieldType,
-      String fieldName) {
+  protected FieldSubject checkFieldIsKept(ClassSubject classSubject, String fieldName) {
+    FieldSubject fieldSubject = classSubject.uniqueFieldWithName(fieldName);
+    assertThat(fieldSubject, isPresent());
+    return fieldSubject;
+  }
+
+  protected void checkFieldIsAbsent(ClassSubject classSubject, String fieldType, String fieldName) {
     // Field must NOT exist in the input.
     checkFieldPresenceInInput(classSubject.getOriginalName(), fieldType, fieldName, false);
     FieldSubject fieldSubject = classSubject.field(fieldType, fieldName);
@@ -137,32 +145,47 @@
     assertFalse(fieldSubject.isPresent());
   }
 
-  protected void checkMethodIsAbsent(ClassSubject classSubject,
-      MethodSignature methodSignature) {
+  protected FieldSubject checkFieldIsAbsent(ClassSubject classSubject, String fieldName) {
+    FieldSubject fieldSubject = classSubject.uniqueFieldWithName(fieldName);
+    assertThat(fieldSubject, not(isPresent()));
+    return fieldSubject;
+  }
+
+  protected void checkMethodIsAbsent(ClassSubject classSubject, MethodSignature methodSignature) {
     checkMethodPresenceInInput(classSubject.getOriginalName(), methodSignature, false);
     checkMethodPresenceInOutput(classSubject, methodSignature, false);
   }
 
-  protected MethodSubject checkMethodIsKept(ClassSubject classSubject,
-      MethodSignature methodSignature) {
+  protected MethodSubject checkMethodIsKept(
+      ClassSubject classSubject, MethodSignature methodSignature) {
     checkMethodPresenceInInput(classSubject.getOriginalName(), methodSignature, true);
     return checkMethodIsKeptOrRemoved(classSubject, methodSignature, true);
   }
 
-  protected void checkMethodIsRemoved(ClassSubject classSubject,
-      MethodSignature methodSignature) {
+  protected MethodSubject checkMethodIsKept(ClassSubject classSubject, String methodName) {
+    MethodSubject methodSubject = classSubject.uniqueMethodWithName(methodName);
+    assertThat(methodSubject, isPresent());
+    return methodSubject;
+  }
+
+  protected void checkMethodIsRemoved(ClassSubject classSubject, MethodSignature methodSignature) {
     checkMethodPresenceInInput(classSubject.getOriginalName(), methodSignature, true);
     checkMethodIsKeptOrRemoved(classSubject, methodSignature, false);
   }
 
-  protected MethodSubject checkMethodIsKeptOrRemoved(ClassSubject classSubject,
-      MethodSignature methodSignature, boolean isPresent) {
+  protected void checkMethodIsRemoved(ClassSubject classSubject, String methodName) {
+    MethodSubject methodSubject = classSubject.uniqueMethodWithName(methodName);
+    assertThat(methodSubject, not(isPresent()));
+  }
+
+  protected MethodSubject checkMethodIsKeptOrRemoved(
+      ClassSubject classSubject, MethodSignature methodSignature, boolean isPresent) {
     checkMethodPresenceInInput(classSubject.getOriginalName(), methodSignature, true);
     return checkMethodPresenceInOutput(classSubject, methodSignature, isPresent);
   }
 
-  private MethodSubject checkMethodPresenceInOutput(ClassSubject classSubject,
-      MethodSignature methodSignature, boolean isPresent) {
+  private MethodSubject checkMethodPresenceInOutput(
+      ClassSubject classSubject, MethodSignature methodSignature, boolean isPresent) {
     MethodSubject methodSubject = classSubject.method(methodSignature);
     assertNotNull(methodSubject);
 
@@ -272,8 +295,8 @@
     }
   }
 
-  private void checkMethodPresenceInInput(String className, MethodSignature methodSignature,
-      boolean isPresent) {
+  private void checkMethodPresenceInInput(
+      String className, MethodSignature methodSignature, boolean isPresent) {
     boolean foundMethod = AsmUtils.doesMethodExist(classpath, className,
         methodSignature.name, methodSignature.toDescriptor());
     if (isPresent != foundMethod) {
@@ -285,8 +308,8 @@
     }
   }
 
-  private void checkFieldPresenceInInput(String className, String fieldType, String fieldName,
-      boolean isPresent) {
+  private void checkFieldPresenceInInput(
+      String className, String fieldType, String fieldName, boolean isPresent) {
     boolean foundField = AsmUtils.doesFieldExist(classpath, className, fieldName, fieldType);
     if (isPresent != foundField) {
       throw new AssertionError(
@@ -296,18 +319,8 @@
     }
   }
 
-  private Path getKotlinJarFile(String folder) {
-    return Paths.get(ToolHelper.TESTS_BUILD_DIR, "kotlinR8TestResources",
-        targetVersion.getFolderName(), folder + FileUtils.JAR_EXTENSION);
-  }
-
-  private Path getJavaJarFile(String folder) {
-    return Paths.get(ToolHelper.TESTS_BUILD_DIR, "kotlinR8TestResources",
-        targetVersion.getFolderName(), folder + ".java" + FileUtils.JAR_EXTENSION);
-  }
-
   @FunctionalInterface
-  interface AndroidAppInspector {
+  public interface AndroidAppInspector {
 
     void inspectApp(AndroidApp androidApp) throws Exception;
   }
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
index 1a690e2..30d90eb 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
@@ -10,6 +10,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.code.NewInstance;
 import com.android.tools.r8.code.SgetObject;
 import com.android.tools.r8.graph.DexClass;
@@ -33,6 +34,11 @@
 
 public class KotlinClassInlinerTest extends AbstractR8KotlinTestBase {
 
+  public KotlinClassInlinerTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   private static boolean isLambda(DexClass clazz) {
     return !clazz.type.getPackageDescriptor().startsWith("kotlin") &&
         (isKStyleLambdaOrGroup(clazz) || isJStyleLambdaOrGroup(clazz));
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java
index ced08f5..3f02c70 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinClassStaticizerTest.java
@@ -9,6 +9,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -16,6 +17,11 @@
 
 public class KotlinClassStaticizerTest extends AbstractR8KotlinTestBase {
 
+  public KotlinClassStaticizerTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void testCompanionAndRegularObjects() throws Exception {
     assumeTrue("Only work with -allowaccessmodification", allowAccessModification);
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java
index 7e9269d..0b79b3b 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingTest.java
@@ -9,6 +9,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.fail;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.optimize.lambda.CaptureSignature;
@@ -39,6 +40,11 @@
         opts.forceProguardCompatibility = true;
       };
 
+  public KotlinLambdaMergingTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   abstract static class LambdaOrGroup {
     abstract boolean match(DexClass clazz);
   }
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithReprocessingTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithReprocessingTest.java
index 343dfdf..7b43112 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithReprocessingTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithReprocessingTest.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.kotlin;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.utils.InternalOptions;
 import java.util.function.Consumer;
 import org.junit.Test;
@@ -17,6 +18,11 @@
       o.enableLambdaMerging = true;
     };
 
+  public KotlinLambdaMergingWithReprocessingTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void testMergingKStyleLambdasAndReprocessing() throws Exception {
     final String mainClassName = "reprocess_merged_lambdas_kstyle.MainKt";
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithSmallInliningBudgetTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithSmallInliningBudgetTest.java
index ba11914..c5ee56d 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithSmallInliningBudgetTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinLambdaMergingWithSmallInliningBudgetTest.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.kotlin;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.utils.InternalOptions;
 import java.util.function.Consumer;
 import org.junit.Test;
@@ -18,6 +19,11 @@
         o.inliningInstructionAllowance = 3;
       };
 
+  public KotlinLambdaMergingWithSmallInliningBudgetTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void testJStyleRunnable() throws Exception {
     final String mainClassName = "lambdas_jstyle_runnable.MainKt";
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
index 1515689..0048b1b 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
@@ -9,6 +9,7 @@
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.jasmin.JasminBuilder;
 import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
@@ -64,6 +65,11 @@
   private Consumer<InternalOptions> disableClassStaticizer =
       opts -> opts.enableClassStaticizer = false;
 
+  public R8KotlinAccessorTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void testCompanionProperty_primitivePropertyIsAlwaysInlined() throws Exception {
     final TestKotlinCompanionClass testedClass = COMPANION_PROPERTY_CLASS;
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
index 9224405..7e16b2f 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.kotlin;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.kotlin.TestKotlinClass.Visibility;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
@@ -37,6 +38,11 @@
 
   private Consumer<InternalOptions> disableClassInliner = o -> o.enableClassInlining = false;
 
+  public R8KotlinDataClassTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void test_dataclass_gettersOnly() throws Exception {
     final String mainClassName = "dataclass.MainGettersOnlyKt";
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
index c90df04..c74b790 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.kotlin;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -20,6 +21,11 @@
   private static final TestKotlinDataClass KOTLIN_INTRINSICS_CLASS =
       new TestKotlinDataClass("kotlin.jvm.internal.Intrinsics");
 
+  public R8KotlinIntrinsicsTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void testParameterNullCheckIsInlined() throws Exception {
     final String extraRules = keepClassMethod("intrinsics.IntrinsicsKt",
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
index bc23757..d310c6e 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
@@ -6,6 +6,7 @@
 
 import static org.junit.Assert.assertTrue;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.kotlin.TestKotlinClass.KotlinProperty;
 import com.android.tools.r8.kotlin.TestKotlinClass.Visibility;
 import com.android.tools.r8.naming.MemberNaming;
@@ -90,6 +91,11 @@
         o.enableClassStaticizer = false;
       };
 
+  public R8KotlinPropertiesTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void testMutableProperty_getterAndSetterAreRemoveIfNotUsed() throws Exception {
     String mainClass = addMainToClasspath("properties/MutablePropertyKt",
diff --git a/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java b/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
index 0ebc393..b4b0c06 100644
--- a/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
@@ -5,6 +5,7 @@
 
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -18,6 +19,11 @@
   private static final String FOLDER = "non_null";
   private static final String STRING = "java.lang.String";
 
+  public SimplifyIfNotNullKotlinTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification) {
+    super(targetVersion, allowAccessModification);
+  }
+
   @Test
   public void test_example1() throws Exception {
     final TestKotlinClass ex1 = new TestKotlinClass("non_null.Example1Kt");
diff --git a/src/test/java/com/android/tools/r8/kotlin/TestKotlinClass.java b/src/test/java/com/android/tools/r8/kotlin/TestKotlinClass.java
index 685df6a..d135bf9 100644
--- a/src/test/java/com/android/tools/r8/kotlin/TestKotlinClass.java
+++ b/src/test/java/com/android/tools/r8/kotlin/TestKotlinClass.java
@@ -16,7 +16,7 @@
  *
  * <p>See https://kotlinlang.org/docs/reference/classes.html</p>
  */
-class TestKotlinClass {
+public class TestKotlinClass {
 
   /**
    * This is the suffix appended by Kotlin compiler to getter and setter method names of
diff --git a/src/test/java/com/android/tools/r8/naming/AbstractR8KotlinNamingTestBase.java b/src/test/java/com/android/tools/r8/naming/AbstractR8KotlinNamingTestBase.java
new file mode 100644
index 0000000..bb9af02
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/AbstractR8KotlinNamingTestBase.java
@@ -0,0 +1,106 @@
+// 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;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.kotlin.AbstractR8KotlinTestBase;
+import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.utils.BooleanUtils;
+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.util.Collection;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public abstract class AbstractR8KotlinNamingTestBase extends AbstractR8KotlinTestBase {
+
+  protected final boolean minification;
+
+  @Parameters(name = "target: {0}, allowAccessModification: {1}, minification: {2}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        KotlinTargetVersion.values(), BooleanUtils.values(), BooleanUtils.values());
+  }
+
+  AbstractR8KotlinNamingTestBase(
+      KotlinTargetVersion kotlinTargetVersion,
+      boolean allowAccessModification,
+      boolean minification) {
+    super(kotlinTargetVersion, allowAccessModification);
+    this.minification = minification;
+  }
+
+  protected ClassSubject checkClassIsRenamed(CodeInspector inspector, String className) {
+    ClassSubject classSubject = inspector.clazz(className);
+    assertThat(classSubject, isRenamed());
+    return classSubject;
+  }
+
+  protected ClassSubject checkClassIsNotRenamed(CodeInspector inspector, String className) {
+    ClassSubject classSubject = inspector.clazz(className);
+    assertThat(classSubject, not(isRenamed()));
+    return classSubject;
+  }
+
+  protected FieldSubject checkFieldIsRenamed(
+      ClassSubject classSubject, String fieldType, String fieldName) {
+    FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldType, fieldName);
+    assertThat(fieldSubject, isRenamed());
+    return fieldSubject;
+  }
+
+  protected FieldSubject checkFieldIsRenamed(ClassSubject classSubject, String fieldName) {
+    FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldName);
+    assertThat(fieldSubject, isRenamed());
+    return fieldSubject;
+  }
+
+  protected FieldSubject checkFieldIsNotRenamed(
+      ClassSubject classSubject, String fieldType, String fieldName) {
+    FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldType, fieldName);
+    assertThat(fieldSubject, not(isRenamed()));
+    return fieldSubject;
+  }
+
+  protected FieldSubject checkFieldIsNotRenamed(ClassSubject classSubject, String fieldName) {
+    FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldName);
+    assertThat(fieldSubject, not(isRenamed()));
+    return fieldSubject;
+  }
+
+  protected MethodSubject checkMethodIsRenamed(
+      ClassSubject classSubject, MethodSignature methodSignature) {
+    MethodSubject methodSubject = checkMethodIsKept(classSubject, methodSignature);
+    assertThat(methodSubject, isRenamed());
+    return methodSubject;
+  }
+
+  protected MethodSubject checkMethodIsRenamed(ClassSubject classSubject, String methodName) {
+    MethodSubject methodSubject = checkMethodIsKept(classSubject, methodName);
+    assertThat(methodSubject, isRenamed());
+    return methodSubject;
+  }
+
+  protected MethodSubject checkMethodIsNotRenamed(
+      ClassSubject classSubject, MethodSignature methodSignature) {
+    MethodSubject methodSubject = checkMethodIsKept(classSubject, methodSignature);
+    assertThat(methodSubject, not(isRenamed()));
+    return methodSubject;
+  }
+
+  protected MethodSubject checkMethodIsNotRenamed(ClassSubject classSubject, String methodName) {
+    MethodSubject methodSubject = checkMethodIsKept(classSubject, methodName);
+    assertThat(methodSubject, not(isRenamed()));
+    return methodSubject;
+  }
+
+}
diff --git a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
new file mode 100644
index 0000000..aa2e69d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
@@ -0,0 +1,150 @@
+// 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;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.TestCompileResult;
+import com.android.tools.r8.TestRunResult;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.kotlin.TestKotlinClass;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+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 java.util.Arrays;
+import java.util.Iterator;
+import java.util.stream.Collectors;
+import org.junit.Test;
+
+public class KotlinIntrinsicsIdentifierTest extends AbstractR8KotlinNamingTestBase {
+  private static final String FOLDER = "intrinsics_identifiers";
+
+  public KotlinIntrinsicsIdentifierTest(
+      KotlinTargetVersion targetVersion, boolean allowAccessModification, boolean minification) {
+    super(targetVersion, allowAccessModification, minification);
+  }
+
+  @Test
+  public void test_example1() throws Exception {
+    TestKotlinClass ex1 = new TestKotlinClass("intrinsics_identifiers.Example1Kt");
+    String targetClassName = "ToBeRenamedClass";
+    String targetFieldName = "toBeRenamedField";
+    String targetMethodName = "toBeRenamedMethod";
+    test(ex1, targetClassName, targetFieldName, targetMethodName);
+  }
+
+  @Test
+  public void test_example2() throws Exception {
+    TestKotlinClass ex2 = new TestKotlinClass("intrinsics_identifiers.Example2Kt");
+    String targetClassName = "AnotherClass";
+    String targetFieldName = "anotherField";
+    String targetMethodName = "anotherMethod";
+    test(ex2, targetClassName, targetFieldName, targetMethodName);
+  }
+
+  @Test
+  public void test_example3() throws Exception {
+    TestKotlinClass ex3 = new TestKotlinClass("intrinsics_identifiers.Example3Kt");
+    String mainClassName = ex3.getClassName();
+    TestCompileResult result = testForR8(Backend.DEX)
+        .addProgramFiles(getKotlinJarFile(FOLDER))
+        .addProgramFiles(getJavaJarFile(FOLDER))
+        .addKeepMainRule(mainClassName)
+        .minification(minification)
+        .compile();
+    CodeInspector codeInspector = result.inspector();
+    MethodSubject main = codeInspector.clazz(ex3.getClassName()).mainMethod();
+    assertThat(main, isPresent());
+    verifyKotlinIntrinsicsRenamed(codeInspector, main);
+  }
+
+  private void verifyKotlinIntrinsicsRenamed(CodeInspector inspector, MethodSubject main) {
+    Iterator<InstructionSubject> it = main.iterateInstructions(InstructionSubject::isInvokeStatic);
+    assertTrue(it.hasNext());
+    boolean metKotlinIntrinsicsNullChecks = false;
+    while (it.hasNext()) {
+      DexMethod invokedMethod = it.next().getMethod();
+      if (invokedMethod.getHolder().toSourceString().contains("java.net")) {
+        continue;
+      }
+      ClassSubject invokedMethodHolderSubject =
+          inspector.clazz(invokedMethod.getHolder().toSourceString());
+      assertThat(invokedMethodHolderSubject, isPresent());
+      assertEquals(minification, invokedMethodHolderSubject.isRenamed());
+      MethodSubject invokedMethodSubject = invokedMethodHolderSubject.method(
+          invokedMethod.proto.returnType.toSourceString(),
+          invokedMethod.name.toString(),
+          Arrays.stream(invokedMethod.proto.parameters.values)
+              .map(DexType::toSourceString)
+              .collect(Collectors.toList()));
+      assertThat(invokedMethodSubject, isPresent());
+      assertEquals(minification, invokedMethodSubject.isRenamed());
+      if (invokedMethodSubject.getOriginalName().startsWith("check")
+          && invokedMethodSubject.getOriginalName().endsWith("Null")
+          && invokedMethodHolderSubject.getOriginalDescriptor()
+              .contains("kotlin/jvm/internal/Intrinsics")) {
+        metKotlinIntrinsicsNullChecks = true;
+      }
+    }
+    assertTrue(metKotlinIntrinsicsNullChecks);
+  }
+
+  private void test(
+      TestKotlinClass testMain,
+      String targetClassName,
+      String targetFieldName,
+      String targetMethodName) throws Exception {
+    String mainClassName = testMain.getClassName();
+    TestRunResult result = testForR8(Backend.DEX)
+        .addProgramFiles(getKotlinJarFile(FOLDER))
+        .addProgramFiles(getJavaJarFile(FOLDER))
+        .enableProguardTestOptions()
+        .addKeepMainRule(mainClassName)
+        .addKeepRules(StringUtils.lines(
+            "-neverclassinline class **." + targetClassName,
+            "-nevermerge class **." + targetClassName,
+            "-neverinline class **." + targetClassName + " { <methods>; }"
+        ))
+        .minification(minification)
+        .run(mainClassName);
+    CodeInspector codeInspector = result.inspector();
+
+    MethodSubject main = codeInspector.clazz(testMain.getClassName()).mainMethod();
+    assertThat(main, isPresent());
+    verifyKotlinIntrinsicsRenamed(codeInspector, main);
+    // Examine all const-string and verify that identifiers are not introduced.
+    Iterator<InstructionSubject> it =
+        main.iterateInstructions(i -> i.isConstString(JumboStringMode.ALLOW));
+    assertTrue(it.hasNext());
+    while (it.hasNext()) {
+      String identifier = it.next().getConstString();
+      if (identifier.contains("arg")) {
+        continue;
+      }
+      assertEquals(!minification, identifier.equals(targetMethodName));
+      assertEquals(!minification, identifier.equals(targetFieldName));
+    }
+
+    targetClassName = FOLDER + "." + targetClassName;
+    ClassSubject clazz = minification
+        ? checkClassIsRenamed(codeInspector, targetClassName)
+        : checkClassIsNotRenamed(codeInspector, targetClassName);
+    if (minification) {
+      checkFieldIsRenamed(clazz, targetFieldName);
+      checkMethodIsRenamed(clazz, targetMethodName);
+    } else {
+      checkFieldIsNotRenamed(clazz, targetFieldName);
+      checkMethodIsNotRenamed(clazz, targetMethodName);
+    }
+  }
+
+}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java
index 94a779b..5f1b405 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java
@@ -142,6 +142,14 @@
   }
 
   @Override
+  public String getConstString() {
+    if (instruction instanceof CfConstString) {
+      return ((CfConstString) instruction).getString().toSourceString();
+    }
+    return null;
+  }
+
+  @Override
   public boolean isConstClass() {
     return instruction instanceof CfConstClass;
   }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java
index 60ad731..ba23a0a 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java
@@ -252,6 +252,17 @@
   }
 
   @Override
+  public String getConstString() {
+    if (instruction instanceof ConstString) {
+      return ((ConstString) instruction).BBBB.toSourceString();
+    }
+    if (instruction instanceof ConstStringJumbo) {
+      return ((ConstStringJumbo) instruction).BBBBBBBB.toSourceString();
+    }
+    return null;
+  }
+
+  @Override
   public boolean isConstClass() {
     return instruction instanceof ConstClass;
   }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
index 7a272c7..f2eb753 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
@@ -48,6 +48,8 @@
 
   boolean isConstString(String value, JumboStringMode jumboStringMode);
 
+  String getConstString();
+
   boolean isConstClass();
 
   boolean isConstClass(String type);
diff --git a/src/test/kotlinR8TestResources/intrinsics_identifiers/ToBeRenamedClass.java b/src/test/kotlinR8TestResources/intrinsics_identifiers/ToBeRenamedClass.java
new file mode 100644
index 0000000..6218d16
--- /dev/null
+++ b/src/test/kotlinR8TestResources/intrinsics_identifiers/ToBeRenamedClass.java
@@ -0,0 +1,14 @@
+// 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 intrinsics_identifiers;
+
+class ToBeRenamedClass {
+  String toBeRenamedField = "SUFFIX";
+  String toBeRenamedMethod(String arg) {
+    return arg + toBeRenamedField;
+  }
+  void updateField(String arg) {
+    toBeRenamedField = arg;
+  }
+}
diff --git a/src/test/kotlinR8TestResources/intrinsics_identifiers/example1.kt b/src/test/kotlinR8TestResources/intrinsics_identifiers/example1.kt
new file mode 100644
index 0000000..4409232
--- /dev/null
+++ b/src/test/kotlinR8TestResources/intrinsics_identifiers/example1.kt
@@ -0,0 +1,17 @@
+// 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 intrinsics_identifiers
+
+fun main(args: Array<String>) {
+  val instance = ToBeRenamedClass()
+  println(instance.toBeRenamedField)
+  println(instance.toBeRenamedMethod("arg1"))
+
+  if (instance.toBeRenamedField.equals("arg2")) {
+    instance.updateField("arg3")
+    println(instance.toBeRenamedField)
+    println(instance.toBeRenamedMethod("arg4"))
+  }
+}
+
diff --git a/src/test/kotlinR8TestResources/intrinsics_identifiers/example2.kt b/src/test/kotlinR8TestResources/intrinsics_identifiers/example2.kt
new file mode 100644
index 0000000..c6c5e09
--- /dev/null
+++ b/src/test/kotlinR8TestResources/intrinsics_identifiers/example2.kt
@@ -0,0 +1,27 @@
+// 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 intrinsics_identifiers
+
+class AnotherClass {
+  var anotherField : String = "PREFIX"
+  fun anotherMethod(arg: String) : String {
+    return anotherField + arg
+  }
+  fun updateField(arg: String) : Unit {
+    anotherField = arg
+  }
+}
+
+fun main(args: Array<String>) {
+  val instance = AnotherClass()
+  println(instance.anotherField)
+  println(instance.anotherMethod("arg1"))
+
+  if (instance.anotherField.equals("arg2")) {
+    instance.updateField("arg3")
+    println(instance.anotherField)
+    println(instance.anotherMethod("arg4"))
+  }
+}
+
diff --git a/src/test/kotlinR8TestResources/intrinsics_identifiers/example3.kt b/src/test/kotlinR8TestResources/intrinsics_identifiers/example3.kt
new file mode 100644
index 0000000..47b1d00
--- /dev/null
+++ b/src/test/kotlinR8TestResources/intrinsics_identifiers/example3.kt
@@ -0,0 +1,14 @@
+// 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 intrinsics_identifiers
+
+import java.net.URI
+
+fun main(args: Array<String>) {
+  // By specifying non-null type of variables for library uses,
+  // kotlin.jvm.internal.Intrinsics#check*Null(...) is added by kotlinc.
+  val uri : URI = URI.create("google.com")
+  val host : String = uri.host
+  println(host)
+}
\ No newline at end of file