summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDmitry Bushev <bushevdv@gmail.com>2012-12-14 17:09:55 +0400
committerEugene Burmako <xeno.by@gmail.com>2013-02-08 12:53:14 +0100
commit09ef8730d13eff1cf200bbfb0f6fda7f6d72524a (patch)
tree85c49426a77eb415678fdea5eee12522ca16e276 /src
parent9164c2af4183e04986eb652e09081daba3d0d279 (diff)
downloadscala-09ef8730d13eff1cf200bbfb0f6fda7f6d72524a.tar.gz
scala-09ef8730d13eff1cf200bbfb0f6fda7f6d72524a.tar.bz2
scala-09ef8730d13eff1cf200bbfb0f6fda7f6d72524a.zip
SI-6591 Reify and path-dependent types
Reification scheme changed. Now Select an SelectFromTypeTree trees reified appropriately, as Select and SelectFromTypeTree accordingly. Packages and Predef object was excluded in order not to break the existing reification scheme and not to break tests which rely on it. Reified free terms can contain flag <stable> to make reified values become stable identifiers. For example in the case of reify_newimpl_15.scala class C { type T reify { val v: List[T] = List(2) } } class C reified as free term C$value, and List[C.T] becomes List[C$value().T], so C$value.apply() need to pass stability test isExprSafeToInline at scala.reflect.internal.TreeInfo. For this purpose special case for reified free terms was added to isExprSafeToInline function. test run/reify_newipl_30 disabled due to SI-7082 test t6591_4 moved to pending due to SI-7083
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala2
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTrees.scala24
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala8
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala2
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala6
7 files changed, 34 insertions, 16 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 22a834d2e4..0d795e3783 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -100,6 +100,8 @@ trait GenSymbols {
reifyIntoSymtab(binding.symbol) { sym =>
if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym + "(" + sym.accurateKindString + ")")
val name = newTermName(nme.REIFY_FREE_PREFIX + sym.name + (if (sym.isType) nme.REIFY_FREE_THIS_SUFFIX else ""))
+ // Flag <stable> is set here to make reified free value pass stability test during reflective compilation
+ if (!sym.isMutable) sym setFlag reflect.internal.Flags.STABLE
if (sym.isCapturedVariable) {
assert(binding.isInstanceOf[Ident], showRaw(binding))
val capturedBinding = referenceCapturedVariable(sym)
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
index 06e287f62f..7c7a79e774 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
@@ -163,11 +163,11 @@ trait GenTrees {
}
}
- private def reifyBoundType(tree: Tree): Tree = {
+ private def reifyBoundType(tree: RefTree): Tree = {
val sym = tree.symbol
val tpe = tree.tpe
- def reifyBoundType(tree: Tree): Tree = {
+ def reifyBoundType(tree: RefTree): Tree = {
assert(tpe != null, "unexpected: bound type that doesn't have a tpe: " + showRaw(tree))
// if a symbol or a type of the scrutinee are local to reifee
@@ -196,13 +196,19 @@ trait GenTrees {
mirrorBuildCall(nme.TypeTree, spliced)
}
}
- else if (sym.isLocatable) {
- if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym))
- mirrorBuildCall(nme.Ident, reify(sym))
- }
- else {
- if (reifyDebug) println("tpe is not locatable: reify as TypeTree(%s)".format(tpe))
- mirrorBuildCall(nme.TypeTree, reify(tpe))
+ else tree match {
+ case Select(qual, name) if !qual.symbol.isPackage && !qual.symbol.isPackageObject && qual.symbol != definitions.PredefModule =>
+ if (reifyDebug) println(s"reifying Select($qual, $name)")
+ mirrorCall(nme.Select, reify(qual), reify(name))
+ case SelectFromTypeTree(qual, name) =>
+ if (reifyDebug) println(s"reifying SelectFromTypeTree($qual, $name)")
+ mirrorCall(nme.SelectFromTypeTree, reify(qual), reify(name))
+ case _ if sym.isLocatable =>
+ if (reifyDebug) println(s"tpe is locatable: reify as Ident($sym)")
+ mirrorBuildCall(nme.Ident, reify(sym))
+ case _ =>
+ if (reifyDebug) println(s"tpe is not locatable: reify as TypeTree($tpe)")
+ mirrorBuildCall(nme.TypeTree, reify(tpe))
}
}
}
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index ebbcb95481..134ae13890 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -263,12 +263,12 @@ trait Extractors {
}
object BoundType {
- def unapply(tree: Tree): Option[Tree] = tree match {
- case Select(_, name) if name.isTypeName =>
+ def unapply(tree: Tree): Option[RefTree] = tree match {
+ case tree @ Select(_, name) if name.isTypeName =>
Some(tree)
- case SelectFromTypeTree(_, name) if name.isTypeName =>
+ case tree @ SelectFromTypeTree(_, _) =>
Some(tree)
- case Ident(name) if name.isTypeName =>
+ case tree @ Ident(name) if name.isTypeName =>
Some(tree)
case _ =>
None
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 95135b84e0..fdc790a920 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -212,7 +212,11 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
def makeParam(schema: (FreeTermSymbol, TermName)) = {
val (fv, name) = schema
- meth.newValueParameter(name) setInfo appliedType(definitions.FunctionClass(0).tpe, List(fv.tpe.resultType))
+ /* Free term symbol `fv` can contain flag <stable> which was set by
+ * `scala.reflect.reify.codegen.GenSymbols.reifyFreeTerm` method.
+ * It is recovered here, so value parameter can pass `isExprSafeToInline`
+ * test in `scala.reflect.internal.TreeInfo`. */
+ meth.newValueParameter(name, newFlags = if (fv.hasStableFlag) Flags.STABLE else 0) setInfo appliedType(definitions.FunctionClass(0).tpe, List(fv.tpe.resultType))
}
meth setInfo MethodType(freeTerms.map(makeParam).toList, AnyClass.tpe)
minfo.decls enter meth
@@ -418,4 +422,3 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
def eval(tree: u.Tree): Any = compile(tree)()
}
}
-
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index a0362c8921..5853315479 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -274,7 +274,7 @@ class Flags extends ModifierFlags {
* from Modifiers. Others which may be applied at creation time are:
* SYNTHETIC.
*/
- final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM
+ final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM | STABLE
final val BeanPropertyFlags = DEFERRED | OVERRIDE | STATIC
final val VarianceFlags = COVARIANT | CONTRAVARIANT
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index ddc5d94e70..bcda2bc1ae 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -607,6 +607,7 @@ trait StdNames {
val RootPackage: NameType = "RootPackage"
val RootClass: NameType = "RootClass"
val Select: NameType = "Select"
+ val SelectFromTypeTree: NameType = "SelectFromTypeTree"
val StringContext: NameType = "StringContext"
val This: NameType = "This"
val ThisType: NameType = "ThisType"
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 8b5dc80c83..f83106aaef 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -89,6 +89,12 @@ abstract class TreeInfo {
tree.symbol.isStable && isExprSafeToInline(qual)
case TypeApply(fn, _) =>
isExprSafeToInline(fn)
+ /* Special case for reified free terms. During reflective compilation,
+ * reified value recovered flag <stable> from free term and wrapped into a
+ * Function object, so it can pass stability check here to become a stable
+ * identifier.*/
+ case Apply(Select(free @ Ident(_), nme.apply), _) if free.symbol.name endsWith nme.REIFY_FREE_VALUE_SUFFIX =>
+ free.symbol.hasStableFlag && isExprSafeToInline(free)
case Apply(fn, List()) =>
/* Note: After uncurry, field accesses are represented as Apply(getter, Nil),
* so an Apply can also be pure.