summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/internal/CapturedVariables.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/reflect/internal/CapturedVariables.scala')
-rw-r--r--src/compiler/scala/reflect/internal/CapturedVariables.scala36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/compiler/scala/reflect/internal/CapturedVariables.scala b/src/compiler/scala/reflect/internal/CapturedVariables.scala
new file mode 100644
index 0000000000..77909d9157
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/CapturedVariables.scala
@@ -0,0 +1,36 @@
+package scala.reflect
+package internal
+
+import Flags._
+
+trait CapturedVariables { self: SymbolTable =>
+
+ import definitions._
+
+ /** Mark a variable as captured; i.e. force boxing in a *Ref type.
+ */
+ def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED
+
+ /** Mark given identifier as a reference to a captured variable itself
+ * suppressing dereferencing with the `elem` field.
+ */
+ def referenceCapturedVariable(vble: Symbol): Tree = ReferenceToBoxed(Ident(vble))
+
+ /** Convert type of a captured variable to *Ref type.
+ */
+ def capturedVariableType(vble: Symbol): Type =
+ capturedVariableType(vble, NoType, false)
+
+ /** Convert type of a captured variable to *Ref type.
+ */
+ def capturedVariableType(vble: Symbol, tpe: Type = NoType, erasedTypes: Boolean = false): Type = {
+ val tpe1 = if (tpe == NoType) vble.tpe else tpe
+ val symClass = tpe1.typeSymbol
+ def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) =
+ if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe
+ else if (erasedTypes) objectRefClass.tpe
+ else appliedType(objectRefClass, tpe)
+ if (vble.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass)
+ else refType(refClass, ObjectRefClass)
+ }
+}