diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-02-06 15:54:36 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-02-06 17:20:11 +0100 |
commit | 8906a074620568db26ba449296031dd3477d8b72 (patch) | |
tree | 0b524c89f2b4e4c3f2b8586563191ccb305c023f | |
parent | 28b2d0c13aba7156431076119c920c7dcee6dc77 (diff) | |
download | scala-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.
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() } |