summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowInterpreter.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowInterpreter.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowInterpreter.scala36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowInterpreter.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowInterpreter.scala
new file mode 100644
index 0000000000..bcf9978c16
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowInterpreter.scala
@@ -0,0 +1,36 @@
+package scala.tools.nsc
+package backend.jvm
+package analysis
+
+import scala.tools.asm.Type
+import scala.tools.asm.tree.analysis.{BasicValue, BasicInterpreter}
+
+abstract class TypeFlowInterpreter extends BasicInterpreter {
+ override def newValue(tp: Type) = {
+ if (tp == null) super.newValue(tp)
+ else if (isRef(tp)) new BasicValue(tp)
+ else super.newValue(tp)
+ }
+
+ def isRef(tp: Type) = tp != null && (tp.getSort match {
+ case Type.OBJECT | Type.ARRAY => true
+ case _ => false
+ })
+
+ def refLub(a: BasicValue, b: BasicValue): BasicValue
+
+ override def merge(a: BasicValue, b: BasicValue): BasicValue = {
+ if (a == b) a
+ else if (isRef(a.getType) && isRef(b.getType)) refLub(a, b)
+ else BasicValue.UNINITIALIZED_VALUE
+ }
+}
+
+/**
+ * A [[TypeFlowInterpreter]] which collapses LUBs of non-equal reference types to Object.
+ * This could be made more precise by looking up ClassBTypes for the two reference types and using
+ * the `jvmWiseLUB` method.
+ */
+class NonLubbingTypeFlowInterpreter extends TypeFlowInterpreter {
+ def refLub(a: BasicValue, b: BasicValue): BasicValue = BasicValue.REFERENCE_VALUE // java/lang/Object
+}