diff options
Diffstat (limited to 'src/compiler')
27 files changed, 308 insertions, 338 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 68d93d5fe5..4d465ca4a0 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -422,9 +422,6 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val FullManifestModule = getRequiredModule("scala.reflect.Manifest") lazy val OptManifestClass = getRequiredClass("scala.reflect.OptManifest") lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest") - lazy val CodeClass = getClass(sn.Code) - lazy val CodeModule = getModule(sn.Code) - lazy val Code_lift = getMember(CodeModule, nme.lift_) lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature") lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature") @@ -628,6 +625,9 @@ trait Definitions extends reflect.api.StandardDefinitions { def ClassType(arg: Type) = if (phase.erasedTypes || forMSIL) ClassClass.tpe else appliedType(ClassClass.typeConstructor, List(arg)) + + def vmClassType(arg: Type): Type = ClassType(arg) + def vmSignature(sym: Symbol, info: Type): String = signature(info) // !!! // // .NET backend diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala index 66af92be5f..aa696bc6e8 100644 --- a/src/compiler/scala/reflect/internal/Flags.scala +++ b/src/compiler/scala/reflect/internal/Flags.scala @@ -466,7 +466,7 @@ class Flags extends ModifierFlags { } protected final val rawFlagPickledOrder: Array[Long] = pickledListOrder.toArray - def flagOfModifier(mod: Modifier.Value): Long = mod match { + def flagOfModifier(mod: Modifier): Long = mod match { case Modifier.`protected` => PROTECTED case Modifier.`private` => PRIVATE case Modifier.`override` => OVERRIDE @@ -496,13 +496,13 @@ class Flags extends ModifierFlags { case Modifier.bynameParameter => BYNAMEPARAM } - def flagsOfModifiers(mods: List[Modifier.Value]): Long = + def flagsOfModifiers(mods: List[Modifier]): Long = (mods :\ 0L) { (mod, curr) => curr | flagOfModifier(mod) } - def modifierOfFlag(flag: Long): Option[Modifier.Value] = + def modifierOfFlag(flag: Long): Option[Modifier] = Modifier.values find { mod => flagOfModifier(mod) == flag } - def modifiersOfFlags(flags: Long): List[Modifier.Value] = + def modifiersOfFlags(flags: Long): List[Modifier] = pickledListOrder map (mask => modifierOfFlag(flags & mask)) flatMap { mod => mod } } diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala index 907b564d4c..e6ca4c49ba 100644 --- a/src/compiler/scala/reflect/internal/Names.scala +++ b/src/compiler/scala/reflect/internal/Names.scala @@ -387,6 +387,13 @@ trait Names extends api.Names { * decode returns a String. */ + /** !!! Duplicative but consistently named. + */ + def decoded: String = decode + def encoded: String = "" + encode + // def decodedName: ThisNameType = newName(decoded) + def encodedName: ThisNameType = encode + /** Replace operator symbols by corresponding $op_name. */ def encode: ThisNameType = { val str = toString diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index c3a7dc23f3..1d6696a082 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -270,8 +270,9 @@ trait StdNames extends NameManglers { self: SymbolTable => // Compiler utilized names // val productElementName: NameType = "productElementName" val Ident: NameType = "Ident" - val This: NameType = "This" val StringContext: NameType = "StringContext" + val This: NameType = "This" + val Tree : NameType = "Tree" val TYPE_ : NameType = "TYPE" val TypeTree: NameType = "TypeTree" val UNIT : NameType = "UNIT" @@ -368,7 +369,10 @@ trait StdNames extends NameManglers { self: SymbolTable => val self: NameType = "self" val setAccessible: NameType = "setAccessible" val setAnnotations: NameType = "setAnnotations" - val setTypeSig: NameType = "setTypeSig" + val setSymbol: NameType = "setSymbol" + val setType: NameType = "setType" + val setTypeSignature: NameType = "setTypeSignature" + val synchronized_ : NameType = "synchronized" val tail: NameType = "tail" val thisModuleType: NameType = "thisModuleType" @@ -426,7 +430,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val toInteger: NameType = "toInteger" } - object tpnme extends TypeNames /*with LibraryTypeNames*/ with TypeNameMangling { + object tpnme extends AbsTypeNames with TypeNames /*with LibraryTypeNames*/ with TypeNameMangling { type NameType = TypeName protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name) @@ -463,7 +467,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val javanme = nme.javaKeywords - object nme extends TermNames /*with LibraryTermNames*/ with TermNameMangling { + object nme extends AbsTermNames with TermNames /*with LibraryTermNames*/ with TermNameMangling { type NameType = TermName protected implicit def createNameType(name: String): TermName = newTermNameCached(name) @@ -710,7 +714,6 @@ trait StdNames extends NameManglers { self: SymbolTable => val BoxedCharacter : TypeName val BoxedNumber : TypeName val Class : TypeName - val Code : TypeName val Delegate : TypeName val IOOBException : TypeName // IndexOutOfBoundsException val InvTargetException : TypeName // InvocationTargetException @@ -845,7 +848,6 @@ trait StdNames extends NameManglers { self: SymbolTable => final val BoxedCharacter: TypeName = "System.IConvertible" final val BoxedNumber: TypeName = "System.IConvertible" final val Class: TypeName = "System.Type" - final val Code: TypeName = tpnme.NO_NAME final val Delegate: TypeName = "System.MulticastDelegate" final val IOOBException: TypeName = "System.IndexOutOfRangeException" final val InvTargetException: TypeName = "System.Reflection.TargetInvocationException" @@ -879,7 +881,6 @@ trait StdNames extends NameManglers { self: SymbolTable => private class J2SENames extends JavaNames { final val BeanProperty: TypeName = "scala.beans.BeanProperty" final val BooleanBeanProperty: TypeName = "scala.beans.BooleanBeanProperty" - final val Code: TypeName = "scala.reflect.Code" final val JavaSerializable: TypeName = "java.io.Serializable" } diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 415b32958d..6093b0962f 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -61,13 +61,18 @@ trait Symbols extends api.Symbols { self: SymbolTable => case n: TermName => newTermSymbol(n, pos, newFlags) case n: TypeName => newTypeSymbol(n, pos, newFlags) } - def typeSig: Type = info - def typeSigIn(site: Type): Type = site.memberInfo(this) + def enclosingClass: Symbol = enclClass + def enclosingMethod: Symbol = enclMethod + def thisPrefix: Type = thisType + def selfType: Type = typeOfThis + def typeSignature: Type = info + def typeSignatureIn(site: Type): Type = site memberInfo this + def asType: Type = tpe def asTypeIn(site: Type): Type = site.memberType(this) def asTypeConstructor: Type = typeConstructor def setInternalFlags(flag: Long): this.type = { setFlag(flag); this } - def setTypeSig(tpe: Type): this.type = { setInfo(tpe); this } + def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this } def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this } } @@ -103,12 +108,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => def pos = rawpos def setPos(pos: Position): this.type = { this.rawpos = pos; this } - override def hasModifier(mod: Modifier.Value) = + /** !!! The logic after "hasFlag" is far too opaque to be unexplained. + * I'm guessing it's attempting to compensate for flag overloading, + * and embedding such logic in an undocumented island like this is a + * notarized guarantee of future breakage. + */ + override def hasModifier(mod: Modifier) = hasFlag(flagOfModifier(mod)) && (!(mod == Modifier.bynameParameter) || isTerm) && (!(mod == Modifier.covariant) || isType) - override def allModifiers: Set[Modifier.Value] = + override def modifiers: Set[Modifier] = Modifier.values filter hasModifier // ------ creators ------------------------------------------------------------------- @@ -1273,14 +1283,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** After the typer phase (before, look at the definition's Modifiers), contains * the annotations attached to member a definition (class, method, type, field). */ - def annotations: List[AnnotationInfo] = _annotations + def annotations: List[AnnotationInfo] = { + // Necessary for reflection, see SI-5423 + if (inReflexiveMirror) + initialize - /** This getter is necessary for reflection, see https://issues.scala-lang.org/browse/SI-5423 - * We could auto-inject completion into `annotations' and `setAnnotations', but I'm not sure about that - * @odersky writes: I fear we can't do the forcing for all compiler symbols as that could introduce cycles - */ - def getAnnotations: List[AnnotationInfo] = { - initialize _annotations } @@ -1574,10 +1581,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => else owner.logicallyEnclosingMember /** The top-level class containing this symbol. */ - def toplevelClass: Symbol = + def enclosingTopLevelClass: Symbol = if (owner.isPackageClass) { if (isClass) this else moduleClass - } else owner.toplevelClass + } else owner.enclosingTopLevelClass /** Is this symbol defined in the same scope and compilation unit as `that` symbol? */ def isCoDefinedWith(that: Symbol) = ( @@ -1881,7 +1888,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def sourceFile: AbstractFileType = if (isModule) moduleClass.sourceFile - else toplevelClass.sourceFile + else enclosingTopLevelClass.sourceFile def sourceFile_=(f: AbstractFileType) { abort("sourceFile_= inapplicable for " + this) @@ -2590,7 +2597,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 @@ -2613,7 +2620,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def defString: String = toString override def locationString: String = "" override def enclClass: Symbol = this - override def toplevelClass: Symbol = this + override def enclosingTopLevelClass: Symbol = this override def enclMethod: Symbol = this override def sourceFile: AbstractFileType = null override def ownerChain: List[Symbol] = List() diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index e7ba0c793d..371618ad79 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) } } @@ -427,7 +424,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/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index 0004311647..4ae8b0d5ac 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -84,9 +84,9 @@ trait Trees extends api.Trees { self: SymbolTable => def withPosition(flag: Long, position: Position) = copy() setPositions positions + (flag -> position) - override def hasModifier(mod: Modifier.Value) = + override def hasModifier(mod: Modifier) = hasFlag(flagOfModifier(mod)) - override def allModifiers: Set[Modifier.Value] = + override def modifiers: Set[Modifier] = Modifier.values filter hasModifier override def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = Modifiers(flags, privateWithin, f(annotations)) setPositions positions @@ -97,7 +97,7 @@ trait Trees extends api.Trees { self: SymbolTable => def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List()) def Modifiers(flags: Long): Modifiers = Modifiers(flags, tpnme.EMPTY) - def Modifiers(mods: Set[Modifier.Value], + def Modifiers(mods: Set[Modifier], privateWithin: Name, annotations: List[Tree]): Modifiers = { val flagSet = mods map flagOfModifier @@ -246,15 +246,6 @@ trait Trees extends api.Trees { self: SymbolTable => def Bind(sym: Symbol, body: Tree): Bind = Bind(sym.name, body) setSymbol sym - - /** Factory method for object creation `new tpt(args_1)...(args_n)` - * A `New(t, as)` is expanded to: `(new t).<init>(as)` - */ - def New(tpt: Tree, argss: List[List[Tree]]): Tree = { - assert(!argss.isEmpty) - val superRef: Tree = Select(New(tpt), nme.CONSTRUCTOR) - (superRef /: argss) (Apply) - } /** 0-1 argument list new, based on a symbol. */ def New(sym: Symbol, args: Tree*): Tree = diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 823bd16d2c..c283f0259b 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -263,6 +263,7 @@ trait Types extends api.Types { self: SymbolTable => def declarations = decls def typeArguments = typeArgs def erasedType = transformedType(this) + def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to) } /** The base class for all types */ diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala index 4808326902..028a660a35 100644 --- a/src/compiler/scala/reflect/runtime/Mirror.scala +++ b/src/compiler/scala/reflect/runtime/Mirror.scala @@ -12,28 +12,28 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe import definitions._ - def classWithName(name: String): Symbol = { + def symbolForName(name: String): Symbol = { val clazz = javaClass(name, defaultReflectiveClassLoader()) classToScala(clazz) } - def getCompanionObject(clazz: Symbol): AnyRef = { + def companionInstance(clazz: Symbol): AnyRef = { val singleton = ReflectionUtils.singletonInstance(clazz.fullName, defaultReflectiveClassLoader()) singleton } - def getClass(obj: AnyRef): Symbol = classToScala(obj.getClass) - def getType(obj: AnyRef): Type = typeToScala(obj.getClass) + def symbolOfInstance(obj: Any): Symbol = classToScala(obj.getClass) + def typeOfInstance(obj: Any): Type = typeToScala(obj.getClass) // to do add getClass/getType for instances of primitive types, probably like this: // def getClass[T <: AnyVal : Manifest](x: T): Symbol = manifest[T].getClass - def getValue(receiver: AnyRef, field: Symbol): Any = { + def getValueOfField(receiver: AnyRef, field: Symbol): Any = { fieldToJava(field).get(receiver) } - def setValue(receiver: AnyRef, field: Symbol, value: Any): Unit = { + def setValueOfField(receiver: AnyRef, field: Symbol, value: Any): Unit = { fieldToJava(field).set(receiver, value) } - def invoke(receiver: AnyRef, meth: Symbol, args: Any*): Any = { + def invoke(receiver: AnyRef, meth: Symbol)(args: Any*): Any = { if (meth.owner == ArrayClass) { meth.name match { case nme.length => return Array.getLength(receiver) diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index 70a3061fc7..b12d84b34f 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/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala index fc4177e956..275c85f332 100644 --- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala +++ b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala @@ -2,7 +2,6 @@ package scala.reflect package runtime trait TreeBuildUtil extends Universe with api.TreeBuildUtil { - def staticClass(fullname: String): Symbol = definitions.getRequiredClass(fullname) def staticModule(fullname: String): Symbol = definitions.getRequiredModule(fullname) def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType @@ -39,7 +38,7 @@ trait TreeBuildUtil extends Universe with api.TreeBuildUtil { selectIn(owner.info, idx) } - def freeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value) + def newFreeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value) def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers = Modifiers(flags, privateWithin, annotations) 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) } |