Migrate utils to create constant replacement to AbstractValue.

Bug: 69963623
Change-Id: Id94d5a8e071077c59a99936e18b65e606d100ab5
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
index 32e2621..eae4fc8 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
@@ -11,7 +11,11 @@
    * concretization of this abstract value has size 1).
    */
   public boolean isSingleValue() {
-    return isSingleEnumValue() || isSingleNumberValue() || isSingleStringValue();
+    return false;
+  }
+
+  public SingleValue asSingleValue() {
+    return null;
   }
 
   public boolean isSingleEnumValue() {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
index a9050ef..8573c36 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
@@ -4,9 +4,15 @@
 
 package com.android.tools.r8.ir.analysis.value;
 
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
 
-public class SingleEnumValue extends AbstractValue {
+public class SingleEnumValue extends SingleValue {
 
   private final DexField field;
 
@@ -34,4 +40,12 @@
   public int hashCode() {
     return System.identityHashCode(this);
   }
+
+  @Override
+  public Instruction createMaterializingInstruction(
+      AppView<? extends AppInfoWithSubtyping> appView,
+      IRCode code,
+      TypeAndLocalInfoSupplier info) {
+    throw new Unreachable("unless we store single enum as a method's returned value.");
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
index 914516a..949dbb5 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
@@ -4,7 +4,17 @@
 
 package com.android.tools.r8.ir.analysis.value;
 
-public class SingleNumberValue extends AbstractValue {
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DebugLocalInfo;
+import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.code.ConstNumber;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
+import com.android.tools.r8.ir.code.Value;
+
+public class SingleNumberValue extends SingleValue {
 
   private final long value;
 
@@ -36,4 +46,16 @@
   public int hashCode() {
     return System.identityHashCode(this);
   }
+
+  @Override
+  public Instruction createMaterializingInstruction(
+      AppView<? extends AppInfoWithSubtyping> appView, IRCode code, TypeAndLocalInfoSupplier info) {
+    TypeLatticeElement typeLattice = info.getTypeLattice();
+    DebugLocalInfo debugLocalInfo = info.getLocalInfo();
+    assert !typeLattice.isReference() || value == 0;
+    Value returnedValue =
+        code.createValue(
+            typeLattice.isReference() ? TypeLatticeElement.NULL : typeLattice, debugLocalInfo);
+    return new ConstNumber(returnedValue, value);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
index acb2f69..d2a8726 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
@@ -4,9 +4,22 @@
 
 package com.android.tools.r8.ir.analysis.value;
 
-import com.android.tools.r8.graph.DexString;
+import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
+import static com.android.tools.r8.ir.analysis.type.TypeLatticeElement.stringClassType;
 
-public class SingleStringValue extends AbstractValue {
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DebugLocalInfo;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
+import com.android.tools.r8.ir.code.ConstString;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
+import com.android.tools.r8.ir.code.Value;
+
+public class SingleStringValue extends SingleValue {
 
   private final DexString string;
 
@@ -38,4 +51,26 @@
   public int hashCode() {
     return string.hashCode();
   }
+
+  @Override
+  public Instruction createMaterializingInstruction(
+      AppView<? extends AppInfoWithSubtyping> appView,
+      IRCode code,
+      TypeAndLocalInfoSupplier info) {
+    TypeLatticeElement typeLattice = info.getTypeLattice();
+    DebugLocalInfo debugLocalInfo = info.getLocalInfo();
+    assert typeLattice.isClassType();
+    assert appView
+        .isSubtype(
+            appView.dexItemFactory().stringType,
+            typeLattice.asClassTypeLatticeElement().getClassType())
+        .isTrue();
+    Value returnedValue =
+        code.createValue(stringClassType(appView, definitelyNotNull()), debugLocalInfo);
+    ConstString instruction =
+        new ConstString(
+            returnedValue, string, ThrowingInfo.defaultForConstString(appView.options()));
+    assert !instruction.instructionInstanceCanThrow();
+    return instruction;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
new file mode 100644
index 0000000..9972328
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
@@ -0,0 +1,29 @@
+// 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.ir.analysis.value;
+
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
+
+public abstract class SingleValue extends AbstractValue {
+
+  @Override
+  public boolean isSingleValue() {
+    return true;
+  }
+
+  @Override
+  public SingleValue asSingleValue() {
+    return this;
+  }
+
+  public abstract Instruction createMaterializingInstruction(
+      AppView<? extends AppInfoWithSubtyping> appView,
+      IRCode code,
+      TypeAndLocalInfoSupplier info);
+}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 309b424..7452a66 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -40,7 +40,7 @@
 import java.util.Set;
 import java.util.function.Function;
 
-public abstract class Instruction implements InstructionOrPhi {
+public abstract class Instruction implements InstructionOrPhi, TypeAndLocalInfoSupplier {
 
   protected Value outValue = null;
   protected final List<Value> inValues = new ArrayList<>();
@@ -138,6 +138,14 @@
     return oldOutValue;
   }
 
+  @Override
+  public TypeLatticeElement getTypeLattice() {
+    if (hasOutValue()) {
+      return outValue().getTypeLattice();
+    }
+    return null;
+  }
+
   public void addDebugValue(Value value) {
     assert value.hasLocalInfo();
     if (debugValues == null) {
@@ -595,6 +603,7 @@
 
   public abstract int maxOutValueRegister();
 
+  @Override
   public DebugLocalInfo getLocalInfo() {
     return outValue == null ? null : outValue.getLocalInfo();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/TypeAndLocalInfoSupplier.java b/src/main/java/com/android/tools/r8/ir/code/TypeAndLocalInfoSupplier.java
new file mode 100644
index 0000000..f5ca688
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/code/TypeAndLocalInfoSupplier.java
@@ -0,0 +1,13 @@
+// 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.ir.code;
+
+import com.android.tools.r8.graph.DebugLocalInfo;
+import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+
+public interface TypeAndLocalInfoSupplier {
+  DebugLocalInfo getLocalInfo();
+  TypeLatticeElement getTypeLattice();
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index adc1112..a2c60a3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -3,27 +3,20 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.optimize;
 
-import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
-import static com.android.tools.r8.ir.analysis.type.TypeLatticeElement.stringClassType;
-
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DebugLocalInfo;
 import com.android.tools.r8.graph.DexDefinition;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexReference;
-import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.type.Nullability;
 import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.analysis.value.AbstractValue;
 import com.android.tools.r8.ir.code.BasicBlock;
-import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
 import com.android.tools.r8.ir.code.ConstInstruction;
-import com.android.tools.r8.ir.code.ConstNumber;
-import com.android.tools.r8.ir.code.ConstString;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.IRMetadata;
 import com.android.tools.r8.ir.code.InstanceGet;
@@ -128,14 +121,15 @@
     }
 
     ProguardMemberRuleReturnValue returnValueRule = rule.getReturnValue();
-    TypeLatticeElement typeLattice = instruction.outValue().getTypeLattice();
 
     // Check if this value can be assumed constant.
     if (returnValueRule.isSingleValue()) {
-      return createConstNumberReplacement(
-          code, returnValueRule.getSingleValue(), typeLattice, instruction.getLocalInfo());
+      return appView.abstractValueFactory()
+          .createSingleNumberValue(returnValueRule.getSingleValue())
+          .createMaterializingInstruction(appView, code, instruction);
     }
 
+    TypeLatticeElement typeLattice = instruction.outValue().getTypeLattice();
     if (returnValueRule.isField()) {
       DexField field = returnValueRule.getField();
       assert typeLattice
@@ -176,35 +170,6 @@
     return null;
   }
 
-  private static ConstNumber createConstNumberReplacement(
-      IRCode code, long constant, TypeLatticeElement typeLattice, DebugLocalInfo debugLocalInfo) {
-    assert !typeLattice.isReference() || constant == 0;
-    Value returnedValue =
-        code.createValue(
-            typeLattice.isReference() ? TypeLatticeElement.NULL : typeLattice, debugLocalInfo);
-    return new ConstNumber(returnedValue, constant);
-  }
-
-  private ConstString createConstStringReplacement(
-      IRCode code,
-      DexString constant,
-      TypeLatticeElement typeLattice,
-      DebugLocalInfo debugLocalInfo) {
-    assert typeLattice.isClassType();
-    assert appView
-        .isSubtype(
-            appView.dexItemFactory().stringType,
-            typeLattice.asClassTypeLatticeElement().getClassType())
-        .isTrue();
-    Value returnedValue =
-        code.createValue(stringClassType(appView, definitelyNotNull()), debugLocalInfo);
-    ConstString instruction =
-        new ConstString(
-            returnedValue, constant, ThrowingInfo.defaultForConstString(appView.options()));
-    assert !instruction.instructionInstanceCanThrow();
-    return instruction;
-  }
-
   private void setValueRangeFromProguardRule(ProguardMemberRule rule, Value value) {
     if (rule.hasReturnValue() && rule.getReturnValue().isValueRange()) {
       assert !rule.getReturnValue().isSingleValue();
@@ -307,20 +272,12 @@
     if (target == null || !mayPropagateValueFor(target)) {
       return;
     }
-    if (target.getOptimizationInfo().returnsConstant()) {
-      ConstInstruction replacement;
-      if (target.getOptimizationInfo().returnsConstantNumber()) {
-        long constant = target.getOptimizationInfo().getReturnedConstantNumber();
-        replacement =
-            createConstNumberReplacement(
-                code, constant, current.outValue().getTypeLattice(), current.getLocalInfo());
-      } else {
-        assert target.getOptimizationInfo().returnsConstantString();
-        DexString constant = target.getOptimizationInfo().getReturnedConstantString();
-        replacement =
-            createConstStringReplacement(
-                code, constant, current.outValue().getTypeLattice(), current.getLocalInfo());
-      }
+
+    AbstractValue abstractReturnValue = target.getOptimizationInfo().getAbstractReturnValue();
+    if (abstractReturnValue.isSingleValue()) {
+      Instruction replacement =
+          abstractReturnValue.asSingleValue()
+              .createMaterializingInstruction(appView, code, current);
 
       affectedValues.addAll(current.outValue().affectedValues());
       current.outValue().replaceUsers(replacement.outValue());
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
index 3b64d1c..e6d0589 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.ir.optimize.info;
 
 import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
-import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -27,7 +26,7 @@
   static int UNKNOWN_RETURNED_ARGUMENT = -1;
   static boolean UNKNOWN_NEVER_RETURNS_NULL = false;
   static boolean UNKNOWN_NEVER_RETURNS_NORMALLY = false;
-  static AbstractValue UNKNOWN_CONSTANT_VALUE = UnknownValue.getInstance();
+  static AbstractValue UNKNOWN_ABSTRACT_RETURN_VALUE = UnknownValue.getInstance();
   static TypeLatticeElement UNKNOWN_TYPE = null;
   static ClassTypeLatticeElement UNKNOWN_CLASS_TYPE = null;
   static boolean DOES_NOT_USE_IDENTIFIER_NAME_STRING = false;
@@ -141,30 +140,13 @@
   }
 
   @Override
-  public boolean returnsConstantNumber() {
-    return UNKNOWN_CONSTANT_VALUE.isSingleNumberValue();
-  }
-
-  @Override
-  public boolean returnsConstantString() {
-    return UNKNOWN_CONSTANT_VALUE.isSingleStringValue();
-  }
-
-  @Override
   public ClassInlinerEligibility getClassInlinerEligibility() {
     return UNKNOWN_CLASS_INLINER_ELIGIBILITY;
   }
 
   @Override
-  public long getReturnedConstantNumber() {
-    assert returnsConstantNumber();
-    return UNKNOWN_CONSTANT_VALUE.asSingleNumberValue().getValue();
-  }
-
-  @Override
-  public DexString getReturnedConstantString() {
-    assert returnsConstantString();
-    return UNKNOWN_CONSTANT_VALUE.asSingleStringValue().getDexString();
+  public AbstractValue getAbstractReturnValue() {
+    return UNKNOWN_ABSTRACT_RETURN_VALUE;
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
index 93cdc1b..26aab1b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
@@ -5,10 +5,10 @@
 package com.android.tools.r8.ir.optimize.info;
 
 import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
-import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.analysis.value.AbstractValue;
 import com.android.tools.r8.ir.optimize.info.ParameterUsagesInfo.ParameterUsage;
 import com.android.tools.r8.ir.optimize.info.initializer.ClassInitializerInfo;
 import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
@@ -55,14 +55,6 @@
 
   boolean neverReturnsNormally();
 
-  default boolean returnsConstant() {
-    return returnsConstantNumber() || returnsConstantString();
-  }
-
-  boolean returnsConstantNumber();
-
-  boolean returnsConstantString();
-
   ClassInlinerEligibility getClassInlinerEligibility();
 
   Set<DexType> getInitializedClassesOnNormalExit();
@@ -73,9 +65,7 @@
 
   boolean isInitializerEnablingJavaAssertions();
 
-  long getReturnedConstantNumber();
-
-  DexString getReturnedConstantString();
+  AbstractValue getAbstractReturnValue();
 
   boolean forceInline();
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
index d553a4c..8bb6fc3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
@@ -35,7 +35,8 @@
   private boolean neverReturnsNull = DefaultMethodOptimizationInfo.UNKNOWN_NEVER_RETURNS_NULL;
   private boolean neverReturnsNormally =
       DefaultMethodOptimizationInfo.UNKNOWN_NEVER_RETURNS_NORMALLY;
-  private AbstractValue constantValue = DefaultMethodOptimizationInfo.UNKNOWN_CONSTANT_VALUE;
+  private AbstractValue abstractReturnValue =
+      DefaultMethodOptimizationInfo.UNKNOWN_ABSTRACT_RETURN_VALUE;
   private TypeLatticeElement returnsObjectWithUpperBoundType =
       DefaultMethodOptimizationInfo.UNKNOWN_TYPE;
   private ClassTypeLatticeElement returnsObjectWithLowerBoundType =
@@ -93,7 +94,7 @@
     returnValueOnlyDependsOnArguments = template.returnValueOnlyDependsOnArguments;
     neverReturnsNull = template.neverReturnsNull;
     neverReturnsNormally = template.neverReturnsNormally;
-    constantValue = template.constantValue;
+    abstractReturnValue = template.abstractReturnValue;
     returnsObjectWithUpperBoundType = template.returnsObjectWithUpperBoundType;
     returnsObjectWithLowerBoundType = template.returnsObjectWithLowerBoundType;
     inlining = template.inlining;
@@ -235,30 +236,13 @@
   }
 
   @Override
-  public boolean returnsConstantNumber() {
-    return constantValue.isSingleNumberValue();
-  }
-
-  @Override
-  public boolean returnsConstantString() {
-    return constantValue.isSingleStringValue();
-  }
-
-  @Override
   public ClassInlinerEligibility getClassInlinerEligibility() {
     return classInlinerEligibility;
   }
 
   @Override
-  public long getReturnedConstantNumber() {
-    assert returnsConstantNumber();
-    return constantValue.asSingleNumberValue().getValue();
-  }
-
-  @Override
-  public DexString getReturnedConstantString() {
-    assert returnsConstantString();
-    return constantValue.asSingleStringValue().getDexString();
+  public AbstractValue getAbstractReturnValue() {
+    return abstractReturnValue;
   }
 
   @Override
@@ -356,21 +340,21 @@
   }
 
   void markReturnsConstantNumber(AppView<?> appView, long value) {
-    assert !constantValue.isSingleStringValue();
-    assert !constantValue.isSingleNumberValue()
-            || constantValue.asSingleNumberValue().getValue() == value
+    assert !abstractReturnValue.isSingleStringValue();
+    assert !abstractReturnValue.isSingleNumberValue()
+            || abstractReturnValue.asSingleNumberValue().getValue() == value
         : "return constant number changed from "
-            + constantValue.asSingleNumberValue().getValue() + " to " + value;
-    constantValue = appView.abstractValueFactory().createSingleNumberValue(value);
+            + abstractReturnValue.asSingleNumberValue().getValue() + " to " + value;
+    abstractReturnValue = appView.abstractValueFactory().createSingleNumberValue(value);
   }
 
   void markReturnsConstantString(AppView<?> appView, DexString value) {
-    assert !constantValue.isSingleNumberValue();
-    assert !constantValue.isSingleStringValue()
-            || constantValue.asSingleStringValue().getDexString() == value
+    assert !abstractReturnValue.isSingleNumberValue();
+    assert !abstractReturnValue.isSingleStringValue()
+            || abstractReturnValue.asSingleStringValue().getDexString() == value
         : "return constant string changed from "
-            + constantValue.asSingleStringValue().getDexString() + " to " + value;
-    constantValue = appView.abstractValueFactory().createSingleStringValue(value);
+            + abstractReturnValue.asSingleStringValue().getDexString() + " to " + value;
+    abstractReturnValue = appView.abstractValueFactory().createSingleStringValue(value);
   }
 
   void markReturnsObjectWithUpperBoundType(AppView<?> appView, TypeLatticeElement type) {