summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-01-21 04:25:44 -0800
committerEugene Burmako <xeno.by@gmail.com>2014-01-21 04:25:44 -0800
commita242101282ba986c4e336b759aaa08a32ca82a7b (patch)
tree6ac44b5195cda51f3a2e54e89c0aa250714797b1
parent26387cacaa8f78105419044fc33acc8fd8343662 (diff)
parent752f1eb63e931e04fd2818f32b6ca7e68e4298d2 (diff)
downloadscala-a242101282ba986c4e336b759aaa08a32ca82a7b.tar.gz
scala-a242101282ba986c4e336b759aaa08a32ca82a7b.tar.bz2
scala-a242101282ba986c4e336b759aaa08a32ca82a7b.zip
Merge pull request #3392 from xeno-by/topic/untypecheck
deprecates resetAllAttrs and resetLocalAttrs in favor of the new API
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Typers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala5
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala15
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala2
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Typers.scala26
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
-rw-r--r--test/files/run/idempotency-case-classes.scala2
-rw-r--r--test/files/run/idempotency-extractors.scala2
-rw-r--r--test/files/run/idempotency-labels.scala2
-rw-r--r--test/files/run/idempotency-lazy-vals.scala2
-rw-r--r--test/files/run/idempotency-this.scala2
-rw-r--r--test/files/run/resetattrs-this.scala2
-rw-r--r--test/files/run/t6187.check2
-rw-r--r--test/files/run/t6187.scala2
19 files changed, 55 insertions, 28 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala
index 85204d0f1b..cd3db74016 100644
--- a/src/compiler/scala/reflect/macros/contexts/Typers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala
@@ -49,4 +49,6 @@ trait Typers {
def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(universe.duplicateAndKeepPositions(tree))
def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(universe.duplicateAndKeepPositions(tree))
+
+ def untypecheck(tree: Tree): Tree = universe.resetLocalAttrs(universe.duplicateAndKeepPositions(tree))
}
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index 429832f22c..eafecf9462 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -632,7 +632,7 @@ abstract class TreeBrowsers {
Document.group("(" :/: symsToDocument(tparams) :/: "), ") :/:
toDocument(result) :: ")"))
- case global.analyzer.ImportType(expr) =>
+ case ImportType(expr) =>
"ImportType(" + expr.toString + ")"
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 4ac6672727..a87a04472a 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -37,7 +37,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
NoSymbol
newImport NoPosition
setFlag SYNTHETIC
- setInfo analyzer.ImportType(qual)
+ setInfo ImportType(qual)
)
val importTree = (
Import(qual, selector)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 53bc9a2772..598b12b00d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -1353,9 +1353,8 @@ trait Contexts { self: Analyzer =>
override def toString = tree.toString
}
- case class ImportType(expr: Tree) extends Type {
- override def safeToString = "ImportType("+expr+")"
- }
+ type ImportType = global.ImportType
+ val ImportType = global.ImportType
}
object ContextMode {
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
index 236b868842..4c1bc794bc 100644
--- a/src/compiler/scala/tools/reflect/ToolBox.scala
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -72,19 +72,22 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree
/** Recursively resets symbols and types in a given tree.
- *
- * Note that this does not revert the tree to its pre-typer shape.
- * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ * WARNING: Don't use this API, go for [[untypecheck]] instead.
*/
+ @deprecated("Use `tb.untypecheck` instead", "2.11.0")
def resetAllAttrs(tree: u.Tree): u.Tree
/** Recursively resets locally defined symbols and types in a given tree.
- *
- * Note that this does not revert the tree to its pre-typer shape.
- * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ * WARNING: Don't use this API, go for [[untypecheck]] instead.
*/
+ @deprecated("Use `tb.untypecheck` instead", "2.11.0")
def resetLocalAttrs(tree: u.Tree): u.Tree
+ /**
+ * @see [[scala.reflect.macros.Typers.untypecheck]]
+ */
+ def untypecheck(tree: u.Tree): u.Tree
+
/** .. */
def parse(code: String): u.Tree
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index af13b7d0ba..4a8c91bd1b 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -401,6 +401,8 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
uttree
}
+ def untypecheck(tree: u.Tree): u.Tree = resetLocalAttrs(tree)
+
def parse(code: String): u.Tree = withCompilerApi { compilerApi =>
import compilerApi._
if (compiler.settings.verbose) println("parsing "+code)
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index b55a573029..0e897d6492 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -956,7 +956,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
singleType(qual.tpe, tree.symbol)
case Import(expr, selectors) =>
tree.symbol.info match {
- case analyzer.ImportType(expr) => expr match {
+ case ImportType(expr) => expr match {
case s@Select(qual, name) if treeInfo.admitsTypeSelection(expr) => singleType(qual.tpe, s.symbol)
case i : Ident => i.tpe
case _ => tree.tpe
@@ -1021,7 +1021,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def addScopeMember(sym: Symbol, pre: Type, viaImport: Tree) =
locals.add(sym, pre, implicitlyAdded = false) { (s, st) =>
// imported val and var are always marked as inaccessible, but they could be accessed through their getters. SI-7995
- if (s.hasGetter)
+ if (s.hasGetter)
new ScopeMember(s, st, context.isAccessible(s.getter, pre, superAccess = false), viaImport)
else
new ScopeMember(s, st, context.isAccessible(s, pre, superAccess = false), viaImport)
@@ -1111,7 +1111,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
val pre = stabilizedType(tree)
val ownerTpe = tree.tpe match {
- case analyzer.ImportType(expr) => expr.tpe
+ case ImportType(expr) => expr.tpe
case null => pre
case MethodType(List(), rtpe) => rtpe
case _ => tree.tpe
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index 86038afaf1..483d0dd656 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -260,6 +260,8 @@ trait Importers extends api.Importers { to: SymbolTable =>
newExistentialType(tparams map importSymbol, importType(result))
case from.OverloadedType(pre, alts) =>
OverloadedType(importType(pre), alts map importSymbol)
+ case from.ImportType(qual) =>
+ ImportType(importTree(qual))
case from.AntiPolyType(pre, targs) =>
AntiPolyType(importType(pre), targs map importType)
case their: from.TypeVar =>
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 17a52c10e4..9ddaea4c62 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2748,6 +2748,10 @@ trait Types
case _ => OverloadedType(pre, alternatives)
}
+ case class ImportType(expr: Tree) extends Type {
+ override def safeToString = "ImportType("+expr+")"
+ }
+
/** A class remembering a type instantiation for some a set of overloaded
* polymorphic symbols.
* Not used after phase `typer`.
diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala
index 54336900f8..87de442921 100644
--- a/src/reflect/scala/reflect/macros/Typers.scala
+++ b/src/reflect/scala/reflect/macros/Typers.scala
@@ -69,18 +69,32 @@ trait Typers {
def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree
/** Recursively resets symbols and types in a given tree.
- *
- * Note that this does not revert the tree to its pre-typer shape.
- * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ * WARNING: Don't use this API, go for [[untypecheck]] instead.
*/
+ @deprecated("Use `c.untypecheck` instead", "2.11.0")
def resetAllAttrs(tree: Tree): Tree
/** Recursively resets locally defined symbols and types in a given tree.
- *
- * Note that this does not revert the tree to its pre-typer shape.
- * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ * WARNING: Don't use this API, go for [[untypecheck]] instead.
*/
+ @deprecated("Use `c.untypecheck` instead", "2.11.0")
def resetLocalAttrs(tree: Tree): Tree
+
+ /** In the current implementation of Scala's reflection API, untyped trees (also known as parser trees or unattributed trees)
+ * are observationally different from typed trees (also known as typer trees, typechecked trees or attributed trees),
+ *
+ * Usually, if some compiler API takes a tree, then both untyped and typed trees will do. However in some cases,
+ * only untyped or only typed trees are appropriate. For example, [[eval]] only accepts untyped trees and one can only splice
+ * typed trees inside typed trees. Therefore in the current reflection API, there is a need in functions
+ * that go back and forth between untyped and typed trees. For this we have [[typecheck]] and `untypecheck`.
+ *
+ * Note that `untypecheck` is currently afflicted by https://issues.scala-lang.org/browse/SI-5464,
+ * which makes it sometimes corrupt trees so that they don't make sense anymore. Unfortunately, there's no workaround for that.
+ * We plan to fix this issue soon, but for now please keep it in mind.
+ *
+ * @see [[http://stackoverflow.com/questions/20936509/scala-macros-what-is-the-difference-between-typed-aka-typechecked-an-untyped]]
+ */
+ def untypecheck(tree: Tree): Tree
}
/** Indicates an error during one of the methods in [[scala.reflect.macros.Typers]].
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 9224749864..b9b171c7ed 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -170,6 +170,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.PolyType
this.ExistentialType
this.OverloadedType
+ this.ImportType
this.AntiPolyType
this.HasTypeMember
this.ArrayTypeRef
diff --git a/test/files/run/idempotency-case-classes.scala b/test/files/run/idempotency-case-classes.scala
index 81e119582b..4ad132174d 100644
--- a/test/files/run/idempotency-case-classes.scala
+++ b/test/files/run/idempotency-case-classes.scala
@@ -12,7 +12,7 @@ object Test extends App {
val tb = cm.mkToolBox()
val tcasee = tb.typecheck(casee.tree)
println(tcasee)
- val rtcasee = tb.resetAllAttrs(tcasee)
+ val rtcasee = tb.untypecheck(tcasee)
try {
println(tb.eval(rtcasee))
} catch {
diff --git a/test/files/run/idempotency-extractors.scala b/test/files/run/idempotency-extractors.scala
index b66b043be1..8c0a0b1106 100644
--- a/test/files/run/idempotency-extractors.scala
+++ b/test/files/run/idempotency-extractors.scala
@@ -12,7 +12,7 @@ object Test extends App {
val tb = cm.mkToolBox()
val textractor = tb.typecheck(extractor.tree)
println(textractor)
- val rtextractor = tb.resetAllAttrs(textractor)
+ val rtextractor = tb.untypecheck(textractor)
try {
println(tb.eval(rtextractor))
} catch {
diff --git a/test/files/run/idempotency-labels.scala b/test/files/run/idempotency-labels.scala
index f1a185d3d0..084c93d3c6 100644
--- a/test/files/run/idempotency-labels.scala
+++ b/test/files/run/idempotency-labels.scala
@@ -13,7 +13,7 @@ object Test extends App {
val tb = cm.mkToolBox()
val tlabel = tb.typecheck(label.tree)
println(tlabel)
- val rtlabel = tb.resetAllAttrs(tlabel)
+ val rtlabel = tb.untypecheck(tlabel)
try {
println(tb.eval(rtlabel))
} catch {
diff --git a/test/files/run/idempotency-lazy-vals.scala b/test/files/run/idempotency-lazy-vals.scala
index e763f2f3f4..9d677caeca 100644
--- a/test/files/run/idempotency-lazy-vals.scala
+++ b/test/files/run/idempotency-lazy-vals.scala
@@ -17,7 +17,7 @@ object Test extends App {
val tb = cm.mkToolBox()
val tlazee = tb.typecheck(lazee.tree)
println(tlazee)
- val rtlazee = tb.resetAllAttrs(tlazee)
+ val rtlazee = tb.untypecheck(tlazee)
try {
println(tb.eval(rtlazee))
} catch {
diff --git a/test/files/run/idempotency-this.scala b/test/files/run/idempotency-this.scala
index 2db1efd2d1..26917ab743 100644
--- a/test/files/run/idempotency-this.scala
+++ b/test/files/run/idempotency-this.scala
@@ -12,7 +12,7 @@ object Test extends App {
val tthiss = tb.typecheck(thiss.tree)
println(tthiss)
println(showRaw(tthiss))
- val rtthiss = tb.resetAllAttrs(tthiss)
+ val rtthiss = tb.untypecheck(tthiss)
try {
println(tb.eval(rtthiss))
} catch {
diff --git a/test/files/run/resetattrs-this.scala b/test/files/run/resetattrs-this.scala
index 6150a4e265..ff45d61dfe 100644
--- a/test/files/run/resetattrs-this.scala
+++ b/test/files/run/resetattrs-this.scala
@@ -6,6 +6,6 @@ object Test extends App {
val tb = cm.mkToolBox()
val tree = Select(This(cm.staticPackage("scala").moduleClass), TermName("Predef"))
val ttree = tb.typecheck(tree)
- val rttree = tb.resetAllAttrs(ttree)
+ val rttree = tb.untypecheck(ttree)
println(tb.eval(rttree) == Predef)
}
diff --git a/test/files/run/t6187.check b/test/files/run/t6187.check
index 97ee68271a..0180125809 100644
--- a/test/files/run/t6187.check
+++ b/test/files/run/t6187.check
@@ -7,7 +7,7 @@ import scala.reflect.macros.blackbox.Context
scala> def macroImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[List[T]] = {
val r = c.universe.reify { List(t.splice) }
- c.Expr[List[T]]( c.resetLocalAttrs(r.tree) )
+ c.Expr[List[T]]( c.untypecheck(r.tree) )
}
macroImpl: [T](c: scala.reflect.macros.blackbox.Context)(t: c.Expr[T])(implicit evidence$1: c.WeakTypeTag[T])c.Expr[List[T]]
diff --git a/test/files/run/t6187.scala b/test/files/run/t6187.scala
index 7d84419b8a..7a39cfd9e7 100644
--- a/test/files/run/t6187.scala
+++ b/test/files/run/t6187.scala
@@ -5,7 +5,7 @@ object Test extends ReplTest {
import scala.language.experimental.macros, scala.reflect.macros.blackbox.Context
def macroImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[List[T]] = {
val r = c.universe.reify { List(t.splice) }
- c.Expr[List[T]]( c.resetLocalAttrs(r.tree) )
+ c.Expr[List[T]]( c.untypecheck(r.tree) )
}
def demo[T](t: T): List[T] = macro macroImpl[T]
def m[T](t: T): List[List[T]] =