diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/StdNames.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/TreePrinters.scala | 43 | ||||
-rw-r--r-- | src/compiler/scala/reflect/runtime/ToolBoxes.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/ant/Scaladoc.scala | 27 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/NodePrinters.scala | 55 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Reifiers.scala | 16 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreePrinters.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 14 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/HashMap.scala | 19 |
10 files changed, 119 insertions, 74 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/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala index 253d1dec5d..92d6e6320c 100644 --- a/src/compiler/scala/tools/ant/Scaladoc.scala +++ b/src/compiler/scala/tools/ant/Scaladoc.scala @@ -43,7 +43,8 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} * - `deprecation`, * - `docgenerator`, * - `docrootcontent`, - * - `unchecked`. + * - `unchecked`, + * - `nofail`. * * It also takes the following parameters as nested elements: * - `src` (for srcdir), @@ -122,7 +123,10 @@ class Scaladoc extends ScalaMatchingTask { /** Instruct the compiler to generate unchecked information. */ private var unchecked: Boolean = false - + + /** Instruct the ant task not to fail in the event of errors */ + private var nofail: Boolean = false + /*============================================================================*\ ** Properties setters ** \*============================================================================*/ @@ -352,6 +356,17 @@ class Scaladoc extends ScalaMatchingTask { def setDocUncompilable(input: String) { docUncompilable = Some(input) } + + /** Set the `nofail` info attribute. + * + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. + */ + def setNoFail(input: String) { + if (Flag.isPermissible(input)) + nofail = "yes".equals(input) || "on".equals(input) + else + buildError("Unknown nofail flag '" + input + "'") + } /*============================================================================*\ ** Properties getters ** @@ -553,6 +568,8 @@ class Scaladoc extends ScalaMatchingTask { Pair(docSettings, sourceFiles) } + def safeBuildError(message: String): Unit = if (nofail) log(message) else buildError(message) + /** Performs the compilation. */ override def execute() = { val Pair(docSettings, sourceFiles) = initialize @@ -561,7 +578,7 @@ class Scaladoc extends ScalaMatchingTask { val docProcessor = new scala.tools.nsc.doc.DocFactory(reporter, docSettings) docProcessor.document(sourceFiles.map (_.toString)) if (reporter.ERROR.count > 0) - buildError( + safeBuildError( "Document failed with " + reporter.ERROR.count + " error" + (if (reporter.ERROR.count > 1) "s" else "") + @@ -576,11 +593,11 @@ class Scaladoc extends ScalaMatchingTask { } catch { case exception: Throwable if exception.getMessage ne null => exception.printStackTrace() - buildError("Document failed because of an internal documenter error (" + + safeBuildError("Document failed because of an internal documenter error (" + exception.getMessage + "); see the error output for details.") case exception => exception.printStackTrace() - buildError("Document failed because of an internal documenter error " + + safeBuildError("Document failed because of an internal documenter error " + "(no error message provided); see the error output for details.") } } 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() } diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 9cde20f1df..6b11371bec 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -138,8 +138,10 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int { override def updated0[B1 >: B](key: A, hash: Int, level: Int, value: B1, kv: (A, B1), merger: Merger[B1]): HashMap[A, B1] = if (hash == this.hash && key == this.key ) { - if (merger eq null) new HashMap1(key, hash, value, kv) - else new HashMap1(key, hash, value, merger(this.kv, kv)) + if (merger eq null) { + if(this.value.asInstanceOf[AnyRef] eq value.asInstanceOf[AnyRef]) this + else new HashMap1(key, hash, value, kv) + } else new HashMap1(key, hash, value, merger(this.kv, kv)) } else { var thatindex = (hash >>> level) & 0x1f var thisindex = (this.hash >>> level) & 0x1f @@ -271,13 +273,15 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int { val mask = (1 << index) val offset = Integer.bitCount(bitmap & (mask-1)) if ((bitmap & mask) != 0) { - val elemsNew = new Array[HashMap[A,B1]](elems.length) - Array.copy(elems, 0, elemsNew, 0, elems.length) val sub = elems(offset) // TODO: might be worth checking if sub is HashTrieMap (-> monomorphic call site) val subNew = sub.updated0(key, hash, level + 5, value, kv, merger) - elemsNew(offset) = subNew - new HashTrieMap(bitmap, elemsNew, size + (subNew.size - sub.size)) + if(subNew eq sub) this else { + val elemsNew = new Array[HashMap[A,B1]](elems.length) + Array.copy(elems, 0, elemsNew, 0, elems.length) + elemsNew(offset) = subNew + new HashTrieMap(bitmap, elemsNew, size + (subNew.size - sub.size)) + } } else { val elemsNew = new Array[HashMap[A,B1]](elems.length + 1) Array.copy(elems, 0, elemsNew, 0, offset) @@ -295,7 +299,8 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int { val sub = elems(offset) // TODO: might be worth checking if sub is HashTrieMap (-> monomorphic call site) val subNew = sub.removed0(key, hash, level + 5) - if (subNew.isEmpty) { + if (subNew eq sub) this + else if (subNew.isEmpty) { val bitmapNew = bitmap ^ mask if (bitmapNew != 0) { val elemsNew = new Array[HashMap[A,B]](elems.length - 1) |