diff options
Diffstat (limited to 'src/compiler/scala/tools')
16 files changed, 223 insertions, 258 deletions
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala index 04ff0c440d..3c79fcd3fb 100644 --- a/src/compiler/scala/tools/ant/Scalac.scala +++ b/src/compiler/scala/tools/ant/Scalac.scala @@ -90,7 +90,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared { /** Defines valid values for properties that refer to compiler phases. */ object CompilerPhase extends PermissibleValue { - val values = List("namer", "typer", "pickler", "refchecks", "liftcode", + val values = List("namer", "typer", "pickler", "refchecks", "uncurry", "tailcalls", "specialize", "explicitouter", "erasure", "lazyvals", "lambdalift", "constructors", "flatten", "mixin", "cleanup", "icode", "inliner", 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/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 8e5ca2156a..281a2eb49b 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -37,6 +37,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb with Plugins with PhaseAssembly with Trees + with Reifiers with TreePrinters with DocComments with MacroContext @@ -124,7 +125,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb /** Print tree in detailed form */ object nodePrinters extends { val global: Global.this.type = Global.this - } with NodePrinters { + } with NodePrinters with ReifyPrinters { infolevel = InfoLevel.Verbose } @@ -134,6 +135,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb } with TreeBrowsers val nodeToString = nodePrinters.nodeToString + val reifiedNodeToString = nodePrinters.reifiedNodeToString val treeBrowser = treeBrowsers.create() // ------------ Hooks for interactive mode------------------------- @@ -463,17 +465,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb val runsRightAfter = None } with RefChecks - // phaseName = "liftcode" - object liftcode extends { - val global: Global.this.type = Global.this - val runsAfter = List("refchecks") - val runsRightAfter = None - } with LiftCode - // phaseName = "uncurry" override object uncurry extends { val global: Global.this.type = Global.this - val runsAfter = List("refchecks", "liftcode") + val runsAfter = List("refchecks") val runsRightAfter = None } with UnCurry @@ -659,7 +654,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb extensionMethods -> "add extension methods for inline classes", pickler -> "serialize symbol tables", refChecks -> "reference/override checking, translate nested objects", - liftcode -> "reify trees", uncurry -> "uncurry, translate function values to anonymous classes", tailCalls -> "replace tail calls by jumps", specializeTypes -> "@specialized-driven class and method specialization", @@ -1090,7 +1084,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def compiles(sym: Symbol): Boolean = if (sym == NoSymbol) false else if (symSource.isDefinedAt(sym)) true - else if (!sym.owner.isPackageClass) compiles(sym.toplevelClass) + else if (!sym.owner.isPackageClass) compiles(sym.enclosingTopLevelClass) else if (sym.isModuleClass) compiles(sym.sourceModule) else false 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/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala index 8affea56a2..c05475d50c 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/ast/Reifiers.scala @@ -5,7 +5,7 @@ */ package scala.tools.nsc -package transform +package ast import symtab._ import Flags._ @@ -14,174 +14,44 @@ import scala.collection.mutable.ListBuffer import scala.tools.nsc.util.FreshNameCreator import scala.runtime.ScalaRunTime.{ isAnyVal, isTuple } -/** - * Translate expressions of the form reflect.Code.lift(exp) - * to the reified "reflect trees" representation of exp. - * Also: mutable variables that are accessed from a local function are wrapped in refs. +/** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type. + * See more info in the comments to `reify' in scala.reflect.macro.Context. * * @author Martin Odersky * @version 2.10 */ -abstract class LiftCode extends Transform with TypingTransformers { - - import global._ // the global environment - import definitions._ // standard classes and methods - import typer.{ typed, atOwner } // methods to type trees - - val symbols: global.type = global - - /** the following two members override abstract members in Transform */ - val phaseName: String = "liftcode" - - def newTransformer(unit: CompilationUnit): Transformer = - new Codifier(unit) - - private lazy val MirrorMemberNames = - ReflectRuntimeMirror.info.nonPrivateMembers filter (_.isTerm) map (_.toString) toSet - - // Would be nice if we could use something like this to check the names, - // but it seems that info is unavailable when I need it. - private def mirrorFactoryName(value: Any): Option[String] = value match { - // Modest (inadequate) sanity check that there's a member by this name. - case x: Product if MirrorMemberNames(x.productPrefix) => - Some(x.productPrefix) - case _ => - Some(value.getClass.getName split """[$.]""" last) filter MirrorMemberNames - } - private def isMirrorMemberObject(value: Product) = value match { - case NoType | NoPrefix | NoPosition | EmptyTree => true - case _ => false - } - - class Codifier(unit: CompilationUnit) extends TypingTransformer(unit) { - - val reifyDebug = settings.Yreifydebug.value - val reifyTyperDebug = settings.Yreifytyperdebug.value - val debugTrace = util.trace when reifyDebug - - val reifyCopypaste = settings.Yreifycopypaste.value - def printCopypaste(tree: Tree) { - if (reifyDebug) println("=======================") - printCopypaste1(tree) - if (reifyDebug) println("=======================") - } - def printCopypaste1(tree: Tree) { - import scala.reflect.api.Modifier - import scala.reflect.api.Modifier._ - - def copypasteModifier(mod: Modifier.Value): String = mod match { - case mod @ ( - `protected` | `private` | `override` | - `abstract` | `final` | `sealed` | - `implicit` | `lazy` | `macro` | - `case` | `trait`) => "`" + mod.toString + "`" - case mod => mod.toString - } - - // I fervently hope this is a test case or something, not anything being - // depended upon. Of more fragile code I cannot conceive. - for (line <- (tree.toString.split(Properties.lineSeparator) drop 2 dropRight 1)) { - var s = line.trim - s = s.replace("$mr.", "") - s = s.replace(".apply", "") - s = s.replace("scala.collection.immutable.", "") - s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") - s = "List\\[.*?\\]".r.replaceAllIn(s, "List") - s = s.replace("immutable.this.Nil", "List()") - s = s.replace("modifiersFromInternalFlags", "Modifiers") - s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()") - s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => { - val buf = new StringBuilder - - val flags = m.group(1).toLong - val s_flags = Flags.modifiersOfFlags(flags) map copypasteModifier mkString ", " - if (s_flags != "") - buf.append("Set(" + s_flags + ")") - - val privateWithin = "" + m.group(2) - if (privateWithin != "") - buf.append(", newTypeName(\"" + privateWithin + "\")") - - val annotations = m.group(3) - if (annotations.nonEmpty) - buf.append(", List(" + annotations + ")") - - "Modifiers(" + buf.toString + ")" - }) - s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => { - val flags = m.group(1).toLong - val mods = Flags.modifiersOfFlags(flags) map copypasteModifier - "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))" - }) - - println(s) - } - } - - override def transformUnit(unit: CompilationUnit) { - atPhase(phase.next) { - super.transformUnit(unit) - } - } - - override def transform(tree: Tree): Tree = { - val sym = tree.symbol - tree match { - case Apply(_, List(tree)) if sym == Code_lift => // reify Code.lift[T](expr) instances - val saved = printTypings - try { - debugTrace("transforming = ")(if (settings.Xshowtrees.value) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) - debugTrace("transformed = ") { - val untyped = codify(super.transform(tree)) - if (reifyCopypaste) printCopypaste(untyped) - - printTypings = reifyTyperDebug - val typed = localTyper.typedPos(tree.pos)(untyped) - typed - } - } catch { - case ex: ReifierError => - unit.error(ex.pos, ex.msg) - tree - } finally { - printTypings = saved +trait Reifiers { self: Global => + + def reify(tree: Tree): Tree = { + if (tree.tpe != null) { + val saved = printTypings + try { + val reifyDebug = settings.Yreifydebug.value + val debugTrace = util.trace when reifyDebug + debugTrace("transforming = ")(if (settings.Xshowtrees.value) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) + debugTrace("transformed = ") { + val reifier = new Reifier() + val untyped = reifier.reifyTopLevel(tree) + + val reifyCopypaste = settings.Yreifycopypaste.value + if (reifyCopypaste) { + if (reifyDebug) println("=======================") + println(reifiedNodeToString(untyped)) + if (reifyDebug) println("=======================") } - case _ => - super.transform(tree) - } - } - def codify(tree: Tree): Tree = debugTrace("codified " + tree + " -> ") { - val targetType = definitions.CodeClass.primaryConstructor.info.paramTypes.head - val reifier = new Reifier() - val arg = gen.mkAsInstanceOf(reifier.reifyTopLevel(tree), targetType, wrapInApply = false) - val treetpe = // this really should use packedType(tree.tpe, context.owner) - // where packedType is defined in Typers. But we can do that only if liftCode is moved to Typers. - if (tree.tpe.typeSymbol.isAnonymousClass) tree.tpe.typeSymbol.classBound - else tree.tpe - New(TypeTree(appliedType(definitions.CodeClass.typeConstructor, List(treetpe.widen))), - List(List(arg))) + untyped + } + } finally { + printTypings = saved + } + } else { + CannotReifyPreTyperTrees(tree) } } - /** - * Given a tree or type, generate a tree that when executed at runtime produces the original tree or type. - * For instance: Given - * - * var x = 1; Code(x + 1) - * - * The `x + 1` expression is reified to - * - * $mr.Apply($mr.Select($mr.Ident($mr.freeVar("x". <Int>, x), "+"), List($mr.Literal($mr.Constant(1)))))) - * - * Or, the term name 'abc' is reified to: - * - * $mr.Apply($mr.Select($mr.Ident("newTermName")), List(Literal(Constant("abc"))))) - * - * todo: Treat embedded Code blocks by merging them into containing block - * - */ class Reifier() { + import definitions._ final val scalaPrefix = "scala." final val localPrefix = "$local" @@ -291,8 +161,6 @@ abstract class LiftCode extends Transform with TypingTransformers { mirrorSelect("definitions.RootClass") else if (sym == EmptyPackage) mirrorSelect("definitions.EmptyPackage") - else if (sym == EmptyPackageClass) - mirrorSelect("definitions.EmptyPackageClass") else if (sym.isModuleClass) Select(reifySymRef(sym.sourceModule), "moduleClass") else if (sym.isStatic && sym.isClass) @@ -321,7 +189,7 @@ abstract class LiftCode extends Transform with TypingTransformers { val symtpe = lambdaLift.boxIfCaptured(sym, sym.tpe, erasedTypes = false) def markIfCaptured(arg: Ident): Tree = if (sym.isCapturedVariable) referenceCapturedVariable(arg) else arg - mirrorCall("freeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym))) + mirrorCall("newFreeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym))) } else { if (reifyDebug) println("Late local: " + sym) registerReifiableSymbol(sym) @@ -349,7 +217,7 @@ abstract class LiftCode extends Transform with TypingTransformers { * Generate code to add type and annotation info to a reified symbol */ private def fillInSymbol(sym: Symbol): Tree = { - val rset = Apply(Select(reifySymRef(sym), nme.setTypeSig), List(reifyType(sym.info))) + val rset = Apply(Select(reifySymRef(sym), nme.setTypeSignature), List(reifyType(sym.info))) if (sym.annotations.isEmpty) rset else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) } @@ -412,9 +280,9 @@ abstract class LiftCode extends Transform with TypingTransformers { private def reifyTree(tree: Tree): Tree = tree match { case EmptyTree => reifyMirrorObject(EmptyTree) - case This(_) if !(boundSyms contains tree.symbol) => + case This(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) => reifyFree(tree) - case Ident(_) if !(boundSyms contains tree.symbol) => + case Ident(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) => if (tree.symbol.isVariable && tree.symbol.owner.isTerm) { captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reifyTree here. mirrorCall("Select", reifyFree(tree), reifyName(nme.elem)) @@ -423,19 +291,25 @@ abstract class LiftCode extends Transform with TypingTransformers { 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) => if (ts exists isErased) reifyTree(hk) else reifyProduct(ta) - case global.emptyValDef => + case self.emptyValDef => mirrorSelect(nme.emptyValDef) case Literal(constant @ Constant(tpe: Type)) if boundSyms exists (tpe contains _) => CannotReifyClassOfBoundType(tree, tpe) @@ -466,7 +340,7 @@ abstract class LiftCode extends Transform with TypingTransformers { val sym = tree.symbol if (reifyDebug) println("This for %s, reified as freeVar".format(sym)) if (reifyDebug) println("Free: " + sym) - val freeVar = mirrorCall("freeVar", reify(sym.name.toString), reify(sym.tpe), This(sym)) + val freeVar = mirrorCall("newFreeVar", reify(sym.name.toString), reify(sym.tpe), This(sym)) mirrorCall(nme.Ident, freeVar) case This(_) => if (reifyDebug) println("This for %s, reified as This".format(tree.symbol)) @@ -535,7 +409,7 @@ abstract class LiftCode extends Transform with TypingTransformers { private def typePath(fullname: String): Tree = path(fullname, newTypeName) private def mirrorAlias = - ValDef(NoMods, nme.MIRROR_SHORT, TypeTree(), termPath(fullnme.MirrorPackage)) + ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(termPath(fullnme.MirrorPackage)), termPath(fullnme.MirrorPackage)) /** * Generate code that generates a symbol table of all symbols registered in `reifiableSyms` @@ -559,6 +433,11 @@ abstract class LiftCode extends Transform with TypingTransformers { def this(msg: String) = this(NoPosition, msg) } + def CannotReifyPreTyperTrees(tree: Tree) = { + val msg = "pre-typer trees are not supported, consider typechecking the tree before passing it to the reifier" + throw new ReifierError(tree.pos, msg) + } + def CannotReifyClassOfBoundType(tree: Tree, tpe: Type) = { val msg = "cannot reify classOf[%s] which refers to a type declared inside the block being reified".format(tpe) throw new ReifierError(tree.pos, msg) diff --git a/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala b/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala new file mode 100644 index 0000000000..98135fadda --- /dev/null +++ b/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala @@ -0,0 +1,75 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc +package ast + +import compat.Platform.EOL +import symtab._ +import Flags._ + +trait ReifyPrinters { self: NodePrinters => + + val global: Global + import global._ + + object reifiedNodeToString extends Function1[Tree, String] { + def apply(tree: Tree): String = { + import scala.reflect.api.Modifier + + // @PP: I fervently hope this is a test case or something, not anything being + // depended upon. Of more fragile code I cannot conceive. + // @eb: This stuff is only needed to debug-print out reifications in human-readable format + // Rolling a full-fledged, robust TreePrinter would be several times more code. + (for (line <- (tree.toString.split(EOL) drop 2 dropRight 1)) yield { + var s = line.trim + s = s.replace("$mr.", "") + s = s.replace(".apply", "") + s = s.replace("scala.collection.immutable.", "") + s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") + s = "List\\[.*?\\]".r.replaceAllIn(s, "List") + s = s.replace("immutable.this.Nil", "List()") + s = s.replace("modifiersFromInternalFlags", "Modifiers") + s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()") + s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => { + val buf = new StringBuilder + + val flags = m.group(1).toLong + val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", " + if (s_flags != "") + buf.append("Set(" + s_flags + ")") + + val privateWithin = "" + m.group(2) + if (privateWithin != "") + buf.append(", newTypeName(\"" + privateWithin + "\")") + + val annotations = m.group(3) + if (annotations.nonEmpty) + buf.append(", List(" + annotations + ")") + + "Modifiers(" + buf.toString + ")" + }) + s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => { + val flags = m.group(1).toLong + val mods = Flags.modifiersOfFlags(flags) map (_.sourceString) + "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))" + }) + + s + }) mkString EOL + } + } + + + def printReifyCopypaste(tree: Tree) { + val reifyDebug = settings.Yreifydebug.value + if (reifyDebug) println("=======================") + printReifyCopypaste1(tree) + if (reifyDebug) println("=======================") + } + + def printReifyCopypaste1(tree: Tree) { + } +}
\ No newline at end of file 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/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 3baff7da9e..6aee52a354 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -133,7 +133,7 @@ abstract class GenICode extends SubComponent { if (!ctx1.bb.closed) ctx1.bb.close prune(ctx1.method) } else - ctx1.method.setCode(null) + ctx1.method.setCode(NoCode) ctx1 case Template(_, _, body) => diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 2668e7f29f..298c9171a1 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -177,8 +177,7 @@ trait Members { /** method parameters */ var params: List[Local] = Nil - // TODO - see how null is stil arriving here - def hasCode = (code ne NoCode) && (code ne null) + def hasCode = code ne NoCode def setCode(code: Code): IMethod = { this.code = code; this diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index d1ce460eb9..485a1f3a5c 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -167,8 +167,6 @@ trait ScalaSettings extends AbsScalaSettings val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") val Yreifydebug = BooleanSetting ("-Yreify-debug", "Trace reification.") - val Yreifytyperdebug - = BooleanSetting ("-Yreifytyper-debug", "Trace typings of reified trees.") val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") . withPostSetHook(_ => interpreter.replProps.debug setValue true) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index d8db62a408..ed89acd9e8 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -1269,13 +1269,13 @@ abstract class ClassfileParser { if ((jflags & (JAVA_ACC_PRIVATE | JAVA_ACC_PROTECTED | JAVA_ACC_PUBLIC)) == 0) // See ticket #1687 for an example of when topLevelClass is NoSymbol: it // apparently occurs when processing v45.3 bytecode. - if (sym.toplevelClass != NoSymbol) - sym.privateWithin = sym.toplevelClass.owner + if (sym.enclosingTopLevelClass != NoSymbol) + sym.privateWithin = sym.enclosingTopLevelClass.owner // protected in java means package protected. #3946 if ((jflags & JAVA_ACC_PROTECTED) != 0) - if (sym.toplevelClass != NoSymbol) - sym.privateWithin = sym.toplevelClass.owner + if (sym.enclosingTopLevelClass != NoSymbol) + sym.privateWithin = sym.enclosingTopLevelClass.owner } @inline private def isPrivate(flags: Int) = (flags & JAVA_ACC_PRIVATE) != 0 diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index 4fa5b52de3..89f1cc26e0 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -60,8 +60,8 @@ abstract class Flatten extends InfoTransform { private val flattened = new TypeMap { def apply(tp: Type): Type = tp match { case TypeRef(pre, sym, args) if isFlattenablePrefix(pre) => - assert(args.isEmpty && sym.toplevelClass != NoSymbol, sym.ownerChain) - typeRef(sym.toplevelClass.owner.thisType, sym, Nil) + assert(args.isEmpty && sym.enclosingTopLevelClass != NoSymbol, sym.ownerChain) + typeRef(sym.enclosingTopLevelClass.owner.thisType, sym, Nil) case ClassInfoType(parents, decls, clazz) => var parents1 = parents val decls1 = scopeTransform(clazz) { @@ -119,7 +119,7 @@ abstract class Flatten extends InfoTransform { val sym = tree.symbol val tree1 = tree match { case ClassDef(_, _, _, _) if sym.isNestedClass => - liftedDefs(sym.toplevelClass.owner) += tree + liftedDefs(sym.enclosingTopLevelClass.owner) += tree EmptyTree case Select(qual, name) if (sym.isStaticModule && !sym.owner.isPackageClass) => atPhase(phase.next) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 036e7fc750..3d2f86d54d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1163,7 +1163,7 @@ trait Implicits { /* !!! the following is almost right, but we have to splice nested manifest * !!! types into this type. This requires a substantial extension of * !!! reifiers. - val reifier = new liftcode.Reifier() + val reifier = new Reifier() val rtree = reifier.reifyTopLevel(tp1) manifestFactoryCall("apply", tp, rtree) */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index eac657da19..b97fbebec2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -228,9 +228,9 @@ trait Infer { if (sym.isError) { tree setSymbol sym setType ErrorType } else { - val topClass = context.owner.toplevelClass + val topClass = context.owner.enclosingTopLevelClass if (context.unit.exists) - context.unit.depends += sym.toplevelClass + context.unit.depends += sym.enclosingTopLevelClass var sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super])) // Console.println("check acc " + (sym, sym1) + ":" + (sym.tpe, sym1.tpe) + " from " + pre);//DEBUG @@ -640,13 +640,7 @@ trait Infer { case ExistentialType(tparams, qtpe) => isApplicable(undetparams, qtpe, argtpes0, pt) case MethodType(params, _) => - val formals0 = params map { param => - param.tpe match { - case TypeRef(_, sym, List(tpe)) if sym isNonBottomSubClass CodeClass => tpe - case tpe => tpe - } - } - val formals = formalTypes(formals0, argtpes0.length) + val formals = formalTypes(params map { _.tpe }, argtpes0.length) def tryTupleApply: Boolean = { // if 1 formal, 1 argtpe (a tuple), otherwise unmodified argtpes0 diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index c63ae90ef6..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)] = { @@ -106,13 +106,16 @@ trait Macros { self: Analyzer => val mmeth = macroMeth(mac) if (mmeth == NoSymbol) None else { - val receiverClass: mirror.Symbol = mirror.classWithName(mmeth.owner.fullName) + val receiverClass: mirror.Symbol = mirror.symbolForName(mmeth.owner.fullName) val receiverObj = receiverClass.companionModule - if (receiverObj == NoSymbol) None + if (receiverObj == mirror.NoSymbol) None else { - val receiver = mirror.getCompanionObject(receiverClass) + val receiver = mirror.companionInstance(receiverClass) val rmeth = receiverObj.info.member(mirror.newTermName(mmeth.name.toString)) - Some((receiver, rmeth)) + if (rmeth == mirror.NoSymbol) None + else { + Some((receiver, rmeth)) + } } } } catch { @@ -136,8 +139,16 @@ trait Macros { self: Analyzer => else as } val rawArgs: Seq[Any] = rawArgss.flatten + val savedInfolevel = nodePrinters.infolevel try { - Some(mirror.invoke(receiver, rmeth, rawArgs: _*)) + // @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 => val realex = ReflectionUtils.unwrapThrowable(ex) @@ -146,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 @@ -159,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/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 66330d4321..59437dc036 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -708,8 +708,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - def isCodeType(tpe: Type) = tpe.typeSymbol isNonBottomSubClass CodeClass - /** Perform the following adaptations of expression, pattern or type `tree` wrt to * given mode `mode` and given prototype `pt`: * (-1) For expressions with annotated types, let AnnotationCheckers decide what to do @@ -2005,8 +2003,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { */ def typedFunction(fun: Function, mode: Int, pt: Type): Tree = { val numVparams = fun.vparams.length - val codeExpected = !forMSIL && (pt.typeSymbol isNonBottomSubClass CodeClass) - if (numVparams > definitions.MaxFunctionArity) return MaxFunctionArityError(fun) @@ -2023,7 +2019,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else (FunctionClass(numVparams), fun.vparams map (x => NoType), WildcardType) - val (clazz, argpts, respt) = decompose(if (codeExpected) pt.normalize.typeArgs.head else pt) + val (clazz, argpts, respt) = decompose(pt) if (argpts.lengthCompare(numVparams) != 0) WrongNumberOfParametersError(fun, argpts) else { @@ -2033,7 +2029,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (isFullyDefined(argpt)) argpt else { fun match { - case etaExpansion(vparams, fn, args) if !codeExpected => + case etaExpansion(vparams, fn, args) => silent(_.typed(fn, forFunMode(mode), pt)) match { case SilentResultValue(fn1) if context.undetparams.isEmpty => // if context,undetparams is not empty, the function was polymorphic, @@ -2065,13 +2061,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val restpe = packedType(body1, fun.symbol).deconst.resultType val funtpe = typeRef(clazz.tpe.prefix, clazz, formals :+ restpe) // body = checkNoEscaping.locals(context.scope, restpe, body) - val fun1 = treeCopy.Function(fun, vparams, body1).setType(funtpe) - if (codeExpected) lifted(fun1) else fun1 - } + treeCopy.Function(fun, vparams, body1).setType(funtpe) } - - def lifted(tree: Tree): Tree = typedPos(tree.pos) { - Apply(Select(Ident(CodeModule), nme.lift_), List(tree)) } def typedRefinement(stats: List[Tree]) { @@ -3733,7 +3724,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { return typed(treeCopy.Select(tree, qual1, name), mode, pt) } if (!reallyExists(sym)) { - if (context.owner.toplevelClass.isJavaDefined && name.isTypeName) { + if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) { val tree1 = atPos(tree.pos) { gen.convertToSelectFromType(qual, name) } if (tree1 != EmptyTree) return typed1(tree1, mode, pt) } |