summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-02-06 15:54:36 +0100
committerEugene Burmako <xeno.by@gmail.com>2012-02-06 17:20:11 +0100
commit8906a074620568db26ba449296031dd3477d8b72 (patch)
tree0b524c89f2b4e4c3f2b8586563191ccb305c023f
parent28b2d0c13aba7156431076119c920c7dcee6dc77 (diff)
downloadscala-8906a074620568db26ba449296031dd3477d8b72.tar.gz
scala-8906a074620568db26ba449296031dd3477d8b72.tar.bz2
scala-8906a074620568db26ba449296031dd3477d8b72.zip
Assorted fixes
Multiple fixes that have been accumulated during my investigations of 5273. Too heterogeneous to describe here, too minor to split into changesets.
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala3
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala2
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala43
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala12
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala55
-rw-r--r--src/compiler/scala/tools/nsc/ast/Reifiers.scala16
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala14
8 files changed, 85 insertions, 62 deletions
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index a072a2eebe..c170eb334f 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -370,7 +370,10 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val self: NameType = "self"
val setAccessible: NameType = "setAccessible"
val setAnnotations: NameType = "setAnnotations"
+ val setSymbol: NameType = "setSymbol"
+ val setType: NameType = "setType"
val setTypeSignature: NameType = "setTypeSignature"
+
val synchronized_ : NameType = "synchronized"
val tail: NameType = "tail"
val thisModuleType: NameType = "thisModuleType"
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 819d94f41a..8e63e3a63c 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -2595,7 +2595,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) {
- override def hashCode = value.hashCode
+ override def hashCode = if (value == null) 0 else value.hashCode
override def equals(other: Any): Boolean = other match {
case that: FreeVar => this.value.asInstanceOf[AnyRef] eq that.value.asInstanceOf[AnyRef]
case _ => false
diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala
index 63e4c9f1fa..e484faff2e 100644
--- a/src/compiler/scala/reflect/internal/TreePrinters.scala
+++ b/src/compiler/scala/reflect/internal/TreePrinters.scala
@@ -24,21 +24,30 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
}
def quotedName(name: Name): String = quotedName(name, false)
+ private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = {
+ val sym = tree.symbol
+ if (sym != null && sym != NoSymbol) {
+ val prefix = if (sym.isMixinConstructor) "/*%s*/".format(quotedName(sym.owner.name, decoded)) else ""
+ var suffix = ""
+ if (settings.uniqid.value) suffix += ("#" + sym.id)
+ if (settings.Yshowsymkinds.value) suffix += ("#" + sym.abbreviatedKindString)
+ prefix + tree.symbol.decodedName + suffix
+ } else {
+ quotedName(name, decoded)
+ }
+ }
+
+ def decodedSymName(tree: Tree, name: Name) = symNameInternal(tree, name, true)
+ def symName(tree: Tree, name: Name) = symNameInternal(tree, name, false)
+
/** Turns a path into a String, introducing backquotes
* as necessary.
*/
def backquotedPath(t: Tree): String = {
- def suffix(t: Tree) = {
- var suffix = ""
- if (t.hasSymbol && settings.uniqid.value) suffix += ("#" + t.symbol.id)
- if (t.hasSymbol && settings.Yshowsymkinds.value) suffix += ("#" + t.symbol.abbreviatedKindString)
- suffix
- }
-
t match {
- case Select(qual, name) if name.isTermName => "%s.%s".format(backquotedPath(qual), quotedName(name)) + suffix(t)
- case Select(qual, name) if name.isTypeName => "%s#%s".format(backquotedPath(qual), quotedName(name)) + suffix(t)
- case Ident(name) => quotedName(name) + suffix(t)
+ case Select(qual, name) if name.isTermName => "%s.%s".format(backquotedPath(qual), symName(t, name))
+ case Select(qual, name) if name.isTypeName => "%s#%s".format(backquotedPath(qual), symName(t, name))
+ case Ident(name) => symName(t, name)
case _ => t.toString
}
}
@@ -128,18 +137,6 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
}
private def ifSym(tree: Tree, p: Symbol => Boolean) = symFn(tree, p, false)
- private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = {
- def nameFn(sym: Symbol) = {
- val prefix = if (sym.isMixinConstructor) "/*%s*/".format(quotedName(sym.owner.name, decoded)) else ""
- val suffix = if (uniqueIds) "#"+sym.id else ""
- prefix + tree.symbol.decodedName + suffix
- }
- symFn(tree, nameFn, quotedName(name, decoded))
- }
-
- def decodedSymName(tree: Tree, name: Name) = symNameInternal(tree, name, true)
- def symName(tree: Tree, name: Name) = symNameInternal(tree, name, false)
-
def printOpt(prefix: String, tree: Tree) {
if (!tree.isEmpty) { print(prefix, tree) }
}
@@ -422,7 +419,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
case name: Name =>
print(quotedName(name))
case arg =>
- out.print(arg.toString)
+ out.print(if (arg == null) "null" else arg.toString)
}
}
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index 6e671ae06e..c09022e535 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -164,7 +164,13 @@ trait ToolBoxes extends { self: Universe =>
}
command.settings.outputDirs setSingleOutput virtualDirectory
- new ToolBoxGlobal(command.settings, reporter)
+ val instance = new ToolBoxGlobal(command.settings, reporter)
+
+ // need to establish a run an phase because otherwise we run into an assertion in TypeHistory
+ // that states that the period must be different from NoPeriod
+ val run = new instance.Run
+ instance.phase = run.refchecksPhase
+ instance
}
lazy val importer = new compiler.Importer {
@@ -176,10 +182,6 @@ trait ToolBoxes extends { self: Universe =>
lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, defaultReflectiveClassLoader)
private def importAndTypeCheck(tree: rm.Tree, expectedType: rm.Type): compiler.Tree = {
- // need to establish a run an phase because otherwise we run into an assertion in TypeHistory
- // that states that the period must be different from NoPeriod
- val run = new compiler.Run
- compiler.phase = run.refchecksPhase
val ctree: compiler.Tree = importer.importTree(tree.asInstanceOf[Tree])
val pt: compiler.Type = importer.importType(expectedType.asInstanceOf[Type])
// val typer = compiler.typer.atOwner(ctree, if (owner.isModule) cowner.moduleClass else cowner)
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index ea51fc0141..9466d1c1f2 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -71,34 +71,39 @@ abstract class NodePrinters {
def nodeinfo(tree: Tree): String =
if (infolevel == InfoLevel.Quiet) ""
else {
- val buf = new StringBuilder(" // sym=" + tree.symbol)
- if (tree.hasSymbol) {
- if (tree.symbol.isPrimaryConstructor)
- buf.append(", isPrimaryConstructor")
- else if (tree.symbol.isConstructor)
- buf.append(", isConstructor")
- if (tree.symbol != NoSymbol)
- buf.append(", sym.owner=" + tree.symbol.owner)
- buf.append(", sym.tpe=" + tree.symbol.tpe)
- }
- buf.append(", tpe=" + tree.tpe)
- if (tree.tpe != null) {
- var sym = tree.tpe.termSymbol
- if (sym == NoSymbol) sym = tree.tpe.typeSymbol
- buf.append(", tpe.sym=" + sym)
- if (sym != NoSymbol) {
- buf.append(", tpe.sym.owner=" + sym.owner)
- if ((infolevel > InfoLevel.Normal) &&
- !(sym.owner eq definitions.ScalaPackageClass) &&
- !sym.isModuleClass && !sym.isPackageClass &&
- !sym.isJavaDefined) {
- val members = for (m <- tree.tpe.decls)
- yield m.toString() + ": " + m.tpe + ", "
- buf.append(", tpe.decls=" + members)
+ try {
+ val buf = new StringBuilder(" // sym=" + tree.symbol)
+ if (tree.hasSymbol) {
+ if (tree.symbol.isPrimaryConstructor)
+ buf.append(", isPrimaryConstructor")
+ else if (tree.symbol.isConstructor)
+ buf.append(", isConstructor")
+ if (tree.symbol != NoSymbol)
+ buf.append(", sym.owner=" + tree.symbol.owner)
+ buf.append(", sym.tpe=" + tree.symbol.tpe)
+ }
+ buf.append(", tpe=" + tree.tpe)
+ if (tree.tpe != null) {
+ var sym = tree.tpe.termSymbol
+ if (sym == NoSymbol) sym = tree.tpe.typeSymbol
+ buf.append(", tpe.sym=" + sym)
+ if (sym != NoSymbol) {
+ buf.append(", tpe.sym.owner=" + sym.owner)
+ if ((infolevel > InfoLevel.Normal) &&
+ !(sym.owner eq definitions.ScalaPackageClass) &&
+ !sym.isModuleClass && !sym.isPackageClass &&
+ !sym.isJavaDefined) {
+ val members = for (m <- tree.tpe.decls)
+ yield m.toString() + ": " + m.tpe + ", "
+ buf.append(", tpe.decls=" + members)
+ }
}
}
+ buf.toString
+ } catch {
+ case ex: Throwable =>
+ return " // sym= <error> " + ex.getMessage
}
- buf.toString
}
def nodeinfo2(tree: Tree): String =
(if (comma) "," else "") + nodeinfo(tree)
diff --git a/src/compiler/scala/tools/nsc/ast/Reifiers.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala
index ac6c8c4c77..105d2cb62b 100644
--- a/src/compiler/scala/tools/nsc/ast/Reifiers.scala
+++ b/src/compiler/scala/tools/nsc/ast/Reifiers.scala
@@ -290,14 +290,20 @@ trait Reifiers { self: Global =>
if (definedInLiftedCode(tt.tpe)) {
// erase non-essential (i.e. inferred) types
// reify symless counterparts of essential types
+ // @xeno.by: in general case reflective compiler lacks the context to typecheck the originals
+ // more info here: https://issues.scala-lang.org/browse/SI-5273?focusedCommentId=56057#comment-56057
+ // this is A BIG BAD TODO!
if (tt.original != null) reify(tt.original) else mirrorCall("TypeTree")
} else {
var rtt = mirrorCall(nme.TypeTree, reifyType(tt.tpe))
- if (tt.original != null) {
- val setOriginal = Select(rtt, newTermName("setOriginal"))
- val reifiedOriginal = reify(tt.original)
- rtt = Apply(setOriginal, List(reifiedOriginal))
- }
+ // @xeno.by: originals get typechecked during subsequent reflective compilation, which leads to subtle bugs
+ // https://issues.scala-lang.org/browse/SI-5273?focusedCommentId=56057#comment-56057
+ // until this is somehow sorted out, I disable reification of originals
+ // if (tt.original != null) {
+ // val setOriginal = Select(rtt, newTermName("setOriginal"))
+ // val reifiedOriginal = reify(tt.original)
+ // rtt = Apply(setOriginal, List(reifiedOriginal))
+ // }
rtt
}
case ta @ TypeApply(hk, ts) =>
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 5c3071739c..c060e938bb 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -58,7 +58,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
treePrinter.print("<tree with deferred refcheck>")
case SelectFromArray(qualifier, name, _) =>
- treePrinter.print(qualifier, ".<arr>", treePrinter.symName(tree, name))
+ treePrinter.print(qualifier, ".<arr>", symName(tree, name))
case _ =>
super.xprintTree(treePrinter, tree)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index b2ee36ee11..a2c918024f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -98,7 +98,7 @@ trait Macros { self: Analyzer =>
}
/** Return optionally address of companion object and implementation method symbol
- * of given macro; or None if implementation classfile cannot be loaded or does
+ * of given macro; or None if implementation classfile cannot be loaded or does
* not contain the macro implementation.
*/
def macroImpl(mac: Symbol): Option[(AnyRef, mirror.Symbol)] = {
@@ -139,7 +139,15 @@ trait Macros { self: Analyzer =>
else as
}
val rawArgs: Seq[Any] = rawArgss.flatten
+ val savedInfolevel = nodePrinters.infolevel
try {
+ // @xeno.by: InfoLevel.Verbose examines and prints out infos of symbols
+ // by the means of this'es these symbols can climb up the lexical scope
+ // when these symbols will be examined by a node printer
+ // they will enumerate and analyze their children (ask for infos and tpes)
+ // if one of those children involves macro expansion, things might get nasty
+ // that's why I'm temporarily turning this behavior off
+ nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet
Some(mirror.invoke(receiver, rmeth)(rawArgs: _*))
} catch {
case ex =>
@@ -149,6 +157,8 @@ trait Macros { self: Analyzer =>
val msg = System.getProperty("line.separator") + stacktrace
context.unit.error(tree.pos, "exception during macro expansion: " + msg)
None
+ } finally {
+ nodePrinters.infolevel = savedInfolevel
}
case None =>
val trace = scala.tools.nsc.util.trace when settings.debug.value
@@ -162,7 +172,7 @@ trait Macros { self: Analyzer =>
macroDef.allOverriddenSymbols match {
case first :: _ =>
Some(Select(qual, name) setPos tree.pos setSymbol first)
- case _ =>
+ case _ =>
trace("macro is not overridden: ")(tree)
notFound()
}