Update nullability tests for local type analysis.

Bug: 69964136
Change-Id: I8c6022f5d01538d8ebc3a45b33069965b06cbb0e
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
index 91d53a2..2fe6685 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
@@ -67,6 +67,7 @@
       //   2) It does not have an out value, so we can skip the env updating.
       if (instruction instanceof Argument) {
         if (argumentsSeen < 0) {
+          // Receiver
           derived = TypeLatticeElement.fromDexType(appInfo, encodedMethod.method.holder, false);
         } else {
           DexType argType = encodedMethod.method.proto.parameters.values[argumentsSeen];
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
index da8772f..d7c9132 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
@@ -7,12 +7,19 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import com.android.tools.r8.ir.code.Argument;
+import com.android.tools.r8.ir.code.ArrayGet;
+import com.android.tools.r8.ir.code.InstanceGet;
+import com.android.tools.r8.ir.code.Instruction;
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.InvokeVirtual;
+import com.android.tools.r8.ir.code.NewInstance;
+import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.smali.SmaliBuilder;
 import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
 import com.android.tools.r8.smali.SmaliTestBase;
@@ -21,6 +28,8 @@
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import java.util.function.BiConsumer;
 import org.junit.Test;
 
@@ -46,6 +55,24 @@
     inspector.accept(appInfo, analysis);
   }
 
+  private static void verifyClassTypeLattice(
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices,
+      DexType receiverType,
+      Value v,
+      TypeLatticeElement l) {
+    assertTrue(l instanceof ClassTypeLatticeElement);
+    ClassTypeLatticeElement lattice = (ClassTypeLatticeElement) l;
+    // Receiver
+    if (lattice.classType.equals(receiverType)) {
+      assertFalse(l.isNullable());
+    } else {
+      TypeLatticeElement expected = expectedLattices.get(v.definition.getClass());
+      if (expected != null) {
+        assertEquals(expected, l);
+      }
+    }
+  }
+
   @Test
   public void nonNullAfterSafeInvokes() throws Exception {
     SmaliBuilder builder = new SmaliBuilder(CLASS_NAME);
@@ -58,20 +85,15 @@
             "throw v0",
             ":not_null",
             "return-void"
-    );
+        );
     buildAndTest(builder, signature, (appInfo, typeAnalysis) -> {
-      typeAnalysis.forEach((v, l) -> {
-        assertTrue(l instanceof ClassTypeLatticeElement);
-        ClassTypeLatticeElement lattice = (ClassTypeLatticeElement) l;
-        if (lattice.classType.equals(appInfo.dexItemFactory.stringType)) {
+      DexType assertionErrorType = appInfo.dexItemFactory.createType("Ljava/lang/AssertionError;");
+      DexType example = appInfo.dexItemFactory.createType("LExample;");
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
           // TODO(b/70795205): Can be refined by using control-flow info.
-          // parameter
-          assertTrue(lattice.isNullable());
-        } else {
-          // holder and newly created assertion error.
-          assertFalse(lattice.isNullable());
-        }
-      });
+          InvokeVirtual.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, true),
+          NewInstance.class, new ClassTypeLatticeElement(assertionErrorType, false));
+      typeAnalysis.forEach((v, l) -> verifyClassTypeLattice(expectedLattices, example, v, l));
     });
   }
 
@@ -91,19 +113,14 @@
             // p1 could be still null at the outside of try-catch.
             "invoke-virtual {p1}, Ljava/lang/String;->hashCode()I",
             "return-void"
-    );
+        );
     buildAndTest(builder, signature, (appInfo, typeAnalysis) -> {
-      typeAnalysis.forEach((v, l) -> {
-        assertTrue(l instanceof ClassTypeLatticeElement);
-        ClassTypeLatticeElement lattice = (ClassTypeLatticeElement) l;
-        if (lattice.classType.equals(appInfo.dexItemFactory.stringType)) {
-          // parameter
-          assertTrue(lattice.isNullable());
-        } else {
-          // holder and newly created assertion error.
-          assertFalse(lattice.isNullable());
-        }
-      });
+      DexType assertionErrorType = appInfo.dexItemFactory.createType("Ljava/lang/AssertionError;");
+      DexType example = appInfo.dexItemFactory.createType("LExample;");
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
+          InvokeVirtual.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, true),
+          NewInstance.class, new ClassTypeLatticeElement(assertionErrorType, false));
+      typeAnalysis.forEach((v, l) -> verifyClassTypeLattice(expectedLattices, example, v, l));
     });
   }
 
@@ -120,24 +137,22 @@
             "throw v0",
             ":not_null",
             "return-void"
-    );
+        );
     buildAndTest(builder, signature, (appInfo, typeAnalysis) -> {
+      DexType assertionErrorType = appInfo.dexItemFactory.createType("Ljava/lang/AssertionError;");
+      DexType example = appInfo.dexItemFactory.createType("LExample;");
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
+          // An element inside a non-null array could be null.
+          ArrayGet.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, true),
+          NewInstance.class, new ClassTypeLatticeElement(assertionErrorType, false));
       typeAnalysis.forEach((v, l) -> {
         if (l instanceof ArrayTypeLatticeElement) {
           ArrayTypeLatticeElement lattice = (ArrayTypeLatticeElement) l;
           assertEquals(appInfo.dexItemFactory.stringType, lattice.elementType);
           // TODO(b/70795205): Can be refined by using control-flow info.
           assertTrue(l.isNullable());
-        }
-        if (l instanceof ClassTypeLatticeElement) {
-          ClassTypeLatticeElement lattice = (ClassTypeLatticeElement) l;
-          if (lattice.classType.equals(appInfo.dexItemFactory.stringType)) {
-            // An element inside a non-null array could be null.
-            assertTrue(lattice.isNullable());
-          } else {
-            // holder and newly created assertion error.
-            assertFalse(lattice.isNullable());
-          }
+        } else if (l instanceof ClassTypeLatticeElement) {
+          verifyClassTypeLattice(expectedLattices, example, v, l);
         }
       });
     });
@@ -160,23 +175,21 @@
             // p1 could be still null at the outside of try-catch.
             "invoke-virtual {p1}, [Ljava/lang/String;->hashCode()I",
             "return-void"
-    );
+        );
     buildAndTest(builder, signature, (appInfo, typeAnalysis) -> {
+      DexType assertionErrorType = appInfo.dexItemFactory.createType("Ljava/lang/AssertionError;");
+      DexType example = appInfo.dexItemFactory.createType("LExample;");
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
+          // An element inside a non-null array could be null.
+          ArrayGet.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, true),
+          NewInstance.class, new ClassTypeLatticeElement(assertionErrorType, false));
       typeAnalysis.forEach((v, l) -> {
         if (l instanceof ArrayTypeLatticeElement) {
           ArrayTypeLatticeElement lattice = (ArrayTypeLatticeElement) l;
           assertEquals(appInfo.dexItemFactory.stringType, lattice.elementType);
           assertTrue(l.isNullable());
-        }
-        if (l instanceof ClassTypeLatticeElement) {
-          ClassTypeLatticeElement lattice = (ClassTypeLatticeElement) l;
-          if (lattice.classType.equals(appInfo.dexItemFactory.stringType)) {
-            // An element inside a non-null array could be null.
-            assertTrue(lattice.isNullable());
-          } else {
-            // holder and newly created assertion error.
-            assertFalse(lattice.isNullable());
-          }
+        } else if (l instanceof ClassTypeLatticeElement) {
+          verifyClassTypeLattice(expectedLattices, example, v, l);
         }
       });
     });
@@ -186,34 +199,28 @@
   public void nonNullAfterSafeFieldAccess() throws Exception {
     SmaliBuilder builder = new SmaliBuilder(CLASS_NAME);
     MethodSignature signature =
-        builder.addInstanceMethod("void", "foo", ImmutableList.of("Test"), 1,
-            "iget-object v0, p1, LTest;->bar:Ljava/lang/String;",
-            // Successful field access above means p1 is not null.
-            "if-nez p1, :not_null",
+        builder.addStaticMethod("void", "foo", ImmutableList.of("Test"), 1,
+            "iget-object v0, p0, LTest;->bar:Ljava/lang/String;",
+            // Successful field access above means p0 is not null.
+            "if-nez p0, :not_null",
             "new-instance v0, Ljava/lang/AssertionError;",
             "throw v0",
             ":not_null",
             "return-void"
-    );
+        );
     builder.addClass("Test");
     builder.addInstanceField("bar", "Ljava/lang/String;");
     buildAndTest(builder, signature, (appInfo, typeAnalysis) -> {
+      DexType assertionErrorType = appInfo.dexItemFactory.createType("Ljava/lang/AssertionError;");
+      DexType example = appInfo.dexItemFactory.createType("LExample;");
       DexType testType = appInfo.dexItemFactory.createType("LTest;");
-      typeAnalysis.forEach((v, l) -> {
-        assertTrue(l instanceof ClassTypeLatticeElement);
-        ClassTypeLatticeElement lattice = (ClassTypeLatticeElement) l;
-        if (lattice.classType.equals(appInfo.dexItemFactory.stringType)) {
-          // instance may not be initialized.
-          assertTrue(lattice.isNullable());
-        } else if (lattice.classType.equals(testType)) {
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
           // TODO(b/70795205): Can be refined by using control-flow info.
-          // parameter
-          assertTrue(lattice.isNullable());
-        } else {
-          // holder and newly created assertion error.
-          assertFalse(lattice.isNullable());
-        }
-      });
+          Argument.class, new ClassTypeLatticeElement(testType, true),
+          // instance may not be initialized.
+          InstanceGet.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, true),
+          NewInstance.class, new ClassTypeLatticeElement(assertionErrorType, false));
+      typeAnalysis.forEach((v, l) -> verifyClassTypeLattice(expectedLattices, example, v, l));
     });
   }
 
@@ -221,37 +228,31 @@
   public void stillNullAfterExceptionCatch_iget() throws Exception {
     SmaliBuilder builder = new SmaliBuilder(CLASS_NAME);
     MethodSignature signature =
-        builder.addInstanceMethod("void", "foo", ImmutableList.of("Test"), 1,
+        builder.addStaticMethod("void", "foo", ImmutableList.of("Test"), 1,
             ":try_start",
-            "iget-object v0, p1, LTest;->bar:Ljava/lang/String;",
-            "if-nez p1, :return",
+            "iget-object v0, p0, LTest;->bar:Ljava/lang/String;",
+            "if-nez p0, :return",
             "new-instance v0, Ljava/lang/AssertionError;",
             "throw v0",
             ":try_end",
             ".catch Ljava/lang/Throwable; {:try_start .. :try_end} :return",
             ":return",
-            // p1 could be still null at the outside of try-catch.
-            "invoke-virtual {p1}, LTest;->hashCode()I",
+            // p0 could be still null at the outside of try-catch.
+            "invoke-virtual {p0}, LTest;->hashCode()I",
             "return-void"
-    );
+        );
     builder.addClass("Test");
     builder.addInstanceField("bar", "Ljava/lang/String;");
     buildAndTest(builder, signature, (appInfo, typeAnalysis) -> {
+      DexType assertionErrorType = appInfo.dexItemFactory.createType("Ljava/lang/AssertionError;");
+      DexType example = appInfo.dexItemFactory.createType("LExample;");
       DexType testType = appInfo.dexItemFactory.createType("LTest;");
-      typeAnalysis.forEach((v, l) -> {
-        assertTrue(l instanceof ClassTypeLatticeElement);
-        ClassTypeLatticeElement lattice = (ClassTypeLatticeElement) l;
-        if (lattice.classType.equals(appInfo.dexItemFactory.stringType)) {
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
+          Argument.class, new ClassTypeLatticeElement(testType, true),
           // instance may not be initialized.
-          assertTrue(lattice.isNullable());
-        } else if (lattice.classType.equals(testType)) {
-          // parameter
-          assertTrue(lattice.isNullable());
-        } else {
-          // holder and newly created assertion error.
-          assertFalse(lattice.isNullable());
-        }
-      });
+          InstanceGet.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, true),
+          NewInstance.class, new ClassTypeLatticeElement(assertionErrorType, false));
+      typeAnalysis.forEach((v, l) -> verifyClassTypeLattice(expectedLattices, example, v, l));
     });
   }
 }
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
index 9bd8af6..c39d347 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
@@ -38,7 +38,7 @@
 import com.android.tools.r8.utils.Smali;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
+import com.google.common.collect.ImmutableMap;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -280,29 +280,18 @@
                 new MethodSignature("a", "void",
                     ImmutableList.of("Test", "Test", "Test", "Test")))
             .getMethod();
-
     DexType test = appInfo.dexItemFactory.createType("LTest;");
-    Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = Maps.newHashMap();
-    expectedLattices.put(ArrayLength.class, PRIMITIVE);
-    expectedLattices.put(ConstNumber.class, PRIMITIVE);
-    expectedLattices.put(
-        ConstString.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, false));
-    expectedLattices.put(CheckCast.class, new ClassTypeLatticeElement(test, true));
-    expectedLattices.put(NewInstance.class, new ClassTypeLatticeElement(test, false));
-
+    Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
+        ArrayLength.class, PRIMITIVE,
+        ConstNumber.class, PRIMITIVE,
+        ConstString.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, false),
+        CheckCast.class, new ClassTypeLatticeElement(test, true),
+        NewInstance.class, new ClassTypeLatticeElement(test, false));
     try {
       IRCode irCode = method.buildIR(TEST_OPTIONS);
       TypeAnalysis analysis = new TypeAnalysis(appInfo, method, irCode);
       analysis.run();
-      analysis.forEach((v, l) -> {
-        if (v.definition == null) {
-          return;
-        }
-        TypeLatticeElement expected = expectedLattices.get(v.definition.getClass());
-        if (expected != null) {
-          assertEquals(expected, l);
-        }
-      });
+      analysis.forEach((v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
     } catch (ApiLevelException e) {
       fail(e.getMessage());
     }
@@ -316,30 +305,32 @@
             .method(
                 new MethodSignature("onClick", "void", ImmutableList.of("Test")))
             .getMethod();
-
     DexType test = appInfo.dexItemFactory.createType("LTest;");
-    Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = Maps.newHashMap();
-    expectedLattices.put(ConstNumber.class, PRIMITIVE);
-    expectedLattices.put(
-        ConstString.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, false));
-    expectedLattices.put(InstanceOf.class, PRIMITIVE);
-    expectedLattices.put(StaticGet.class, new ClassTypeLatticeElement(test, true));
-
+    Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
+      ConstNumber.class, PRIMITIVE,
+      ConstString.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, false),
+      InstanceOf.class, PRIMITIVE,
+      StaticGet.class, new ClassTypeLatticeElement(test, true));
     try {
       IRCode irCode = method.buildIR(TEST_OPTIONS);
       TypeAnalysis analysis = new TypeAnalysis(appInfo, method, irCode);
       analysis.run();
-      analysis.forEach((v, l) -> {
-        if (v.definition == null) {
-          return;
-        }
-        TypeLatticeElement expected = expectedLattices.get(v.definition.getClass());
-        if (expected != null) {
-          assertEquals(expected, l);
-        }
-      });
+      analysis.forEach((v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
     } catch (ApiLevelException e) {
       fail(e.getMessage());
     }
   }
+
+  private static void verifyTypeEnvironment(
+      Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices,
+      Value v,
+      TypeLatticeElement l) {
+    if (v.definition == null) {
+      return;
+    }
+    TypeLatticeElement expected = expectedLattices.get(v.definition.getClass());
+    if (expected != null) {
+      assertEquals(expected, l);
+    }
+  }
 }