diff options
author | Martin Odersky <odersky@gmail.com> | 2010-02-01 15:10:26 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2010-02-01 15:10:26 +0000 |
commit | e75346d68d46f188dbcd7d76707d9c6f778f7803 (patch) | |
tree | 947527c04304b55e9c9767c1152e31760e494146 | |
parent | bdf37de86a3eeeecafe84e22a91b8aa23866d075 (diff) | |
download | scala-e75346d68d46f188dbcd7d76707d9c6f778f7803.tar.gz scala-e75346d68d46f188dbcd7d76707d9c6f778f7803.tar.bz2 scala-e75346d68d46f188dbcd7d76707d9c6f778f7803.zip |
lifted out core compiler data structures into r...
lifted out core compiler data structures into reflect.generic package.
Made Unpickler work on generic data.
57 files changed, 3081 insertions, 1479 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 9c7fc42f00..9b77890486 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -127,7 +127,6 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable // ------------------ Reporting ------------------------------------- - import util.NoPosition def error(msg: String) = reporter.error(NoPosition, msg) def warning(msg: String) = reporter.warning(NoPosition, msg) def inform(msg: String) = reporter.info(NoPosition, msg, true) @@ -928,7 +927,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable def getFile(clazz: Symbol, suffix: String): File = { val outdirname = settings.outputDirs.outputDirFor(clazz.sourceFile) var outdir = new File(if (outdirname.path == "") "." else outdirname.path) - val filename = clazz.fullNameString('.') + val filename = clazz.fullName var start = 0 var end = filename.indexOf('.', start) while (end >= start) { diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 7f2bcf99c5..104e00a03d 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -192,7 +192,7 @@ abstract class TreeGen mkTypeApply(value, tpe, (if (any) Any_asInstanceOf else Object_asInstanceOf)) def mkClassOf(tp: Type): Tree = - Literal(Constant(tp)) setType Predef_classOfType(tp) + Literal(Constant(tp)) setType ClassType(tp) def mkCheckInit(tree: Tree): Tree = { val tpe = diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index aa0e484578..2e543a0960 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -98,7 +98,7 @@ abstract class TreeInfo { def mayBeVarGetter(sym: Symbol) = sym.info match { case PolyType(List(), _) => sym.owner.isClass && !sym.isStable - case _: ImplicitMethodType => sym.owner.isClass && !sym.isStable + case mt: MethodType => mt.isImplicit && sym.owner.isClass && !sym.isStable case _ => false } diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index c0b2fb41be..fd5a5b391e 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -12,14 +12,13 @@ import java.io.{ OutputStream, PrintWriter, StringWriter, Writer } import symtab.Flags._ import symtab.SymbolTable -abstract class TreePrinters { - val trees: SymbolTable - import trees._ +trait TreePrinters { trees: SymbolTable => + import treeInfo.{ IsTrue, IsFalse } final val showOuterTests = false - class TreePrinter(out: PrintWriter) { + class TreePrinter(out: PrintWriter) extends trees.AbsTreePrinter(out) { protected var indentMargin = 0 protected val indentStep = 2 protected var indentString = " " // 40 @@ -32,7 +31,7 @@ abstract class TreePrinters { protected def doPrintPositions = settings.Xprintpos.value def printPosition(tree: Tree) = if (doPrintPositions) print(tree.pos.show) - def println { + def println() { out.println() while (indentMargin > indentString.length()) indentString += indentString @@ -49,8 +48,8 @@ abstract class TreePrinters { } def printColumn(ts: List[Tree], start: String, sep: String, end: String) { - print(start); indent; println - printSeq(ts){print}{print(sep); println}; undent; println; print(end) + print(start); indent; println() + printSeq(ts){print}{print(sep); println()}; undent; println(); print(end) } def printRow(ts: List[Tree], start: String, sep: String, end: String) { @@ -138,7 +137,7 @@ abstract class TreePrinters { annots foreach (annot => print("@"+annot+" ")) if (annots.nonEmpty) - println + println() } def print(str: String) { out.print(str) } @@ -221,7 +220,7 @@ abstract class TreePrinters { } case DocDef(comment, definition) => - print(comment.raw); println; print(definition) + print(comment.raw); println(); print(definition) case Template(parents, self, body) => val currentOwner1 = currentOwner @@ -287,10 +286,10 @@ abstract class TreePrinters { print(lhs); print(" = "); print(rhs) case If(cond, thenp, elsep) => - print("if ("); print(cond); print(")"); indent; println + print("if ("); print(cond); print(")"); indent; println() print(thenp); undent if (!elsep.isEmpty) { - println; print("else"); indent; println; print(elsep); undent + println(); print("else"); indent; println(); print(elsep); undent } case Return(expr) => @@ -383,9 +382,6 @@ abstract class TreePrinters { case SelectFromArray(qualifier, name, _) => print(qualifier); print(".<arr>"); print(symName(tree, name)) - case tree: StubTree => - print(tree.toString) - case tree => print("<unknown tree of class "+tree.getClass+">") } @@ -399,7 +395,7 @@ abstract class TreePrinters { printRaw( if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) { tree match { - case ClassDef(_, _, _, impl @ Template(ps, trees.emptyValDef, body)) + case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body)) if (tree.symbol.thisSym != tree.symbol) => ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body)) case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl) @@ -415,15 +411,14 @@ abstract class TreePrinters { def print(unit: CompilationUnit) { print("// Scala source: " + unit.source + LINE_SEPARATOR) if (unit.body ne null) { - print(unit.body); println + print(unit.body); println() } else { print("<null>") } - println; flush + println(); flush } } - /** A tree printer which is stingier about vertical whitespace and unnecessary * punctuation than the standard one. */ @@ -517,7 +512,7 @@ abstract class TreePrinters { // If thenp or elsep has only one statement, it doesn't need more than one line. case If(cond, thenp, elsep) => def ifIndented(x: Tree) = { - indent ; println ; printRaw(x) ; undent + indent ; println() ; printRaw(x) ; undent } val List(thenStmts, elseStmts) = List(thenp, elsep) map allStatements @@ -531,12 +526,12 @@ abstract class TreePrinters { if (elseStmts.nonEmpty) { print("else") - indent ; println + indent ; println() elseStmts match { case List(x) => printRaw(x) case _ => printRaw(elsep) } - undent ; println + undent ; println() } case _ => s() } @@ -648,16 +643,22 @@ abstract class TreePrinters { printer.flush() buffer.toString } - def asString(t: Tree): String = asStringInternal(t, create) - def asCompactString(t: Tree): String = asStringInternal(t, createCompact) - - def create(writer: PrintWriter): TreePrinter = new TreePrinter(writer) - def create(stream: OutputStream): TreePrinter = create(new PrintWriter(stream)) - def create(): TreePrinter = create(new PrintWriter(ConsoleWriter)) - - def createCompact(writer: PrintWriter): CompactTreePrinter = new CompactTreePrinter(writer) - def createCompact(stream: OutputStream): CompactTreePrinter = createCompact(new PrintWriter(stream)) - def createCompact(): CompactTreePrinter = createCompact(new PrintWriter(ConsoleWriter)) + def asString(t: Tree): String = asStringInternal(t, newStandardTreePrinter) + def asCompactString(t: Tree): String = asStringInternal(t, newCompactTreePrinter) + + def newStandardTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer) + def newStandardTreePrinter(stream: OutputStream): TreePrinter = newStandardTreePrinter(new PrintWriter(stream)) + def newStandardTreePrinter(): TreePrinter = newStandardTreePrinter(new PrintWriter(ConsoleWriter)) + + def newCompactTreePrinter(writer: PrintWriter): CompactTreePrinter = new CompactTreePrinter(writer) + def newCompactTreePrinter(stream: OutputStream): CompactTreePrinter = newCompactTreePrinter(new PrintWriter(stream)) + def newCompactTreePrinter(): CompactTreePrinter = newCompactTreePrinter(new PrintWriter(ConsoleWriter)) + + def newTreePrinter(writer: PrintWriter): TreePrinter = + if (settings.Ycompacttrees.value) newCompactTreePrinter(writer) + else newStandardTreePrinter(writer) + def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream)) + def newTreePrinter(): TreePrinter = newTreePrinter(new PrintWriter(ConsoleWriter)) /** A writer that writes to the current Console and * is sensitive to replacement of the Console's diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 21f2919535..4f2cd8d01f 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -7,20 +7,12 @@ package scala.tools.nsc package ast -import java.io.{PrintWriter, StringWriter} - import scala.collection.mutable.ListBuffer -import scala.tools.nsc.symtab.{Flags, SymbolTable} +import scala.tools.nsc.symtab.SymbolTable import scala.tools.nsc.symtab.Flags._ -import scala.tools.nsc.util.{FreshNameCreator, HashSet, Position, NoPosition, SourceFile} - - -trait Trees { - self: SymbolTable => - - //statistics +import scala.tools.nsc.util.{FreshNameCreator, HashSet, SourceFile} - var nodeCount = 0 +trait Trees extends reflect.generic.Trees { self: SymbolTable => trait CompilationUnitTrait { var body: Tree @@ -32,13 +24,7 @@ trait Trees { // sub-components -------------------------------------------------- - object treePrinters extends { - val trees: Trees.this.type = Trees.this - } with TreePrinters - - lazy val treePrinter = - if (settings.Ycompacttrees.value) treePrinters.createCompact() - else treePrinters.create() + lazy val treePrinter = newTreePrinter() object treeInfo extends { val trees: Trees.this.type = Trees.this @@ -46,131 +32,39 @@ trait Trees { val treeCopy = new LazyTreeCopier() - // modifiers -------------------------------------------------------- - - /** @param privateWithin the qualifier for a private (a type name) - * or nme.EMPTY.toTypeName, if none is given. - * @param annotations the annotations for the definition. - * <strong>Note:</strong> the typechecker drops these annotations, - * use the AnnotationInfo's (Symbol.annotations) in later phases. - */ - case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree], positions: Map[Long, Position]) { - def isCovariant = hasFlag(COVARIANT ) // marked with `+' - def isContravariant = hasFlag(CONTRAVARIANT) // marked with `-' - def isPrivate = hasFlag(PRIVATE ) - def isProtected = hasFlag(PROTECTED) - def isVariable = hasFlag(MUTABLE ) - def isArgument = hasFlag(PARAM ) - def isAccessor = hasFlag(ACCESSOR ) - def isOverride = hasFlag(OVERRIDE ) - def isAbstract = hasFlag(ABSTRACT ) - def isDeferred = hasFlag(DEFERRED ) - def isCase = hasFlag(CASE ) - def isLazy = hasFlag(LAZY ) - def isSealed = hasFlag(SEALED ) - def isFinal = hasFlag(FINAL ) - def isTrait = hasFlag(TRAIT | notDEFERRED) // (part of DEVIRTUALIZE) - def isImplicit = hasFlag(IMPLICIT ) - def isPublic = !isPrivate && !isProtected - def hasFlag(flag: Long) = (flag & flags) != 0L - def & (flag: Long): Modifiers = { - val flags1 = flags & flag - if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations, positions) - } - def &~ (flag: Long): Modifiers = { - val flags1 = flags & (~flag) - if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations, positions) - } - def | (flag: Long): Modifiers = { - val flags1 = flags | flag - if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations, positions) - } - def withAnnotations(annots: List[Tree]) = - if (annots.isEmpty) this - else Modifiers(flags, privateWithin, annotations ::: annots, positions) - def withPosition(flag: Long, position: Position) = - Modifiers(flags, privateWithin, annotations, positions + (flag -> position)) - } - - def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List(), new Map.EmptyMap) - def Modifiers(flags: Long): Modifiers = Modifiers(flags, nme.EMPTY.toTypeName) - - val NoMods = Modifiers(0) - - // @M helper method for asserts that check consistency in kinding - //def kindingIrrelevant(tp: Type) = (tp eq null) || phase.name == "erasure" || phase.erasedTypes - - abstract class Tree extends Product { - if (util.Statistics.enabled) { - util.Statistics.nodeByType(getClass) += 1 - } - - val id = nodeCount -// assert(id != 1223) - nodeCount += 1 - - private var rawpos: Position = NoPosition + implicit def treeWrapper(tree: Tree): TreeOps = new TreeOps(tree) - def pos = rawpos + class TreeOps(tree: Tree) { - private[this] var rawtpe: Type = _ - - def tpe = rawtpe - def tpe_=(t: Type) = rawtpe = t - - def setPos(pos: Position): this.type = { - rawpos = pos -/* - for (c <- this.children) - if (c.pos.isOpaqueRange && !pos.includes(c.pos)) { - assert(false, "non-enclosing positions in "+this) - } -*/ - this - } - - /** Set tpe to give `tp` and return this. - */ - def setType(tp: Type): this.type = { - /*assert(kindingIrrelevant(tp) || !kindStar || !tp.isHigherKinded, - tp+" should not be higher-kinded"); */ - tpe = tp - this + def isTerm: Boolean = tree match { + case _: TermTree => true + case Bind(name, _) => name.isTermName + case Select(_, name) => name.isTermName + case Ident(name) => name.isTermName + case Annotated(_, arg) => arg.isTerm + case DocDef(_, defn) => defn.isTerm + case _ => false } - /** Like `setType`, but if this is a previously empty TypeTree - * that fact is remembered so that resetType will snap back. - */ - def defineType(tp: Type): this.type = setType(tp) - - /** Reset type to `null`, with special handling of TypeTrees and the EmptyType - */ - def resetType() { tpe = null } - - def symbol: Symbol = null - def symbol_=(sym: Symbol) { - throw new Error("symbol_= inapplicable for " + this) + def isType: Boolean = tree match { + case _: TypTree => true + case Bind(name, _) => name.isTypeName + case Select(_, name) => name.isTypeName + case Ident(name) => name.isTypeName + case Annotated(_, arg) => arg.isType + case DocDef(_, defn) => defn.isType + case _ => false } - def setSymbol(sym: Symbol): this.type = { symbol = sym; this } - def hasSymbol = false - def isDef = false - def isTerm = false - def isType = false - def isEmpty = false - - def isErroneous = (tpe ne null) && tpe.isErroneous + def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous /** Apply `f' to each subtree */ - def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) } + def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(tree) } /** Find all subtrees matching predicate `p' */ def filter(f: Tree => Boolean): List[Tree] = { val ft = new FilterTreeTraverser(f) - ft.traverse(this) + ft.traverse(tree) ft.hits.toList } @@ -179,63 +73,20 @@ trait Trees { */ def find(p: Tree => Boolean): Option[Tree] = { val ft = new FindTreeTraverser(p) - ft.traverse(this) + ft.traverse(tree) ft.result } /** Is there part of this tree which satisfies predicate `p'? */ def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty - /** The direct child trees of this tree - * EmptyTrees are always omitted. Lists are collapsed. - */ - def children: List[Tree] = { - def subtrees(x: Any): List[Tree] = x match { - case EmptyTree => List() - case t: Tree => List(t) - case xs: List[_] => xs flatMap subtrees - case _ => List() - } - productIterator.toList flatMap subtrees - } - - override def toString(): String = - if (settings.Ycompacttrees.value) treePrinters.asCompactString(this) - else treePrinters.asString(this) - - override def hashCode(): Int = super.hashCode() - - override def equals(that: Any): Boolean = that match { - case t: Tree => this eq t - case _ => false - } - def hashCodeStructure: Int = { - var hc = getClass.hashCode - def f(what : Any) : Unit = what match { - case what : Tree => hc += what.hashCodeStructure - case what : Iterable[_] => what.foreach(f) - case what : Product => g(what) - case null => - case what => hc += what.hashCode - } - def g(what: Product) { - hc += what.productArity - var i = 0 - while (i < what.productArity) { - f(what.productElement(i)) - i += 1 - } - } - g(this) - hc - } def equalsStructure(that : Tree) = equalsStructure0(that){case (t0,t1) => false} def equalsStructure0(that: Tree)(f : (Tree,Tree) => Boolean): Boolean = { - if (this == that) return true - if (this.getClass != that.getClass) return false - val this0 = this.asInstanceOf[Product] + if (tree == that) return true + if (tree.getClass != that.getClass) return false + val tree0 = tree.asInstanceOf[Product] val that0 = that.asInstanceOf[Product] - assert(this0.productArity == that0.productArity) + assert(tree0.productArity == that0.productArity) def equals0(thiz: Any, that: Any): Boolean = thiz match { case thiz: Tree => f(thiz,that.asInstanceOf[Tree]) || thiz.equalsStructure0(that.asInstanceOf[Tree])(f) @@ -250,130 +101,26 @@ trait Trees { case thiz => thiz == that } - val results = for (i <- 0.until(this0.productArity).toList) yield - equals0(this0.productElement(i), that0.productElement(i)) + val results = for (i <- 0.until(tree0.productArity).toList) yield + equals0(tree0.productElement(i), that0.productElement(i)) val b = results.foldLeft(true)((x,y) => x && y) - if (b) (this,that) match { - case (this0 : TypeTree, that0 : TypeTree) if this0.original != null && that0.original != null => - this0.original.equalsStructure0(that0.original)(f) + if (b) (tree,that) match { + case (tree0 : TypeTree, that0 : TypeTree) if tree0.original != null && that0.original != null => + tree0.original.equalsStructure0(that0.original)(f) case _ => true } else false } - /** Make a copy of this tree, keeping all attributes, - * except that all positions are focussed (so nothing - * in this tree will be found when searching by position). - */ - def duplicate: this.type = - (duplicator transform this).asInstanceOf[this.type] - - def shallowDuplicate: this.type = - ((new ShallowDuplicator(this)) transform this).asInstanceOf[this.type] - - def copyAttrs(tree: Tree): this.type = { - rawpos = tree.rawpos - tpe = tree.tpe - if (hasSymbol) symbol = tree.symbol - this - } - } - - trait SymTree extends Tree { - override def hasSymbol = true - override var symbol: Symbol = NoSymbol - } - - trait RefTree extends SymTree { - def name: Name - } - - abstract class DefTree extends SymTree { - def name: Name - override def isDef = true - } - - trait TermTree extends Tree { - override def isTerm = true - } - - /** A tree for a type. Note that not all type trees implement - * this trait; in particular, Ident's are an exception. */ - trait TypTree extends Tree { - override def isType = true - } - -// ----- auxiliary objects and methods ------------------------------ - - private lazy val duplicator = new Transformer { - override val treeCopy = new StrictTreeCopier - override def transform(t: Tree) = { - val t1 = super.transform(t) - if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus - t1 - } - } - - private class ShallowDuplicator(orig: Tree) extends Transformer { - override val treeCopy = new StrictTreeCopier - override def transform(tree: Tree) = - if (tree eq orig) - super.transform(tree) - else - tree + def shallowDuplicate: Tree = + (new ShallowDuplicator(tree)) transform tree } -// def nextPhase = if (phase.id > globalPhase.id) phase else phase.next; + private[scala] override def duplicateTree(tree: Tree): Tree = duplicator transform tree -// ----- tree node alternatives -------------------------------------- +// ---- values and creators --------------------------------------- - /** The empty tree */ - case object EmptyTree extends TermTree { - super.tpe_=(NoType) - override def tpe_=(t: Type) = - if (t != NoType) throw new Error("tpe_=("+t+") inapplicable for <empty>") - override def resetType() {} - override def isEmpty = true - } - - abstract class MemberDef extends DefTree { - def mods: Modifiers - def keyword: String = this match { - case TypeDef(_, _, _, _) => "type" - case ClassDef(mods, _, _, _) => if (mods.isTrait) "trait" else "class" - case DefDef(_, _, _, _, _, _) => "def" - case ModuleDef(_, _, _) => "object" - case PackageDef(_, _) => "package" - case ValDef(mods, _, _, _) => if (mods.isVariable) "var" else "val" - case _ => "" - } - final def hasFlag(mask: Long): Boolean = (mods.flags & mask) != 0L - } - - /** Package clause - */ - case class PackageDef(pid: RefTree, stats: List[Tree]) - extends MemberDef { - def name = pid.name - def mods = NoMods - } - -/* disabled, as this is now dangerous - def PackageDef(sym: Symbol, stats: List[Tree]): PackageDef = - PackageDef(Ident(sym.name), stats) setSymbol sym -*/ - - abstract class ImplDef extends MemberDef { - def impl: Template - } - - /** Class definition */ - case class ClassDef(mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) - extends ImplDef - - /** - * @param sym the class symbol - * @param impl ... - * @return ... + /** @param sym the class symbol + * @return the implementation template */ def ClassDef(sym: Symbol, impl: Template): ClassDef = atPos(sym.pos) { @@ -393,7 +140,6 @@ trait Trees { * @param argss the supercall arguments * @param body the template statements without primary constructor * and value parameter fields. - * @return ... */ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = ClassDef(sym, @@ -401,45 +147,15 @@ trait Trees { if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym), constrMods, vparamss, argss, body, superPos)) - /** Singleton object definition - * - * @param mods - * @param name - * @param impl - */ - case class ModuleDef(mods: Modifiers, name: Name, impl: Template) - extends ImplDef - /** * @param sym the class symbol - * @param impl ... - * @return ... + * @param impl the implementation template */ def ModuleDef(sym: Symbol, impl: Template): ModuleDef = atPos(sym.pos) { ModuleDef(Modifiers(sym.flags), sym.name, impl) setSymbol sym } - abstract class ValOrDefDef extends MemberDef { - def tpt: Tree - def rhs: Tree - } - - /** Value definition - * - * @param mods - * @param name - * @param tpt - * @param rhs - */ - case class ValDef(mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) - extends ValOrDefDef { - assert(tpt.isType, tpt) - //assert(kindingIrrelevant(tpt.tpe) || !tpt.tpe.isHigherKinded, tpt.tpe) //@M a value definition should never be typed with a higher-kinded type (values must be classified by types with kind *) - //tpt.kindStar=true //@M turn on consistency checking in Tree - assert(rhs.isTerm, rhs) - } - def ValDef(sym: Symbol, rhs: Tree): ValDef = atPos(sym.pos) { ValDef(Modifiers(sym.flags), sym.name, @@ -449,30 +165,12 @@ trait Trees { def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree) - object emptyValDef - extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) { + object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) { override def isEmpty = true super.setPos(NoPosition) override def setPos(pos: Position) = { assert(false); this } } - /** Method definition - * - * @param mods - * @param name - * @param tparams - * @param vparamss - * @param tpt - * @param rhs - */ - case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], - vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) - extends ValOrDefDef { - assert(tpt.isType, tpt) - //assert(kindingIrrelevant(tpt.tpe) || !tpt.tpe.isHigherKinded, tpt.tpe) //@M a method definition should never be typed with a higher-kinded type (values must be classified by types with kind *) - //tpt.kindStar=true //@M turn on consistency checking in Tree - assert(rhs.isTerm, rhs) - } def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = atPos(sym.pos) { @@ -498,10 +196,6 @@ trait Trees { DefDef(sym, rhs(sym.info.paramss)) } - /** Abstract type, type parameter, or type alias */ - case class TypeDef(mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) - extends MemberDef - /** A TypeDef node which defines given `sym' with given tight hand side `rhs'. */ def TypeDef(sym: Symbol, rhs: Tree): TypeDef = atPos(sym.pos) { @@ -512,91 +206,11 @@ trait Trees { def TypeDef(sym: Symbol): TypeDef = TypeDef(sym, TypeBoundsTree(TypeTree(sym.info.bounds.lo), TypeTree(sym.info.bounds.hi))) - /** <p> - * Labelled expression - the symbols in the array (must be Idents!) - * are those the label takes as argument - * </p> - * <p> - * The symbol that is given to the labeldef should have a MethodType - * (as if it were a nested function) - * </p> - * <p> - * Jumps are apply nodes attributed with label symbol, the arguments - * will get assigned to the idents. - * </p> - * <p> - * Note: on 2005-06-09 Martin, Iuli, Burak agreed to have forward - * jumps within a Block. - * </p> - */ - case class LabelDef(name: Name, params: List[Ident], rhs: Tree) - extends DefTree with TermTree { - assert(rhs.isTerm) - } - - /** - * @param sym the class symbol - * @param params ... - * @param rhs ... - * @return ... - */ def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = atPos(sym.pos) { LabelDef(sym.name, params map Ident, rhs) setSymbol sym } - /** Import selector - * - * Representation of an imported name its optional rename and their optional positions - * - * @param name the imported name - * @param namePos its position or -1 if undefined - * @param rename the name the import is renamed to (== name if no renaming) - * @param renamePos the position of the rename or -1 if undefined - */ - case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) - - /** Import clause - * - * @param expr - * @param selectors - */ - case class Import(expr: Tree, selectors: List[ImportSelector]) - extends SymTree - // The symbol of an Import is an import symbol @see Symbol.newImport - // It's used primarily as a marker to check that the import has been typechecked. - - /** Documented definition, eliminated by analyzer */ - case class DocDef(comment: DocComment, definition: Tree) - extends Tree { - override def symbol: Symbol = definition.symbol - override def symbol_=(sym: Symbol) { definition.symbol = sym } - // sean: seems to be important to the IDE - override def isDef = definition.isDef - override def isTerm = definition.isTerm - override def isType = definition.isType - } - - /** Instantiation template of a class or trait - * - * @param parents - * @param body - */ - case class Template(parents: List[Tree], self: ValDef, body: List[Tree]) - extends SymTree { - // the symbol of a template is a local dummy. @see Symbol.newLocalDummy - // the owner of the local dummy is the enclosing trait or class. - // the local dummy is itself the owner of any local blocks - // For example: - // - // class C { - // def foo // owner is C - // { - // def bar // owner is local dummy - // } - // System.err.println("TEMPLATE: " + parents) - } - /** Generates a template with constructor corresponding to * * constrmods (vparams1_) ... (vparams_n) preSuper { presupers } @@ -667,119 +281,15 @@ trait Trees { Template(parents, self, gvdefs ::: vparamss2.flatten ::: constrs ::: etdefs ::: rest) } - /** Block of expressions (semicolon separated expressions) */ - case class Block(stats: List[Tree], expr: Tree) - extends TermTree - - /** Case clause in a pattern match, eliminated by TransMatch - * (except for occurences in switch statements) - */ - case class CaseDef(pat: Tree, guard: Tree, body: Tree) - extends Tree - /** casedef shorthand */ def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body) - /** Alternatives of patterns, eliminated by TransMatch, except for - * occurences in encoded Switch stmt (=remaining Match(CaseDef(...)) - */ - case class Alternative(trees: List[Tree]) - extends TermTree - - /** Repetition of pattern, eliminated by TransMatch */ - case class Star(elem: Tree) - extends TermTree - - /** Bind of a variable to a rhs pattern, eliminated by TransMatch - * - * @param name - * @param body - */ - case class Bind(name: Name, body: Tree) - extends DefTree { - override def isTerm = name.isTermName - override def isType = name.isTypeName - } - def Bind(sym: Symbol, body: Tree): Bind = Bind(sym.name, body) setSymbol sym - case class UnApply(fun: Tree, args: List[Tree]) - extends TermTree - /** Array of expressions, needs to be translated in backend, - */ - case class ArrayValue(elemtpt: Tree, elems: List[Tree]) - extends TermTree - - /** Anonymous function, eliminated by analyzer */ - case class Function(vparams: List[ValDef], body: Tree) - extends TermTree with SymTree - // The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME - // It is the owner of the function's parameters. - - /** Assignment */ - case class Assign(lhs: Tree, rhs: Tree) - extends TermTree - - /** Either an assignment or a named argument. Only appears in argument lists, - * eliminated by typecheck (doTypedApply) - */ - case class AssignOrNamedArg(lhs: Tree, rhs: Tree) - extends TermTree - - /** Conditional expression */ - case class If(cond: Tree, thenp: Tree, elsep: Tree) - extends TermTree - - /** <p> - * Pattern matching expression (before <code>TransMatch</code>) - * Switch statements (after TransMatch) - * </p> - * <p> - * After <code>TransMatch</code>, cases will satisfy the following - * constraints: - * </p> - * <ul> - * <li>all guards are EmptyTree,</li> - * <li>all patterns will be either <code>Literal(Constant(x:Int))</code> - * or <code>Alternative(lit|...|lit)</code></li> - * <li>except for an "otherwise" branch, which has pattern - * <code>Ident(nme.WILDCARD)</code></li> - * </ul> - */ - case class Match(selector: Tree, cases: List[CaseDef]) - extends TermTree - - /** Return expression */ - case class Return(expr: Tree) - extends TermTree with SymTree - // The symbol of a Return node is the enclosing method. - - case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) - extends TermTree - - /** Throw expression */ - case class Throw(expr: Tree) - extends TermTree - - /** Object instantiation - * One should always use factory method below to build a user level new. - * - * @param tpt a class type - */ - case class New(tpt: Tree) - extends TermTree { - assert(tpt.isType) - } - - /** Factory method for object creation <code><new tpt(args_1)...(args_n)></code>. - * A New(t, as) is expanded to: - * (new t).<init>(as) - * - * @param tpt ... - * @param argss ... - * @return ... + /** 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) @@ -787,279 +297,56 @@ trait Trees { (superRef /: argss) (Apply) } - /** Type annotation, eliminated by explicit outer */ - case class Typed(expr: Tree, tpt: Tree) - extends TermTree - - // Martin to Sean: Should GenericApply/TypeApply/Apply not be SymTree's? After all, - // ApplyDynamic is a SymTree. - abstract class GenericApply extends TermTree { - val fun: Tree - val args: List[Tree] - } - - /** Type application */ - case class TypeApply(fun: Tree, args: List[Tree]) - extends GenericApply { - override def symbol: Symbol = fun.symbol - override def symbol_=(sym: Symbol) { fun.symbol = sym } - } - - /** Value application */ - case class Apply(fun: Tree, args: List[Tree]) - extends GenericApply { - override def symbol: Symbol = fun.symbol - override def symbol_=(sym: Symbol) { fun.symbol = sym } - } - - /** Dynamic value application. - * In a dynamic application q.f(as) - * - q is stored in qual - * - as is stored in args - * - f is stored as the node's symbol field. - */ - case class ApplyDynamic(qual: Tree, args: List[Tree]) - extends TermTree with SymTree - // The symbol of an ApplyDynamic is the function symbol of `qual', or NoSymbol, if there is none. - - /** Super reference */ - case class Super(qual: Name, mix: Name) - extends TermTree with SymTree - // The symbol of a Super is the class _from_ which the super reference is made. - // For instance in C.super(...), it would be C. - def Super(sym: Symbol, mix: Name): Tree = Super(sym.name, mix) setSymbol sym - /** Self reference */ - case class This(qual: Name) - extends TermTree with SymTree { - // The symbol of a This is the class to which the this refers. - // For instance in C.this, it would be C. - } - def This(sym: Symbol): Tree = This(sym.name) setSymbol sym - /** Designator <qualifier> . <name> */ - case class Select(qualifier: Tree, name: Name) - extends RefTree { - override def isTerm = name.isTermName - override def isType = name.isTypeName - } - def Select(qualifier: Tree, sym: Symbol): Select = Select(qualifier, sym.name) setSymbol sym - /** Identifier <name> */ - case class Ident(name: Name) - extends RefTree { - override def isTerm = name.isTermName - override def isType = name.isTypeName - } - - class BackQuotedIdent(name: Name) extends Ident(name) - def Ident(sym: Symbol): Ident = Ident(sym.name) setSymbol sym - /** Literal */ - case class Literal(value: Constant) - extends TermTree { - assert(value ne null) - } - - def Literal(value: Any): Literal = - Literal(Constant(value)) - /** A synthetic term holding an arbitrary type. Not to be confused with * with TypTree, the trait for trees that are only used for type trees. * TypeTree's are inserted in several places, but most notably in * <code>RefCheck</code>, where the arbitrary type trees are all replaced by * TypeTree's. */ - case class TypeTree() extends TypTree { - override def symbol = if (tpe == null) null else tpe.typeSymbol - + case class TypeTree() extends AbsTypeTree { private var orig: Tree = null - private var wasEmpty: Boolean = false + private[Trees] var wasEmpty: Boolean = false def original: Tree = orig - def setOriginal(tree: Tree): this.type = { orig = tree; setPos(tree.pos); this } override def defineType(tp: Type): this.type = { wasEmpty = isEmpty setType(tp) } - - /** Reset type to null, unless type original was empty and then - * got its type via a defineType - */ - override def resetType() { - if (wasEmpty) tpe = null - } - - override def isEmpty = (tpe eq null) || tpe == NoType - } - - def TypeTree(tp: Type): TypeTree = TypeTree() setType tp - // def TypeTree(tp: Type, tree : Tree): TypeTree = TypeTree(tree) setType tp - - /** A tree that has an annotation attached to it. Only used for annotated types and - * annotation ascriptions, annotations on definitions are stored in the Modifiers. - * Eliminated by typechecker (typedAnnotated), the annotations are then stored in - * an AnnotatedType. - */ - case class Annotated(annot: Tree, arg: Tree) extends Tree { - override def isType = arg.isType - override def isTerm = arg.isTerm } - /** Singleton type, eliminated by RefCheck */ - case class SingletonTypeTree(ref: Tree) - extends TypTree + object TypeTree extends TypeTreeExtractor - /** Type selection <qualifier> # <name>, eliminated by RefCheck */ - case class SelectFromTypeTree(qualifier: Tree, name: Name) - extends TypTree with RefTree - - /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */ - case class CompoundTypeTree(templ: Template) - extends TypTree + def TypeTree(tp: Type): TypeTree = TypeTree() setType tp - /** Applied type <tpt> [ <args> ], eliminated by RefCheck */ - case class AppliedTypeTree(tpt: Tree, args: List[Tree]) - extends TypTree { - override def symbol: Symbol = tpt.symbol - override def symbol_=(sym: Symbol) { tpt.symbol = sym } + /** Documented definition, eliminated by analyzer */ + case class DocDef(comment: DocComment, definition: Tree) + extends Tree { + override def symbol: Symbol = definition.symbol + override def symbol_=(sym: Symbol) { definition.symbol = sym } + // sean: seems to be important to the IDE + override def isDef = definition.isDef } - case class TypeBoundsTree(lo: Tree, hi: Tree) - extends TypTree - - case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree]) - extends TypTree + /** Either an assignment or a named argument. Only appears in argument lists, + * eliminated by typecheck (doTypedApply) + */ + case class AssignOrNamedArg(lhs: Tree, rhs: Tree) + extends TermTree case class Parens(args: List[Tree]) extends Tree // only used during parsing - /** Array selection <qualifier> . <name> only used during erasure */ - case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type) - extends TermTree with RefTree - - trait StubTree extends Tree { - def underlying : AnyRef - override def equalsStructure0(that: Tree)(f : (Tree,Tree) => Boolean): Boolean = this eq that - } - -/* A standard pattern match - case EmptyTree => - case PackageDef(pid, stats) => - // package pid { stats } - case ClassDef(mods, name, tparams, impl) => - // mods class name [tparams] impl where impl = extends parents { defs } - case ModuleDef(mods, name, impl) => (eliminated by refcheck) - // mods object name impl where impl = extends parents { defs } - case ValDef(mods, name, tpt, rhs) => - // mods val name: tpt = rhs - // note missing type information is expressed by tpt = TypeTree() - case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - // mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs - // note missing type information is expressed by tpt = TypeTree() - case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure) - // mods type name[tparams] = rhs - // mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree, - and DEFERRED is set in mods - case LabelDef(name, params, rhs) => - // used for tailcalls and like - // while/do are desugared to label defs as follows: - // while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ()) - // do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ()) - case Import(expr, selectors) => (eliminated by typecheck) - // import expr.{selectors} - // Selectors are a list of pairs of names (from, to). - // The last (and maybe only name) may be a nme.WILDCARD - // for instance - // import qual.{x, y => z, _} would be represented as - // Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null))) - case DocDef(comment, definition) => (eliminated by typecheck) - // /** comment */ definition - case Template(parents, self, body) => - // extends parents { self => body } - // if self is missing it is represented as emptyValDef - case Block(stats, expr) => - // { stats; expr } - case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter) - // case pat if guard => body - case Alternative(trees) => (eliminated by transmatch/explicitouter) - // pat1 | ... | patn - case Star(elem) => (eliminated by transmatch/explicitouter) - // pat* - case Bind(name, body) => (eliminated by transmatch/explicitouter) - // name @ pat - case UnApply(fun: Tree, args) (introduced by typer, eliminated by transmatch/explicitouter) - // used for unapply's - case ArrayValue(elemtpt, trees) => (introduced by uncurry) - // used to pass arguments to vararg arguments - // for instance, printf("%s%d", foo, 42) is translated to after uncurry to: - // Apply( - // Ident("printf"), - // Literal("%s%d"), - // ArrayValue(<Any>, List(Ident("foo"), Literal(42)))) - case Function(vparams, body) => (eliminated by lambdaLift) - // vparams => body where vparams:List[ValDef] - case Assign(lhs, rhs) => - // lhs = rhs - case AssignOrNamedArg(lhs, rhs) => (eliminated by typecheck) - // lhs = rhs - case If(cond, thenp, elsep) => - // if (cond) thenp else elsep - case Match(selector, cases) => - // selector match { cases } - case Return(expr) => - // return expr - case Try(block, catches, finalizer) => - // try block catch { catches } finally finalizer where catches: List[CaseDef] - case Throw(expr) => - // throw expr - case New(tpt) => - // new tpt always in the context: (new tpt).<init>[targs](args) - case Typed(expr, tpt) => (eliminated by erasure) - // expr: tpt - case TypeApply(fun, args) => - // fun[args] - case Apply(fun, args) => - // fun(args) - // for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args) - case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup) - // fun(args) - case Super(qual, mix) => - // qual.super[mix] if qual and/or mix is empty, ther are nme.EMPTY.toTypeName - case This(qual) => - // qual.this - case Select(qualifier, selector) => - // qualifier.selector - case Ident(name) => - // name - // note: type checker converts idents that refer to enclosing fields or methods - // to selects; name ==> this.name - case Literal(value) => - // value - case TypeTree() => (introduced by refcheck) - // a type that's not written out, but given in the tpe attribute - case Annotated(annot, arg) => (eliminated by typer) - // arg @annot for types, arg: @annot for exprs - case SingletonTypeTree(ref) => (eliminated by uncurry) - // ref.type - case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry) - // qualifier # selector, a path-dependent type p.T is expressed as p.type # T - case CompoundTypeTree(templ: Template) => (eliminated by uncurry) - // parent1 with ... with parentN { refinement } - case AppliedTypeTree(tpt, args) => (eliminated by uncurry) - // tpt[args] - case TypeBoundsTree(lo, hi) => (eliminated by uncurry) - // >: lo <: hi - case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry) - // tpt forSome { whereClauses } - -*/ +// ----- auxiliary objects and methods ------------------------------ abstract class TreeCopier { def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef @@ -1543,10 +830,6 @@ trait Trees { treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses)) case SelectFromArray(qualifier, selector, erasure) => treeCopy.SelectFromArray(tree, transform(qualifier), selector, erasure) - case tree : StubTree => - tree.symbol = NoSymbol - tree.tpe = null - tree } def transformTrees(trees: List[Tree]): List[Tree] = @@ -1694,7 +977,6 @@ trait Trees { traverse(qualifier) case Parens(ts) => traverseTrees(ts) - case tree : StubTree => } def traverseTrees(trees: List[Tree]) { @@ -1718,6 +1000,24 @@ trait Trees { } } + private lazy val duplicator = new Transformer { + override val treeCopy = new StrictTreeCopier + override def transform(t: Tree) = { + val t1 = super.transform(t) + if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus + t1 + } + } + + private class ShallowDuplicator(orig: Tree) extends Transformer { + override val treeCopy = new StrictTreeCopier + override def transform(tree: Tree) = + if (tree eq orig) + super.transform(tree) + else + tree + } + class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { override def transform(tree: Tree): Tree = tree match { case Ident(_) => @@ -1853,7 +1153,14 @@ trait Trees { case _ => if (tree.hasSymbol && isLocal(tree.symbol)) tree.symbol = NoSymbol } - tree.resetType() + tree match { + case tpt: TypeTree => + if (tpt.wasEmpty) tree.tpe = null + case EmptyTree => + ; + case _ => + tree.tpe = null + } super.traverse(tree) } } @@ -1875,14 +1182,5 @@ trait Trees { super.traverse(tree) } } - - /* hook to memoize trees in IDE */ - trait TreeKind { - def isType : Boolean - def isTerm : Boolean - def isDef : Boolean - def hasSymbol : Boolean - def isTop : Boolean - } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index f7f6fea2c2..53fc6542b2 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -10,7 +10,7 @@ package ast.parser import scala.collection.mutable import mutable.{ Buffer, ArrayBuffer, ListBuffer, HashMap } import scala.util.control.ControlException -import scala.tools.nsc.util.{Position,NoPosition,SourceFile,CharArrayReader} +import scala.tools.nsc.util.{SourceFile,CharArrayReader} import scala.xml.{ Text, TextBuffer } import scala.xml.Utility.{ isNameStart, isNameChar, isSpace } import util.Chars.{ SU, LF } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 35048c7a7d..58552e18e5 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -10,7 +10,7 @@ package scala.tools.nsc package ast.parser import scala.collection.mutable.ListBuffer -import scala.tools.nsc.util.{Position, OffsetPosition, NoPosition, BatchSourceFile} +import scala.tools.nsc.util.{OffsetPosition, BatchSourceFile} import symtab.Flags import Tokens._ diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index 57b705094c..9c34739a15 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -10,7 +10,6 @@ package ast.parser import collection.mutable.Map import xml.{ EntityRef, Text } import xml.XML.{ xmlns } -import util.Position import symtab.Flags.MUTABLE /** This class builds instance of <code>Tree</code> that represent XML. diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index bb87a9248e..a23b8339a3 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -9,7 +9,6 @@ package ast.parser import symtab.Flags._ import scala.collection.mutable.ListBuffer -import scala.tools.nsc.util.Position /** Methods for building trees, used in the parser. All the trees * returned by this class must be untyped. diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index a91abac94a..ec9c371534 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -15,7 +15,6 @@ import scala.collection.immutable.{Set, ListSet} import scala.collection.mutable.{Map, HashMap, HashSet} import scala.tools.nsc.io.AbstractFile import scala.tools.nsc.symtab._ -import scala.tools.nsc.util.{Position, NoPosition} import scala.tools.nsc.symtab.classfile.ClassfileConstants._ import ch.epfl.lamp.fjbg._ @@ -77,7 +76,7 @@ abstract class GenJVM extends SubComponent { val MIN_SWITCH_DENSITY = 0.7 val INNER_CLASSES_FLAGS = (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT) - val StringBuilderClass = definitions.getClass2("scala.StringBuilder", "scala.collection.mutable.StringBuilder").fullNameString + val StringBuilderClass = definitions.getClass2("scala.StringBuilder", "scala.collection.mutable.StringBuilder").fullName val BoxesRunTime = "scala.runtime.BoxesRunTime" val StringBuilderType = new JObjectType(StringBuilderClass) @@ -210,7 +209,7 @@ abstract class GenJVM extends SubComponent { dumpMirrorClass(c.symbol, c.cunit.source.toString); else log("No mirror class for module with linked class: " + - c.symbol.fullNameString) + c.symbol.fullName) } } else { @@ -437,7 +436,7 @@ abstract class GenJVM extends SubComponent { && !(sym.isMethod && sym.hasFlag(Flags.LIFTED)) && !(sym.ownerChain exists (_.isImplClass))) { // @M don't generate java generics sigs for (members of) implementation classes, as they are monomorphic (TODO: ok?) val memberTpe = atPhase(currentRun.erasurePhase)(owner.thisType.memberInfo(sym)) - // println("addGenericSignature sym: " + sym.fullNameString + " : " + memberTpe + " sym.info: " + sym.info) + // println("addGenericSignature sym: " + sym.fullName + " : " + memberTpe + " sym.info: " + sym.info) // println("addGenericSignature: "+ (sym.ownerChain map (x => (x.name, x.isImplClass)))) erasure.javaSig(sym, memberTpe) match { case Some(sig) => @@ -543,7 +542,7 @@ abstract class GenJVM extends SubComponent { def genField(f: IField) { if (settings.debug.value) - log("Adding field: " + f.symbol.fullNameString); + log("Adding field: " + f.symbol.fullName); var attributes = 0 f.symbol.annotations foreach { a => a match { @@ -568,7 +567,7 @@ abstract class GenJVM extends SubComponent { def genMethod(m: IMethod) { if (m.isStaticCtor) return - log("Generating method " + m.symbol.fullNameString) + log("Generating method " + m.symbol.fullName) method = m endPC.clear computeLocalVarsIndex(m) @@ -1142,11 +1141,11 @@ abstract class GenJVM extends SubComponent { case BOX(kind) => val boxedType = definitions.boxedClass(kind.toType.typeSymbol) val mtype = new JMethodType(javaType(boxedType), Array(javaType(kind))) - jcode.emitINVOKESTATIC(BoxesRunTime, "boxTo" + boxedType.cleanNameString, mtype) + jcode.emitINVOKESTATIC(BoxesRunTime, "boxTo" + boxedType.decodedName, mtype) case UNBOX(kind) => val mtype = new JMethodType(javaType(kind), Array(JObjectType.JAVA_LANG_OBJECT)) - jcode.emitINVOKESTATIC(BoxesRunTime, "unboxTo" + kind.toType.typeSymbol.cleanNameString, mtype) + jcode.emitINVOKESTATIC(BoxesRunTime, "unboxTo" + kind.toType.typeSymbol.decodedName, mtype) case NEW(REFERENCE(cls)) => val className = javaName(cls) @@ -1715,7 +1714,7 @@ abstract class GenJVM extends SubComponent { } (if (sym.isClass || (sym.isModule && !sym.isMethod)) - sym.fullNameString('/') + sym.fullName('/') else sym.simpleName.toString.trim()) + suffix } @@ -1775,7 +1774,7 @@ abstract class GenJVM extends SubComponent { /** Calls to methods in 'sym' need invokeinterface? */ def needsInterfaceCall(sym: Symbol): Boolean = { - log("checking for interface call: " + sym.fullNameString) + log("checking for interface call: " + sym.fullName) // the following call to 'info' may cause certain symbols to fail loading because we're // too late in the compilation chain (aliases to overloaded symbols will not be properly // resolved, see scala.Range, method super$++ that fails in UnPickler at LazyTypeRefAndAlias.complete diff --git a/src/compiler/scala/tools/nsc/dependencies/Changes.scala b/src/compiler/scala/tools/nsc/dependencies/Changes.scala index c5669d6214..ddab003752 100644 --- a/src/compiler/scala/tools/nsc/dependencies/Changes.scala +++ b/src/compiler/scala/tools/nsc/dependencies/Changes.scala @@ -42,7 +42,7 @@ abstract class Changes { case class ParentChanged(e: Entity) extends Change private def sameSymbol(sym1: Symbol, sym2: Symbol): Boolean = - sym1.fullNameString == sym2.fullNameString + sym1.fullName == sym2.fullName private def sameFlags(sym1: Symbol, sym2: Symbol): Boolean = sym1.flags == sym2.flags private def sameAnnotations(sym1: Symbol, sym2: Symbol): Boolean = @@ -197,6 +197,6 @@ abstract class Changes { def parentChangeSet(sym: Symbol): Change = ParentChanged(toEntity(sym)) private def toEntity(sym: Symbol): Entity = - if (sym.isClass) Class(sym.fullNameString) - else Definition(sym.fullNameString) + if (sym.isClass) Class(sym.fullName) + else Definition(sym.fullName) } diff --git a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala index 2aaab33dc3..761b9dac3c 100644 --- a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala +++ b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala @@ -160,7 +160,7 @@ trait DependencyAnalysis extends SubComponent with Files { && ((tree.symbol.sourceFile eq null) || (tree.symbol.sourceFile.path != file.path)) && (!tree.symbol.isClassConstructor)) { - updateReferences(tree.symbol.fullNameString) + updateReferences(tree.symbol.fullName) atPhase(currentRun.uncurryPhase.prev) { checkType(tree.symbol.tpe) } @@ -204,18 +204,18 @@ trait DependencyAnalysis extends SubComponent with Files { case t: TypeRef => if (t.sym.isAliasType) { - updateReferences(t.typeSymbolDirect.fullNameString) + updateReferences(t.typeSymbolDirect.fullName) checkType(t.typeSymbolDirect.info) } - updateReferences(t.typeSymbol.fullNameString) + updateReferences(t.typeSymbol.fullName) for (tp <- t.args) checkType(tp) case t: PolyType => checkType(t.resultType) - updateReferences(t.typeSymbol.fullNameString) + updateReferences(t.typeSymbol.fullName) case t => - updateReferences(t.typeSymbol.fullNameString) + updateReferences(t.typeSymbol.fullName) } def updateReferences(s: String): Unit = diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala index e51919b7c2..5f2c18e597 100644 --- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala +++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala @@ -13,9 +13,7 @@ import java.io.{ StringWriter, PrintWriter } /** Ancillary bits of ParallelMatching which are better off * out of the way. */ -trait MatchSupport extends ast.TreeDSL -{ - self: ParallelMatching => +trait MatchSupport extends ast.TreeDSL { self: ParallelMatching => import global.{ typer => _, _ } import CODE._ @@ -102,7 +100,7 @@ trait MatchSupport extends ast.TreeDSL pp(x match { case s: String => return clean(s) - case x: Tree => treePrinters asCompactString x + case x: Tree => asCompactString(x) case xs: List[_] => pplist(xs map pp) case x: Tuple2[_,_] => "%s -> %s".format(pp(x._1), pp(x._2)) case x => x.toString diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala index 61ca97ea24..8464ecc46e 100644 --- a/src/compiler/scala/tools/nsc/matching/Matrix.scala +++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala @@ -7,7 +7,6 @@ package scala.tools.nsc package matching import transform.ExplicitOuter -import util.Position import symtab.Flags trait Matrix extends MatrixAdditions { diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala index 3158f8a6cf..adc3e5df2c 100644 --- a/src/compiler/scala/tools/nsc/matching/Patterns.scala +++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala @@ -7,7 +7,6 @@ package scala.tools.nsc package matching import symtab.Flags -import util.NoPosition import scala.util.NameTransformer.decode import PartialFunction._ @@ -131,7 +130,7 @@ trait Patterns extends ast.TreeDSL { case class ConstructorPattern(tree: Apply) extends ApplyPattern with NamePattern { require(fn.isType && this.isCaseClass) def name = tpe.typeSymbol.name - def cleanName = tpe.typeSymbol.cleanNameString + def cleanName = tpe.typeSymbol.decodedName def hasPrefix = tpe.prefix.prefixString != "" def prefixedName = if (hasPrefix) "%s.%s".format(tpe.prefix.prefixString, cleanName) diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala index b4a15733f9..c4569b0441 100644 --- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala +++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala @@ -7,8 +7,6 @@ package scala.tools.nsc package matching -import util.Position -import ast.{ TreePrinters, Trees } import symtab.SymbolTable import transform.ExplicitOuter import java.io.{ StringWriter, PrintWriter } diff --git a/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala b/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala index 93839057d8..f0265c5e5d 100644 --- a/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala +++ b/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala @@ -11,8 +11,7 @@ import scala.tools.nsc.transform.Reifiers import util._ /** AnnotationInfo and its helpers */ -trait AnnotationInfos { - self: SymbolTable => +trait AnnotationInfos extends reflect.generic.AnnotationInfos { self: SymbolTable => /** Arguments to classfile annotations (which are written to * bytecode as java annotations) are either: @@ -33,12 +32,16 @@ trait AnnotationInfos { override def toString = const.escapedStringValue } + object LiteralAnnotArg extends LiteralAnnotArgExtractor + /** Represents an array of classfile annotation arguments */ case class ArrayAnnotArg(args: Array[ClassfileAnnotArg]) extends ClassfileAnnotArg { override def toString = args.mkString("[", ", ", "]") } + object ArrayAnnotArg extends ArrayAnnotArgExtractor + /** Represents a nested classfile annotation */ case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg { @@ -47,6 +50,8 @@ trait AnnotationInfos { override def toString = annInfo.toString } + object NestedAnnotArg extends NestedAnnotArgExtractor + class AnnotationInfoBase /** <p> @@ -106,6 +111,11 @@ trait AnnotationInfos { } } + object AnnotationInfo extends AnnotationInfoExtractor + + lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] = + reflect.ClassManifest.classType(classOf[ClassfileAnnotArg]) + /** Symbol annotations parsed in Namer (typeCompleter of * definitions) have to be lazy (#1782) */ diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index a1ef4a07ae..026b6c3e25 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -11,10 +11,10 @@ import scala.collection.mutable.{HashMap, HashSet} import scala.tools.nsc.util.{Position, NoPosition} import Flags._ -trait Definitions { +trait Definitions extends reflect.generic.StandardDefinitions { self: SymbolTable => - object definitions { + object definitions extends AbsDefinitions { def isDefinitionsInitialized = isInitialized // Working around bug #2133 @@ -30,7 +30,7 @@ trait Definitions { val rp=NoSymbol.newValue(NoPosition, nme.ROOTPKG) .setFlag(FINAL | MODULE | PACKAGE | JAVA) .setInfo(PolyType(List(), RootClass.tpe)) - RootClass.setSourceModule(rp) + RootClass.sourceModule = rp rp } lazy val RootClass: ModuleClassSymbol = NoSymbol.newModuleClass(NoPosition, nme.ROOT.toTypeName) @@ -140,10 +140,6 @@ trait Definitions { // fundamental modules lazy val PredefModule: Symbol = getModule("scala.Predef") def Predef_classOf = getMember(PredefModule, nme.classOf) - def Predef_classOfType(classType: Type): Type = - if (!ClassClass.unsafeTypeParams.isEmpty && !phase.erasedTypes) - appliedType(ClassClass.tpe, List(classType)) - else ClassClass.tpe def Predef_error = getMember(PredefModule, nme.error) def Predef_identity = getMember(PredefModule, nme.identity) def Predef_conforms = getMember(PredefModule, nme.conforms) @@ -349,6 +345,10 @@ trait Definitions { def seqType(arg: Type) = typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(arg)) def arrayType(arg: Type) = typeRef(ArrayClass.typeConstructor.prefix, ArrayClass, List(arg)) + def ClassType(arg: Type) = + if (ClassClass.unsafeTypeParams.isEmpty || phase.erasedTypes) ClassClass.tpe + else appliedType(ClassClass.tpe, List(arg)) + // // .NET backend // @@ -598,7 +598,7 @@ trait Definitions { val abbrvTag = new HashMap[Symbol, Char] val numericWidth = new HashMap[Symbol, Int] - private def newValueClass(name: Name, tag: Char, width: Int): Symbol = { + private[symtab] def newValueClass(name: Name, tag: Char, width: Int): Symbol = { val boxedName = sn.Boxed(name) val clazz = newClass(ScalaPackageClass, name, anyvalparam) setFlag (ABSTRACT | FINAL) @@ -737,6 +737,7 @@ trait Definitions { case _ => false } + // todo: reconcile with javaSignature!!! def signature(tp: Type): String = { def erasure(tp: Type): Type = tp match { case st: SubType => erasure(st.supertype) @@ -744,7 +745,7 @@ trait Definitions { case _ => tp } def flatNameString(sym: Symbol, separator: Char): String = - if (sym.owner.isPackageClass) sym.fullNameString('.') + (if (sym.isModuleClass) "$" else "") + if (sym.owner.isPackageClass) sym.fullName('.') + (if (sym.isModuleClass) "$" else "") else flatNameString(sym.owner, separator) + "$" + sym.simpleName; def signature1(etp: Type): String = { if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head)) diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala index 9901027db6..0b1315a18b 100644 --- a/src/compiler/scala/tools/nsc/symtab/Flags.scala +++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala @@ -7,83 +7,7 @@ package scala.tools.nsc package symtab -object Flags { - - // modifiers - final val IMPLICIT = 0x00000200 - final val FINAL = 0x00000020 - final val PRIVATE = 0x00000004 - final val PROTECTED = 0x00000001 - - final val SEALED = 0x00000400 - final val OVERRIDE = 0x00000002 - final val CASE = 0x00000800 - final val ABSTRACT = 0x00000008 // abstract class, or used in conjunction - // with abstract override. - // Note difference to DEFERRED! - - final val DEFERRED = 0x00000010 // was `abstract' for members | trait is virtual - final val METHOD = 0x00000040 // a method - final val MODULE = 0x00000100 // symbol is module or class implementing a module - final val INTERFACE = 0x00000080 // symbol is an interface (i.e. a trait which defines only abstract methods) - - - final val MUTABLE = 0x00001000 // symbol is a mutable variable. - final val PARAM = 0x00002000 // symbol is a (value or type) parameter to a method - final val PACKAGE = 0x00004000 // symbol is a java package - // available: 0x00008000 - - final val COVARIANT = 0x00010000 // symbol is a covariant type variable - final val CAPTURED = 0x00010000 // variable is accessed from nested function. - // Set by LambdaLift - final val BYNAMEPARAM = 0x00010000 // parameter is by name - final val CONTRAVARIANT = 0x00020000 // symbol is a contravariant type variable - final val LABEL = 0x00020000 // method symbol is a label. Set by TailCall - final val INCONSTRUCTOR = 0x00020000 // class symbol is defined in this/superclass - // constructor. - final val ABSOVERRIDE = 0x00040000 // combination of abstract & override - final val LOCAL = 0x00080000 // symbol is local to current class (i.e. private[this] or protected[this] - // pre: PRIVATE or PROTECTED are also set - final val JAVA = 0x00100000 // symbol was defined by a Java class - final val SYNTHETIC = 0x00200000 // symbol is compiler-generated - final val STABLE = 0x00400000 // functions that are assumed to be stable - // (typically, access methods for valdefs) - // or classes that do not contain abstract types. - final val STATIC = 0x00800000 // static field, method or class - - final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor) - final val TRAIT = 0x02000000 // symbol is a trait - final val DEFAULTPARAM = 0x02000000 // the parameter has a default value - final val BRIDGE = 0x04000000 // function is a bridge method. Set by Erasure - final val ACCESSOR = 0x08000000 // a value or variable accessor (getter or setter) - - final val SUPERACCESSOR = 0x10000000 // a super accessor - final val PARAMACCESSOR = 0x20000000 // for value definitions: is an access method - // for a final val parameter - // for parameters: is a val parameter - final val MODULEVAR = 0x40000000 // for variables: is the variable caching a module value - final val SYNTHETICMETH = 0x40000000 // for methods: synthetic method, but without SYNTHETIC flag - final val MONOMORPHIC = 0x40000000 // for type symbols: does not have type parameters - final val LAZY = 0x80000000L // symbol is a lazy val. can't have MUTABLE unless transformed by typer - - final val IS_ERROR = 0x100000000L // symbol is an error symbol - final val OVERLOADED = 0x200000000L // symbol is overloaded - final val LIFTED = 0x400000000L // class has been lifted out to package level - // local value has been lifted out to class level - // todo: make LIFTED = latePRIVATE? - final val MIXEDIN = 0x800000000L // term member has been mixed in - final val EXISTENTIAL = 0x800000000L // type is an existential parameter or skolem - - final val EXPANDEDNAME = 0x1000000000L // name has been expanded with class suffix - final val IMPLCLASS = 0x2000000000L // symbol is an implementation class - final val PRESUPER = 0x2000000000L // value is evaluated before super call - final val TRANS_FLAG = 0x4000000000L // transient flag guaranteed to be reset - // after each phase. - - final val LOCKED = 0x8000000000L // temporary flag to catch cyclic dependencies - final val SPECIALIZED = 0x10000000000L// symbol is a generated specialized member - final val DEFAULTINIT = 0x20000000000L// symbol is a generated specialized member - final val VBRIDGE = 0x40000000000L// symbol is a varargs bridge +object Flags extends reflect.generic.Flags { final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1. final val LateFlags = 0x00FE000000000000L // flags that override flags in 0x1FC. @@ -108,118 +32,6 @@ object Flags { final val notOVERRIDE = (OVERRIDE: Long) << AntiShift final val notMETHOD = (METHOD: Long) << AntiShift - // The flags from 0x001 to 0x800 are different in the raw flags - // and in the pickled format. - - private final val IMPLICIT_PKL = 0x00000001 - private final val FINAL_PKL = 0x00000002 - private final val PRIVATE_PKL = 0x00000004 - private final val PROTECTED_PKL = 0x00000008 - - private final val SEALED_PKL = 0x00000010 - private final val OVERRIDE_PKL = 0x00000020 - private final val CASE_PKL = 0x00000040 - private final val ABSTRACT_PKL = 0x00000080 - - private final val DEFERRED_PKL = 0x00000100 - private final val METHOD_PKL = 0x00000200 - private final val MODULE_PKL = 0x00000400 - private final val INTERFACE_PKL = 0x00000800 - - private final val PKL_MASK = 0x00000FFF - - - private val r2p = { - def rawFlagsToPickledAux(flags:Int) = { - var pflags=0 - if ((flags & IMPLICIT )!=0) pflags|=IMPLICIT_PKL - if ((flags & FINAL )!=0) pflags|=FINAL_PKL - if ((flags & PRIVATE )!=0) pflags|=PRIVATE_PKL - if ((flags & PROTECTED)!=0) pflags|=PROTECTED_PKL - if ((flags & SEALED )!=0) pflags|=SEALED_PKL - if ((flags & OVERRIDE )!=0) pflags|=OVERRIDE_PKL - if ((flags & CASE )!=0) pflags|=CASE_PKL - if ((flags & ABSTRACT )!=0) pflags|=ABSTRACT_PKL - if ((flags & DEFERRED )!=0) pflags|=DEFERRED_PKL - if ((flags & METHOD )!=0) pflags|=METHOD_PKL - if ((flags & MODULE )!=0) pflags|=MODULE_PKL - if ((flags & INTERFACE)!=0) pflags|=INTERFACE_PKL - pflags - } - val v=new Array[Int](PKL_MASK+1) - var i=0 - while (i<=PKL_MASK) { - v(i)=rawFlagsToPickledAux(i) - i+=1 - } - v - } - - private val p2r = { - def pickledToRawFlagsAux(pflags:Int) = { - var flags=0 - if ((pflags & IMPLICIT_PKL )!=0) flags|=IMPLICIT - if ((pflags & FINAL_PKL )!=0) flags|=FINAL - if ((pflags & PRIVATE_PKL )!=0) flags|=PRIVATE - if ((pflags & PROTECTED_PKL)!=0) flags|=PROTECTED - if ((pflags & SEALED_PKL )!=0) flags|=SEALED - if ((pflags & OVERRIDE_PKL )!=0) flags|=OVERRIDE - if ((pflags & CASE_PKL )!=0) flags|=CASE - if ((pflags & ABSTRACT_PKL )!=0) flags|=ABSTRACT - if ((pflags & DEFERRED_PKL )!=0) flags|=DEFERRED - if ((pflags & METHOD_PKL )!=0) flags|=METHOD - if ((pflags & MODULE_PKL )!=0) flags|=MODULE - if ((pflags & INTERFACE_PKL)!=0) flags|=INTERFACE - flags - } - val v=new Array[Int](PKL_MASK+1) - var i=0 - while (i<=PKL_MASK) { - v(i)=pickledToRawFlagsAux(i) - i+=1 - } - v - } - - def rawFlagsToPickled(flags:Long):Long = - (flags & ~PKL_MASK) | r2p(flags.toInt & PKL_MASK) - - def pickledToRawFlags(pflags:Long):Long = - (pflags & ~PKL_MASK) | p2r(pflags.toInt & PKL_MASK) - - // List of the raw flags, in pickled order - private val pickledListOrder = { - def findBit(m:Long):Int = { - var mask=m - var i=0 - while (i <= 62) { - if ((mask&1) == 1L) return i - mask >>= 1 - i += 1 - } - throw new FatalError("Internal error: mask is zero") - } - val v=new Array[Long](63) - v(findBit(IMPLICIT_PKL ))=IMPLICIT - v(findBit(FINAL_PKL ))=FINAL - v(findBit(PRIVATE_PKL ))=PRIVATE - v(findBit(PROTECTED_PKL))=PROTECTED - v(findBit(SEALED_PKL ))=SEALED - v(findBit(OVERRIDE_PKL ))=OVERRIDE - v(findBit(CASE_PKL ))=CASE - v(findBit(ABSTRACT_PKL ))=ABSTRACT - v(findBit(DEFERRED_PKL ))=DEFERRED - v(findBit(METHOD_PKL ))=METHOD - v(findBit(MODULE_PKL ))=MODULE - v(findBit(INTERFACE_PKL))=INTERFACE - var i=findBit(PKL_MASK+1) - while (i <= 62) { - v(i)=1L << i - i += 1 - } - v.toList - } - // masks /** This flags can be set when class or module symbol is first created. */ final val TopLevelCreationFlags: Long = @@ -244,7 +56,6 @@ object Flags { final val AccessFlags: Long = PRIVATE | PROTECTED final val VARIANCES = COVARIANT | CONTRAVARIANT final val ConstrFlags: Long = JAVA - final val PickledFlags: Long = 0xFFFFFFFFL /** Module flags inherited by their module-class */ final val ModuleToClassFlags: Long = AccessFlags | MODULE | PACKAGE | CASE | SYNTHETIC | JAVA diff --git a/src/compiler/scala/tools/nsc/symtab/Names.scala b/src/compiler/scala/tools/nsc/symtab/Names.scala index ddadc32202..3b9c1520e5 100644 --- a/src/compiler/scala/tools/nsc/symtab/Names.scala +++ b/src/compiler/scala/tools/nsc/symtab/Names.scala @@ -16,7 +16,7 @@ import java.security.MessageDigest * @author Martin Odersky * @version 1.0, 05/02/2005 */ -class Names { +trait Names extends reflect.generic.Names { // Operations ------------------------------------------------------------- @@ -164,6 +164,9 @@ class Names { def newTypeName(bs: Array[Byte], offset: Int, len: Int): Name = newTermName(bs, offset, len).toTypeName + def mkTermName(name: Name) = name.toTermName + def mkTypeName(name: Name) = name.toTypeName + def nameChars: Array[Char] = chrs implicit def view(s: String): Name = newTermName(s) diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala index e096d3b5e3..215a6217af 100644 --- a/src/compiler/scala/tools/nsc/symtab/Positions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Positions.scala @@ -33,4 +33,7 @@ self: scala.tools.nsc.symtab.SymbolTable => def ensureNonOverlapping(tree: Tree, others: List[Tree]) {} def validatePositions(tree: Tree) {} + + type Position = scala.tools.nsc.util.Position + val NoPosition = scala.tools.nsc.util.NoPosition } diff --git a/src/compiler/scala/tools/nsc/symtab/Scopes.scala b/src/compiler/scala/tools/nsc/symtab/Scopes.scala index dcd9e76b62..a66e5b6cc3 100644 --- a/src/compiler/scala/tools/nsc/symtab/Scopes.scala +++ b/src/compiler/scala/tools/nsc/symtab/Scopes.scala @@ -44,7 +44,7 @@ trait Scopes { e } - class Scope(initElems: ScopeEntry) extends Iterable[Symbol] { + class Scope(initElems: ScopeEntry) extends AbsScope { var elems: ScopeEntry = initElems @@ -275,10 +275,39 @@ trait Scopes { elemsCache } + /** Return the nesting level of this scope, i.e. the number of times this scope + * was nested in another */ + def nestingLevel = nestinglevel + /** Return all symbols as an interator in the order they were entered in this scope. */ def iterator: Iterator[Symbol] = toList.iterator +/* + /** Does this scope contain an entry for `sym`? + */ + def contains(sym: Symbol): Boolean = lookupAll(sym.name) contains sym + + /** A scope that contains all symbols of this scope and that also contains `sym`. + */ + def +(sym: Symbol): Scope = + if (contains(sym)) this + else { + val result = cloneScope + result enter sym + result + } + + /** A scope that contains all symbols of this scope except `sym`. + */ + def -(sym: Symbol): Scope = + if (!contains(sym)) this + else { + val result = cloneScope + result unlink sym + result + } +*/ override def foreach[U](p: Symbol => U): Unit = toList foreach p override def filter(p: Symbol => Boolean): Scope = @@ -287,13 +316,12 @@ trait Scopes { override def mkString(start: String, sep: String, end: String) = toList.map(_.defString).mkString(start, sep, end) - override def toString(): String = mkString("{\n ", ";\n ", "\n}") + override def toString(): String = mkString("Scope{\n ", ";\n ", "\n}") - /** Return the nesting level of this scope, i.e. the number of times this scope - * was nested in another */ - def nestingLevel = nestinglevel } + def newScope: Scope = new Scope + /** The empty scope (immutable). */ object EmptyScope extends Scope { diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index e762448462..94bcbabaf1 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -9,10 +9,9 @@ package symtab import scala.util.NameTransformer -trait StdNames { - self: SymbolTable => +trait StdNames extends reflect.generic.StdNames { self: SymbolTable => - object nme { + object nme extends StandardNames { // Scala keywords; enter them first to minimize scanner.maxKey val ABSTRACTkw = newTermName("abstract") @@ -73,7 +72,6 @@ trait StdNames { val LOCALDUMMY_PREFIX_STRING = "<local " val SUPER_PREFIX_STRING = "super$" - val EXPAND_SEPARATOR_STRING = "$$" val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" val TUPLE_FIELD_PREFIX_STRING = "_" val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$" @@ -88,7 +86,7 @@ trait StdNames { def LOCAL(clazz: Symbol) = newTermName(LOCALDUMMY_PREFIX_STRING + clazz.name+">") def TUPLE_FIELD(index: Int) = newTermName(TUPLE_FIELD_PREFIX_STRING + index) - val LOCAL_SUFFIX = newTermName(" ") + val LOCAL_SUFFIX = newTermName(LOCAL_SUFFIX_STRING) val SETTER_SUFFIX = encode("_=") val IMPL_CLASS_SUFFIX = newTermName("$class") val MODULE_SUFFIX = newTermName("$module") @@ -116,9 +114,13 @@ trait StdNames { chtp == Character.MATH_SYMBOL.toInt || chtp == Character.OTHER_SYMBOL.toInt } + /** The expanded setter name of `name' relative to this class `base` + */ + def expandedSetterName(name: Name, base: Symbol): Name = + expandedName(name, base, separator = TRAIT_SETTER_SEPARATOR_STRING) + /** If `name' is an expandedName name, the original name. * Otherwise `name' itself. - * @see Symbol.expandedName */ def originalName(name: Name): Name = { var i = name.length @@ -183,19 +185,11 @@ trait StdNames { val LOCALCHILD = newTypeName("<local child>") val NOSYMBOL = newTermName("<none>") - val EMPTY = newTermName("") val ANYNAME = newTermName("<anyname>") val WILDCARD = newTermName("_") val WILDCARD_STAR = newTermName("_*") - val ANON_CLASS_NAME = newTermName("$anon") - val ANON_FUN_NAME = newTermName("$anonfun") - val REFINE_CLASS_NAME = newTermName("<refinement>") - val EMPTY_PACKAGE_NAME = newTermName("<empty>") - val IMPORT = newTermName("<import>") val STAR = newTermName("*") - val ROOT = newTermName("<root>") - val ROOTPKG = newTermName("_root_") val REPEATED_PARAM_CLASS_NAME = newTermName("<repeated>") val JAVA_REPEATED_PARAM_CLASS_NAME = newTermName("<repeated...>") val BYNAME_PARAM_CLASS_NAME = newTermName("<byname>") diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 51ef2fc313..23e525d8c8 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -14,7 +14,7 @@ import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute} import scala.collection.mutable.{HashMap, HashSet} import scala.compat.Platform.currentTime import scala.tools.nsc.io.AbstractFile -import scala.tools.nsc.util.{Position, NoPosition, ClassPath, ClassRep, JavaClassPath, MsilClassPath} +import scala.tools.nsc.util.{ClassPath, ClassRep, JavaClassPath, MsilClassPath} import classfile.ClassfileParser import Flags._ @@ -110,7 +110,7 @@ abstract class SymbolLoaders { def enterClassAndModule(root: Symbol, name: String, completer: SymbolLoader) { val owner = if (root.isRoot) definitions.EmptyPackageClass else root val className = newTermName(name) - assert(owner.info.decls.lookup(name) == NoSymbol, owner.fullNameString + "." + name) + assert(owner.info.decls.lookup(name) == NoSymbol, owner.fullName + "." + name) val clazz = owner.newClass(NoPosition, name.toTypeName) val module = owner.newModule(NoPosition, name) clazz setInfo completer diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala index 2a70c55cd6..618c601b8f 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala @@ -6,22 +6,25 @@ package scala.tools.nsc package symtab -import ast.{Trees, DocComments} + +import ast.{Trees, TreePrinters, DocComments} import util._ -abstract class SymbolTable extends Names +abstract class SymbolTable extends reflect.generic.Universe + with Names with Symbols with Types with Scopes with Definitions - with Constants + with reflect.generic.Constants with BaseTypeSeqs with InfoTransformers with StdNames with AnnotationInfos with AnnotationCheckers with Trees + with TreePrinters with Positions with DocComments { diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala b/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala index f2e16b537a..8c111875dd 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala @@ -3,7 +3,6 @@ package symtab trait SymbolWalker { val global : Global - import scala.tools.nsc.util._ import global._ import scala.collection.mutable.LinkedHashSet trait Visitor { @@ -33,8 +32,6 @@ trait SymbolWalker { def fs(l: List[Tree]) = l foreach f def fss(l: List[List[Tree]]) = l foreach fs - if (t.isInstanceOf[StubTree]) return - val sym = (t, t.tpe) match { case (Super(_,_),SuperType(_,supertp)) if validSym(supertp) => supertp.typeSymbol case _ if validSym(t) => t.symbol diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index d6f4ef5672..1ba70a3fcf 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -17,8 +17,7 @@ import Flags._ //todo: get rid of MONOMORPHIC flag -trait Symbols { - self: SymbolTable => +trait Symbols extends reflect.generic.Symbols { self: SymbolTable => import definitions._ private var ids = 0 @@ -51,7 +50,7 @@ trait Symbols { } */ /** The class for all symbols */ - abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name) { + abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name) extends AbsSymbol { var rawowner = initOwner var rawname = initName @@ -124,8 +123,9 @@ trait Symbols { this } - def addAnnotation(annot: AnnotationInfo): this.type = + override def addAnnotation(annot: AnnotationInfo) { setAnnotations(annot :: this.rawannots) + } /** Does this symbol have an annotation of the given class? */ def hasAnnotation(cls: Symbol) = @@ -157,12 +157,16 @@ trait Symbols { * Java protected: PROTECTED flag set, privateWithin == enclosing package * Java public: no flag set, privateWithin == NoSymbol */ - var privateWithin: Symbol = _ + private[this] var _privateWithin: Symbol = _ + def privateWithin = _privateWithin + override def privateWithin_=(sym: Symbol) { _privateWithin = sym } // Creators ------------------------------------------------------------------- final def newValue(pos: Position, name: Name) = new TermSymbol(this, pos, name) + final def newValue(name: Name, pos: Position = NoPosition) = + new TermSymbol(this, pos, name) final def newVariable(pos: Position, name: Name) = newValue(pos, name).setFlag(MUTABLE) final def newValueParameter(pos: Position, name: Name) = @@ -172,6 +176,8 @@ trait Symbols { newValue(pos, nme.LOCAL(this)).setInfo(NoType) final def newMethod(pos: Position, name: Name) = new MethodSymbol(this, pos, name).setFlag(METHOD) + final def newMethod(name: Name, pos: Position = NoPosition) = + new MethodSymbol(this, pos, name).setFlag(METHOD) final def newLabel(pos: Position, name: Name) = newMethod(pos, name).setFlag(LABEL) final def newConstructor(pos: Position) = @@ -179,6 +185,9 @@ trait Symbols { final def newModule(pos: Position, name: Name, clazz: ClassSymbol) = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) .setModuleClass(clazz) + final def newModule(name: Name, clazz: Symbol, pos: Position = NoPosition) = + new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) + .setModuleClass(clazz.asInstanceOf[ClassSymbol]) final def newModule(pos: Position, name: Name) = { val m = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) m.setModuleClass(new ModuleClassSymbol(m)) @@ -234,11 +243,15 @@ trait Symbols { */ final def newAliasType(pos: Position, name: Name) = new TypeSymbol(this, pos, name) + final def newAliasType(name: Name, pos: Position = NoPosition) = + new TypeSymbol(this, pos, name) /** Symbol of an abstract type type T >: ... <: ... */ final def newAbstractType(pos: Position, name: Name) = new TypeSymbol(this, pos, name).setFlag(DEFERRED) + final def newAbstractType(name: Name, pos: Position = NoPosition) = + new TypeSymbol(this, pos, name).setFlag(DEFERRED) /** Symbol of a type parameter */ @@ -291,9 +304,13 @@ trait Symbols { final def newClass(pos: Position, name: Name) = new ClassSymbol(this, pos, name) + final def newClass(name: Name, pos: Position = NoPosition) = + new ClassSymbol(this, pos, name) final def newModuleClass(pos: Position, name: Name) = new ModuleClassSymbol(this, pos, name) + final def newModuleClass(name: Name, pos: Position = NoPosition) = + new ModuleClassSymbol(this, pos, name) final def newAnonymousClass(pos: Position) = newClass(pos, nme.ANON_CLASS_NAME.toTypeName) @@ -362,15 +379,8 @@ trait Symbols { // Tests ---------------------------------------------------------------------- - def isTerm = false //to be overridden - def isType = false //to be overridden - def isClass = false //to be overridden - def isTypeMember = false //to be overridden todo: rename, it's something - // whose definition starts with `type', i.e. a type - // which is not a class. - def isAliasType = false //to be overridden - def isAbstractType = false //to be overridden - def isSkolem = false //to be overridden + /** Is this symbol a type but not a class? */ + def isNonClassType = false /** Term symbols with the exception of static parts of Java classes and packages */ final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)) @@ -388,29 +398,23 @@ trait Symbols { final def isValueParameter = isTerm && hasFlag(PARAM) final def isLocalDummy = isTerm && nme.isLocalDummyName(name) - final def isMethod = isTerm && hasFlag(METHOD) - final def isSourceMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD.toLong // ??? final def isLabel = isMethod && !hasFlag(ACCESSOR) && hasFlag(LABEL) final def isInitializedToDefault = !isType && (getFlag(DEFAULTINIT | ACCESSOR) == (DEFAULTINIT | ACCESSOR)) final def isClassConstructor = isTerm && (name == nme.CONSTRUCTOR) final def isMixinConstructor = isTerm && (name == nme.MIXIN_CONSTRUCTOR) final def isConstructor = isTerm && (name == nme.CONSTRUCTOR) || (name == nme.MIXIN_CONSTRUCTOR) - final def isModule = isTerm && hasFlag(MODULE) final def isStaticModule = isModule && isStatic && !isMethod - final def isPackage = isModule && hasFlag(PACKAGE) final def isThisSym = isTerm && owner.thisSym == this //final def isMonomorphicType = isType && hasFlag(MONOMORPHIC) final def isError = hasFlag(IS_ERROR) final def isErroneous = isError || isInitialized && tpe.isErroneous - final def isTrait = isClass && hasFlag(TRAIT | notDEFERRED) // A virtual class becomes a trait (part of DEVIRTUALIZE) + override final def isTrait: Boolean = isClass && hasFlag(TRAIT | notDEFERRED) // A virtual class becomes a trait (part of DEVIRTUALIZE) final def isTypeParameterOrSkolem = isType && hasFlag(PARAM) final def isTypeSkolem = isSkolem && hasFlag(PARAM) - final def isTypeParameter = isTypeParameterOrSkolem && !isSkolem // a type symbol bound by an existential type, for instance the T in // List[T] forSome { type T } - final def isExistential = isType && hasFlag(EXISTENTIAL) - final def isExistentialSkolem = isSkolem && hasFlag(EXISTENTIAL) - final def isExistentialQuantified = isExistential && !isSkolem + final def isExistentialSkolem = isExistentiallyBound && isSkolem + final def isExistentialQuantified = isExistentiallyBound && !isSkolem // class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR) @@ -418,17 +422,10 @@ trait Symbols { final def isAnonymousClass = isClass && (originalName startsWith nme.ANON_CLASS_NAME) // todo: find out why we can't use containsName here. final def isAnonymousFunction = hasFlag(SYNTHETIC) && (name containsName nme.ANON_FUN_NAME) - final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME.toTypeName; // no lifting for refinement classes - final def isModuleClass = isClass && hasFlag(MODULE) final def isClassOfModule = isModuleClass || isClass && nme.isLocalName(name) - final def isPackageClass = isClass && hasFlag(PACKAGE) final def isPackageObject = isModule && name == nme.PACKAGEkw && owner.isPackageClass final def isPackageObjectClass = isModuleClass && name.toTermName == nme.PACKAGEkw && owner.isPackageClass final def definedInPackage = owner.isPackageClass || owner.isPackageObjectClass - final def isRoot = isPackageClass && name == nme.ROOT.toTypeName - final def isRootPackage = isPackage && name == nme.ROOTPKG - final def isEmptyPackage = isPackage && name == nme.EMPTY_PACKAGE_NAME - final def isEmptyPackageClass = isPackageClass && name == nme.EMPTY_PACKAGE_NAME.toTypeName final def isPredefModule = isModule && name == nme.Predef && owner.isScalaPackageClass // not printed as a prefix final def isScalaPackage = isPackage && name == nme.scala_ && owner.isRoot || // not printed as a prefix isPackageObject && owner.isScalaPackageClass @@ -476,6 +473,8 @@ trait Symbols { name.toString.startsWith(nme.INTERPRETER_LINE_PREFIX) && name.toString.endsWith(nme.INTERPRETER_WRAPPER_SUFFIX) + override def isEffectiveRoot = super.isEffectiveRoot || isInterpreterWrapper + /** Is this symbol an accessor method for outer? */ final def isOuterAccessor = { hasFlag(STABLE | SYNTHETIC) && @@ -495,9 +494,6 @@ trait Symbols { (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) && !(tpe.isVolatile && !hasAnnotation(uncheckedStableClass)) - def isDeferred = - hasFlag(DEFERRED) && !isClass - def isVirtualClass = hasFlag(DEFERRED) && isClass @@ -505,16 +501,6 @@ trait Symbols { hasFlag(DEFERRED) && isTrait /** Is this symbol a public */ - final def isPublic: Boolean = - !hasFlag(PRIVATE | PROTECTED) && privateWithin == NoSymbol - - /** Is this symbol a private local */ - final def isPrivateLocal = - hasFlag(PRIVATE) && hasFlag(LOCAL) - - /** Is this symbol a protected local */ - final def isProtectedLocal = - hasFlag(PROTECTED) && hasFlag(LOCAL) /** Does this symbol denote the primary constructor of its enclosing class? */ final def isPrimaryConstructor = @@ -528,11 +514,6 @@ trait Symbols { final def isCaseApplyOrUnapply = isMethod && hasFlag(CASE) && hasFlag(SYNTHETIC) - /** Is this symbol an implementation class for a mixin? */ - final def isImplClass: Boolean = isClass && hasFlag(IMPLCLASS) - - /** Is thhis symbol early initialized */ - final def isEarly: Boolean = isTerm && hasFlag(PRESUPER) /** Is this symbol a trait which needs an implementation class? */ final def needsImplClass: Boolean = @@ -560,16 +541,9 @@ trait Symbols { final def isStaticOwner: Boolean = isPackageClass || isModuleClass && isStatic - /** Is this symbol final? */ - final def isFinal: Boolean = ( - hasFlag(FINAL) || - isTerm && ( - hasFlag(PRIVATE) || isLocal || owner.isClass && owner.hasFlag(FINAL | MODULE)) - ) - - /** Is this symbol a sealed class? */ - final def isSealed: Boolean = - isClass && (hasFlag(SEALED) || isValueClass(this)) + /** Is this symbol effectively final? I.e, it cannot be overridden */ + final def isEffectivelyFinal: Boolean = isFinal || isTerm && ( + hasFlag(PRIVATE) || isLocal || owner.isClass && owner.hasFlag(FINAL | MODULE)) /** Is this symbol locally defined? I.e. not accessed from outside `this' instance */ final def isLocal: Boolean = owner.isTerm @@ -642,9 +616,6 @@ trait Symbols { isClass && (hasFlag(STABLE) || checkStable()) } - final def isCovariant: Boolean = isType && hasFlag(COVARIANT) - - final def isContravariant: Boolean = isType && hasFlag(CONTRAVARIANT) /** The variance of this symbol as an integer */ final def variance: Int = @@ -655,7 +626,7 @@ trait Symbols { // Flags, owner, and name attributes -------------------------------------------------------------- def owner: Symbol = rawowner - final def owner_=(owner: Symbol) { rawowner = owner } + override final def owner_=(owner: Symbol) { rawowner = owner } def ownerChain: List[Symbol] = this :: owner.ownerChain @@ -696,11 +667,10 @@ trait Symbols { val fs = rawflags & phase.flagMask (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift) } - final def flags_=(fs: Long) = rawflags = fs + override final def flags_=(fs: Long) = rawflags = fs final def setFlag(mask: Long): this.type = { rawflags = rawflags | mask; this } final def resetFlag(mask: Long): this.type = { rawflags = rawflags & ~mask; this } final def getFlag(mask: Long): Long = flags & mask - final def hasFlag(mask: Long): Boolean = (flags & mask) != 0L final def resetFlags { rawflags = rawflags & TopLevelCreationFlags } /** The class or term up to which this symbol is accessible, @@ -735,12 +705,12 @@ trait Symbols { * to generate a type of kind * * for a term symbol, its usual type */ - def tpe: Type = info + override def tpe: Type = info /** Get type info associated with symbol at current phase, after * ensuring that symbol is initialized (i.e. type is completed). */ - def info: Type = try { + override def info: Type = try { var cnt = 0 while (validTo == NoPeriod) { //if (settings.debug.value) System.out.println("completing " + this);//DEBUG @@ -748,9 +718,14 @@ trait Symbols { assert(infos.prev eq null, this.name) val tp = infos.info //if (settings.debug.value) System.out.println("completing " + this.rawname + tp.getClass());//debug - lock { - setInfo(ErrorType) - throw CyclicReference(this, tp) + if ((rawflags & LOCKED) != 0L) { // rolled out once for performance + lock { + setInfo(ErrorType) + throw CyclicReference(this, tp) + } + } else { + rawflags |= LOCKED + activeLocks += 1 } val current = phase try { @@ -774,15 +749,16 @@ trait Symbols { throw ex } - /** Set initial info. */ - def setInfo(info: Type): this.type = { + override def info_=(info: Type) { assert(info ne null) infos = TypeHistory(currentPeriod, info, null) unlock() validTo = if (info.isComplete) currentPeriod else NoPeriod - this } + /** Set initial info. */ + def setInfo(info: Type): this.type = { info_=(info); this } + /** Set new info valid from start of this phase. */ final def updateInfo(info: Type): Symbol = { assert(phaseId(infos.validFrom) <= phase.id) @@ -1078,12 +1054,6 @@ trait Symbols { // Access to related symbols -------------------------------------------------- - /** The next enclosing class */ - def enclClass: Symbol = if (isClass) this else owner.enclClass - - /** The next enclosing method */ - def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod - /** The primary constructor of a class */ def primaryConstructor: Symbol = { var c = info.decl( @@ -1102,10 +1072,6 @@ trait Symbols { /** The type of `this' in a class, or else the type of the symbol itself. */ def typeOfThis = thisSym.tpe - /** Sets the type of `this' in a class */ - def typeOfThis_=(tp: Type): Unit = - throw new Error("typeOfThis cannot be set for " + this) - /** If symbol is a class, the type <code>this.type</code> in this class, * otherwise <code>NoPrefix</code>. * We always have: thisType <:< typeOfThis @@ -1320,11 +1286,6 @@ trait Symbols { result } else this - /** The module corresponding to this module class (note that this - * is not updated when a module is cloned). - */ - def sourceModule: Symbol = NoSymbol - /** The module class corresponding to this module. */ def moduleClass: Symbol = NoSymbol @@ -1400,7 +1361,7 @@ trait Symbols { final def setter(base: Symbol, hasExpandedName: Boolean): Symbol = { var sname = nme.getterToSetter(nme.getterName(name)) - if (hasExpandedName) sname = base.expandedSetterName(sname) + if (hasExpandedName) sname = nme.expandedSetterName(sname, base) base.info.decl(sname) filter (_.hasFlag(ACCESSOR)) } @@ -1410,7 +1371,7 @@ trait Symbols { final def caseModule: Symbol = { var modname = name.toTermName if (privateWithin.isClass && !privateWithin.isModuleClass && !hasFlag(EXPANDEDNAME)) - modname = privateWithin.expandedName(modname) + modname = nme.expandedName(modname, privateWithin) initialize.owner.info.decl(modname).suchThat(_.isModule) } @@ -1448,20 +1409,11 @@ trait Symbols { getter(owner).expandName(base) setter(owner).expandName(base) } - name = base.expandedName(name) + name = nme.expandedName(name, base) if (isType) name = name.toTypeName } } - def expandedSetterName(simpleSetterName: Name): Name = - newTermName(fullNameString('$') + nme.TRAIT_SETTER_SEPARATOR_STRING + simpleSetterName) - - /** The expanded name of `name' relative to this class as base - */ - def expandedName(name: Name): Name = { - newTermName(fullNameString('$') + nme.EXPAND_SEPARATOR_STRING + name) - } - def sourceFile: AbstractFile = (if (isModule) moduleClass else toplevelClass).sourceFile @@ -1475,16 +1427,10 @@ trait Symbols { /** If this is a sealed class, its known direct subclasses. Otherwise Set.empty */ def children: Set[Symbol] = emptySymbolSet - /** Declare given subclass `sym' of this sealed class */ - def addChild(sym: Symbol) { - throw new Error("addChild inapplicable for " + this) - } - - // ToString ------------------------------------------------------------------- /** A tag which (in the ideal case) uniquely identifies class symbols */ - final def tag: Int = fullNameString.hashCode() + final def tag: Int = fullName.hashCode() /** The simple name of this Symbol */ final def simpleName: Name = name @@ -1527,32 +1473,11 @@ trait Symbols { * E.g. $eq => =. * If settings.uniquId adds id. */ - def nameString: String = cleanNameString + idString - - /** A nameString that never adds idString, for use in e.g. GenJVM - * where appending #uniqid breaks the bytecode. - */ - def cleanNameString: String = { - val s = simpleName.decode - if (s endsWith nme.LOCAL_SUFFIX) s.substring(0, s.length - nme.LOCAL_SUFFIX.length) - else s - } + def nameString: String = decodedName + idString - /** String representation of symbol's full name with <code>separator</code> - * between class names. - * Never translates expansions of operators back to operator symbol. - * Never adds id. + /** The name of the symbol before decoding, e.g. `$eq$eq` instead of `==`. */ - final def fullNameString(separator: Char): String = { - var str = - if (isRoot || isRootPackage || this == NoSymbol) this.toString - else if (owner.isRoot || owner.isEmptyPackageClass || owner.isInterpreterWrapper) simpleName.toString - else owner.enclClass.fullNameString(separator) + separator + simpleName - if (str.charAt(str.length - 1) == ' ') str = str.substring(0, str.length - 1) - str - } - - final def fullNameString: String = fullNameString('.') + def encodedName: String = name.toString /** If settings.uniqid is set, the symbol's id, else "" */ final def idString: String = @@ -1804,7 +1729,7 @@ trait Symbols { private var tpePeriod = NoPeriod override def isType = true - override def isTypeMember = true + override def isNonClassType = true override def isAbstractType = isDeferred override def isAliasType = !isDeferred @@ -1851,7 +1776,7 @@ trait Symbols { tyconCache } - override def setInfo(tp: Type): this.type = { + override def info_=(tp: Type) { tpePeriod = NoPeriod tyconCache = null if (tp.isComplete) @@ -1860,8 +1785,7 @@ trait Symbols { case NoType | AnnotatedType(_, _, _) => ; case _ => setFlag(MONOMORPHIC) } - super.setInfo(tp) - this + super.info_=(tp) } override def reset(completer: Type) { @@ -1954,7 +1878,7 @@ trait Symbols { private var thissym: Symbol = this override def isClass: Boolean = true - override def isTypeMember = false + override def isNonClassType = false override def isAbstractType = false override def isAliasType = false @@ -2037,22 +1961,21 @@ trait Symbols { def this(module: TermSymbol) = { this(module.owner, module.pos, module.name.toTypeName) setFlag(module.getFlag(ModuleToClassFlags) | MODULE | FINAL) - setSourceModule(module) + sourceModule = module } override def sourceModule = module lazy val implicitMembers = info.implicitMembers - def setSourceModule(module: Symbol) { this.module = module } + override def sourceModule_=(module: Symbol) { this.module = module } } /** An object repreesenting a missing symbol */ object NoSymbol extends Symbol(null, NoPosition, nme.NOSYMBOL) { setInfo(NoType) privateWithin = this - override def setInfo(info: Type): this.type = { + override def info_=(info: Type) { infos = TypeHistory(1, NoType, null) unlock() validTo = currentPeriod - this } override def defString: String = toString override def locationString: String = "" diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index f1755ed841..6a9f9a334d 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -14,7 +14,6 @@ import util.{HashSet, Position, NoPosition} import util.Statistics._ import Flags._ - /* A standard type pattern match: case ErrorType => // internal: error @@ -60,8 +59,7 @@ import Flags._ case DeBruijnIndex(level, index) */ -trait Types { - self: SymbolTable => +trait Types extends reflect.generic.Types { self: SymbolTable => import definitions._ @@ -236,7 +234,7 @@ trait Types { } /** The base class for all types */ - abstract class Type { + abstract class Type extends AbsType { /** Types for which asSeenFrom always is the identity, no matter what * prefix or owner. @@ -349,6 +347,11 @@ trait Types { def resultType(actuals: List[Type]) = this + /** If this is a TypeRef `clazz`[`T`], return the argument `T` + * otherwise return this type + */ + def remove(clazz: Symbol): Type = this + def resultApprox: Type = ApproximateDeBruijnMap(resultType) /** For a curried method or poly type its non-method result type, @@ -719,17 +722,10 @@ trait Types { typeVarToOriginMap(this) eq this } - /** Is this type completed (i.e. not a lazy type)? - */ - def isComplete: Boolean = true - /** Is this type a varargs parameter? */ def isVarargs: Boolean = typeSymbol == RepeatedParamClass - /** If this is a lazy type, assign a new type to `sym'. */ - def complete(sym: Symbol) {} - /** If this is a symbol loader type, load and assign a new type to * `sym'. */ @@ -899,24 +895,8 @@ trait Types { /** The kind of this type; used for debugging */ def kind: String = "unknown type of class "+getClass() - - override def toString: String = - if (tostringRecursions >= maxTostringRecursions) - "..." - else - try { - tostringRecursions += 1 - safeToString - } finally { - tostringRecursions -= 1 - } - - def safeToString: String = super.toString } - private final val maxTostringRecursions = 50 - private var tostringRecursions = 0 - // Subclasses ------------------------------------------------------------ trait UniqueType { @@ -1020,12 +1000,6 @@ trait Types { override def kind = "NoPrefixType" } - def ThisType(sym: Symbol) = { - if (!phase.erasedTypes) unique(new ThisType(sym) with UniqueType) - else if (sym.isImplClass) sym.typeOfThis - else sym.tpe - } - /** A class for this-types of the form <sym>.this.type */ abstract case class ThisType(sym: Symbol) extends SingletonType { @@ -1039,7 +1013,7 @@ trait Types { if (settings.debug.value) sym.nameString + ".this." else if (sym.isRoot || sym.isEmptyPackageClass || sym.isInterpreterWrapper || sym.isScalaPackageClass) "" else if (sym.isAnonymousClass || sym.isRefinementClass) "this." - else if (sym.isModuleClass) sym.fullNameString + "." + else if (sym.isModuleClass) sym.fullName + "." else sym.nameString + ".this." override def safeToString: String = if (sym.isRoot) "<root>" @@ -1049,6 +1023,13 @@ trait Types { override def kind = "ThisType" } + object ThisType extends ThisTypeExtractor { + def apply(sym: Symbol): Type = + if (!phase.erasedTypes) unique(new ThisType(sym) with UniqueType) + else if (sym.isImplClass) sym.typeOfThis + else sym.tpe + } + case class DeBruijnIndex(level: Int, paramId: Int) extends Type { override def isTrivial = true override def isStable = true @@ -1102,22 +1083,9 @@ trait Types { else pre.prefixString + sym.nameString + "." override def kind = "SingleType" } -/* - object SingleType { - def apply(pre: Type, sym: Symbol): Type = { - if (phase.erasedTypes) - sym.tpe.resultType - else if (sym.isRootPackage) - ThisType(RootClass) - else { - var sym1 = rebind(pre, sym) - val pre1 = removeSuper(pre, sym1) - if (pre1 ne pre) sym1 = rebind(pre1, sym1) - unique(new SingleType(pre1, sym1) with UniqueType) - } - } - } -*/ + + object SingleType extends SingleTypeExtractor + abstract case class SuperType(thistpe: Type, supertpe: Type) extends SingletonType { override val isTrivial: Boolean = thistpe.isTrivial && supertpe.isTrivial override def isNotNull = true; @@ -1132,9 +1100,11 @@ trait Types { override def kind = "SuperType" } - def SuperType(thistp: Type, supertp: Type): Type = - if (phase.erasedTypes) supertp - else unique(new SuperType(thistp, supertp) with UniqueType) + object SuperType extends SuperTypeExtractor { + def apply(thistp: Type, supertp: Type): Type = + if (phase.erasedTypes) supertp + else unique(new SuperType(thistp, supertp) with UniqueType) + } /** A class for the bounds of abstract types and type parameters */ @@ -1151,8 +1121,10 @@ trait Types { override def kind = "TypeBoundsType" } - def TypeBounds(lo: Type, hi: Type): TypeBounds = - unique(new TypeBounds(lo, hi) with UniqueType) + object TypeBounds extends TypeBoundsExtractor { + def apply(lo: Type, hi: Type): TypeBounds = + unique(new TypeBounds(lo, hi) with UniqueType) + } /** A common base class for intersection types and class types */ @@ -1306,13 +1278,13 @@ trait Types { if (isHigherKinded) PolyType( typeParams, - refinementOfClass( - typeSymbol, + RefinedType( parents map { case TypeRef(pre, sym, List()) => TypeRef(pre, sym, dummyArgs) case p => p }, - decls)) + decls, + typeSymbol)) else super.normalize } @@ -1346,6 +1318,11 @@ trait Types { override def kind = "RefinedType" } + object RefinedType extends RefinedTypeExtractor { + def apply(parents: List[Type], decls: Scope, clazz: Symbol) = + new RefinedType(parents, decls) { override def typeSymbol = clazz } + } + /** A class representing a class info */ case class ClassInfoType( @@ -1486,6 +1463,8 @@ trait Types { override def kind = "ClassInfoType" } + object ClassInfoType extends ClassInfoTypeExtractor + class PackageClassInfoType(decls: Scope, clazz: Symbol) extends ClassInfoType(List(), decls, clazz) @@ -1506,14 +1485,16 @@ trait Types { override def kind = "ConstantType" } - def ConstantType(value: Constant) = { - class UniqueConstantType extends ConstantType(value) with UniqueType { - /** Save the type of 'value'. For Java enums, it depends on finding the linked class, - * which might not be found after 'flatten'. */ - private lazy val _tpe: Type = value.tpe - override def underlying: Type = _tpe + object ConstantType extends ConstantTypeExtractor { + def apply(value: Constant): ConstantType = { + class UniqueConstantType extends ConstantType(value) with UniqueType { + /** Save the type of 'value'. For Java enums, it depends on finding the linked class, + * which might not be found after 'flatten'. */ + private lazy val _tpe: Type = value.tpe + override def underlying: Type = _tpe + } + unique(new UniqueConstantType) } - unique(new UniqueConstantType) } /** A class for named types of the form @@ -1526,7 +1507,7 @@ trait Types { * @param sym ... * @param args ... */ - case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type { + abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type { // assert(!sym.isAbstractType || pre.isStable || pre.isError) // assert(!pre.isInstanceOf[ClassInfoType], this) // assert(!(sym hasFlag (PARAM | EXISTENTIAL)) || pre == NoPrefix, this) @@ -1567,10 +1548,10 @@ trait Types { def thisInfo = if (sym.isAliasType) normalize - else if (sym.isTypeMember) transformInfo(sym.info) + else if (sym.isNonClassType) transformInfo(sym.info) else sym.info - def relativeInfo = if (sym.isTypeMember) transformInfo(pre.memberInfo(sym)) else pre.memberInfo(sym) + def relativeInfo = if (sym.isNonClassType) transformInfo(pre.memberInfo(sym)) else pre.memberInfo(sym) override def typeSymbol = if (sym.isAliasType) normalize.typeSymbol else sym override def termSymbol = if (sym.isAliasType) normalize.termSymbol else super.termSymbol @@ -1632,7 +1613,7 @@ A type's typeSymbol should never be inspected directly. // (!result.isEmpty) IFF isHigherKinded override def typeParams: List[Symbol] = if (isHigherKinded) typeParamsDirect else List() - override def typeConstructor = rawTypeRef(pre, sym, List()) + override def typeConstructor = TypeRef(pre, sym, List()) // a reference (in a Scala program) to a type that has type parameters, but where the reference does not include type arguments // note that it doesn't matter whether the symbol refers to a java or scala symbol, @@ -1662,6 +1643,9 @@ A type's typeSymbol should never be inspected directly. xform.dealias } else this + override def remove(clazz: Symbol): Type = + if (sym == clazz && !args.isEmpty) args.head else this + def normalize0: Type = if (sym.isAliasType) { // beta-reduce if (sym.info.typeParams.length == args.length || !isHigherKinded) { @@ -1774,7 +1758,7 @@ A type's typeSymbol should never be inspected directly. } val monopart = if (!settings.debug.value && - (shorthands contains sym.fullNameString) && + (shorthands contains sym.fullName) && (sym.ownerChain forall (_.isClass))) // ensure that symbol is not a local copy with a name coincidence sym.name.toString else @@ -1808,7 +1792,7 @@ A type's typeSymbol should never be inspected directly. sym.isAnonymousClass || sym.isRefinementClass || sym.isScalaPackageClass) "" else if (sym.isPackageClass) - sym.fullNameString + "." + sym.fullName + "." else if (isStable && (sym.name.toString endsWith ".type")) sym.name.toString.substring(0, sym.name.length - 4) else @@ -1817,6 +1801,13 @@ A type's typeSymbol should never be inspected directly. override def kind = "TypeRef" } + object TypeRef extends TypeRefExtractor { + def apply(pre: Type, sym: Symbol, args: List[Type]): Type = { + class rawTypeRef extends TypeRef(pre, sym, args) with UniqueType + unique(new rawTypeRef) + } + } + /** A class representing a method type with parameters. */ case class MethodType(override val params: List[Symbol], @@ -1824,12 +1815,8 @@ A type's typeSymbol should never be inspected directly. override val isTrivial: Boolean = params.forall(_.tpe.isTrivial) && resultType.isTrivial - // The comment at ImplicitMethodType says the class is no longer needed, - // "a method type is implicit if the first parameter has the IMPLICIT flag". - // Should that change be pursued, then this method should be: - // def isImplicit = vparams.nonEmpty && (vparams.head hasFlag IMPLICIT) - def isImplicit = false - def isJava = false + def isImplicit = params.nonEmpty && params.head.isImplicit + def isJava = false // can we do something like for implicits? I.e. do Java methods without parameters need to be recognized? //assert(paramTypes forall (pt => !pt.typeSymbol.isImplClass))//DEBUG override def paramSectionCount: Int = resultType.paramSectionCount + 1 @@ -1873,11 +1860,7 @@ A type's typeSymbol should never be inspected directly. override def kind = "MethodType" } - // todo: this class is no longer needed, a method type is implicit if the first - // parameter has the IMPLICIT flag - class ImplicitMethodType(ps: List[Symbol], rt: Type) extends MethodType(ps, rt) { - override def isImplicit = true - } + object MethodType extends MethodTypeExtractor class JavaMethodType(ps: List[Symbol], rt: Type) extends MethodType(ps, rt) { override def isJava = true @@ -1935,6 +1918,8 @@ A type's typeSymbol should never be inspected directly. override def kind = "PolyType" } + object PolyType extends PolyTypeExtractor + case class ExistentialType(quantified: List[Symbol], override val underlying: Type) extends RewrappingTypeProxy { @@ -2029,6 +2014,8 @@ A type's typeSymbol should never be inspected directly. } } + object ExistentialType extends ExistentialTypeExtractor + /** A class containing the alternatives and type prefix of an overloaded symbol. * Not used after phase `typer'. */ @@ -2305,6 +2292,8 @@ A type's typeSymbol should never be inspected directly. override def kind = "AnnotatedType" } + object AnnotatedType extends AnnotatedTypeExtractor + /** A class representing types with a name. When an application uses * named arguments, the named argument types for calling isApplicable * are represented as NamedType. @@ -2315,10 +2304,7 @@ A type's typeSymbol should never be inspected directly. /** A class representing an as-yet unevaluated type. */ - abstract class LazyType extends Type { - override def isComplete: Boolean = false - override def complete(sym: Symbol) - override def safeToString = "<?>" + abstract class LazyType extends Type with AbsLazyType { override def kind = "LazyType" } @@ -2329,7 +2315,7 @@ A type's typeSymbol should never be inspected directly. */ private def rebind(pre: Type, sym: Symbol): Symbol = { val owner = sym.owner - if (owner.isClass && owner != pre.typeSymbol && !sym.isFinal && !sym.isClass) { + if (owner.isClass && owner != pre.typeSymbol && !sym.isEffectivelyFinal && !sym.isClass) { //Console.println("rebind "+pre+" "+sym)//DEBUG val rebind = pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || sym.isStable) if (rebind == NoSymbol) sym @@ -2345,7 +2331,7 @@ A type's typeSymbol should never be inspected directly. */ private def removeSuper(tp: Type, sym: Symbol): Type = tp match { case SuperType(thistp, _) => - if (sym.isFinal || sym.isDeferred) thistp + if (sym.isEffectivelyFinal || sym.isDeferred) thistp else tp case _ => tp @@ -2365,20 +2351,13 @@ A type's typeSymbol should never be inspected directly. } } - def refinementOfClass(clazz: Symbol, parents: List[Type], decls: Scope) = { - class RefinementOfClass extends RefinedType(parents, decls) { - override def typeSymbol: Symbol = clazz - } - new RefinementOfClass - } - /** the canonical creator for a refined type with a given scope */ def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos : Position): Type = { if (phase.erasedTypes) if (parents.isEmpty) ObjectClass.tpe else parents.head else { val clazz = owner.newRefinementClass(NoPosition) - val result = refinementOfClass(clazz, parents, decls) + val result = RefinedType(parents, decls, clazz) clazz.setInfo(result) result } @@ -2427,7 +2406,7 @@ A type's typeSymbol should never be inspected directly. transform(sym1.info) // check there are no cycles sym1.unlock() */ - rawTypeRef(pre, sym1, args) // don't expand type alias (cycles checked above) + TypeRef(pre, sym1, args) // don't expand type alias (cycles checked above) } else { val pre1 = removeSuper(pre, sym1) if (pre1 ne pre) { @@ -2438,31 +2417,20 @@ A type's typeSymbol should never be inspected directly. // sharpen prefix so that it is maximal and still contains the class. var p = pre.parents.reverse while (!p.isEmpty && p.head.member(sym1.name) != sym1) p = p.tail - if (p.isEmpty) rawTypeRef(pre, sym1, args) + if (p.isEmpty) TypeRef(pre, sym1, args) else typeRef(p.head, sym1, args) } else { - rawTypeRef(pre, sym1, args) + TypeRef(pre, sym1, args) } } } - /** create a type-ref as found, without checks or rebinds */ - def rawTypeRef(pre: Type, sym: Symbol, args: List[Type]): Type = { - class rawTypeRef extends TypeRef(pre, sym, args) with UniqueType - unique(new rawTypeRef) - } - - /** The canonical creator for implicit method types */ - def ImplicitMethodType(params: List[Symbol], resultType: Type): ImplicitMethodType = - new ImplicitMethodType(params, resultType) // don't unique this! - /** The canonical creator for implicit method types */ def JavaMethodType(params: List[Symbol], resultType: Type): JavaMethodType = new JavaMethodType(params, resultType) // don't unique this! - /** Create a new MethodType of the same class as tp, i.e. keep Java / ImplicitMethodType */ + /** Create a new MethodType of the same class as tp, i.e. keep JavaMethodType */ def copyMethodType(tp: Type, params: List[Symbol], restpe: Type): Type = tp match { - case _: ImplicitMethodType => ImplicitMethodType(params, restpe) case _: JavaMethodType => JavaMethodType(params, restpe) case _ => MethodType(params, restpe) } @@ -4480,7 +4448,7 @@ A type's typeSymbol should never be inspected directly. params1.length == params2.length && // useful pre-secreening optimization matchingParams(params1, params2, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) && matchesType(res1, res2, alwaysMatchSimple) && - tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType] + tp1.isImplicit == tp2.isImplicit case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => matchesQuantified(tparams1, tparams2, res1, res2) case (PolyType(List(), rtp1), MethodType(List(), rtp2)) => diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala index e827b28331..f1e88fe6e8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -154,7 +154,7 @@ abstract class ConstantFolder { private def foldBinop(op: Name, x: Constant, y: Constant): Constant = { val optag = if (x.tag == y.tag) x.tag - else if (isNumeric(x.tag) && isNumeric(y.tag)) math.max(x.tag, y.tag) + else if (x.isNumeric && y.isNumeric) math.max(x.tag, y.tag) else NoTag try optag match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index dd592bb96d..7ca4dcf885 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -8,7 +8,6 @@ package scala.tools.nsc package typechecker import symtab.Flags._ -import scala.tools.nsc.util.{Position,NoPosition} import scala.collection.mutable.ListBuffer /** This trait ... @@ -122,40 +121,6 @@ trait Contexts { self: Analyzer => var savedTypeBounds: List[(Symbol, Type)] = List() // saved type bounds // for type parameters which are narrowed in a GADT - def intern0 : Context = { - if (this eq NoContext) return this - val txt = new Context - txt.unit = unit - txt.tree = tree - txt.owner = owner - txt.scope = scope - assert(outer ne this) // stupid - txt.outer = outer // already interned - def fix(what : Context) = - if (what eq this) txt - else what - txt.enclClass = fix(enclClass) - txt.enclMethod = fix(enclMethod) - txt.implicitsEnabled = implicitsEnabled - txt.variance = variance - txt._undetparams = _undetparams - txt.depth = depth - txt.imports = imports - txt.openImplicits = openImplicits - txt.prefix = prefix - txt.inConstructorSuffix = inConstructorSuffix - txt.returnsSeen = returnsSeen - txt.reportGeneralErrors = reportGeneralErrors - txt.checking = checking - txt.retyping = retyping - txt.savedTypeBounds = savedTypeBounds - txt - } - override def equals(that: Any): Boolean = that match { - case that: AnyRef if this eq that => true - case that => super.equals(that) - } - def undetparams = _undetparams def undetparams_=(ps: List[Symbol]) = { //System.out.println("undetparams = " + ps);//debug @@ -184,11 +149,7 @@ trait Contexts { self: Analyzer => c.owner = owner c.scope = scope - c.outer = intern(this) - def internIf(txt : Context) = { - if (txt eq this) c.outer // already interned! - else txt - } + c.outer = this tree match { case Template(_, _, _) | PackageDef(_, _) => @@ -196,7 +157,7 @@ trait Contexts { self: Analyzer => c.prefix = c.owner.thisType c.inConstructorSuffix = false case _ => - c.enclClass = internIf(this.enclClass) + c.enclClass = this.enclClass c.prefix = if (c.owner != this.owner && c.owner.isTerm) NoPrefix else this.prefix @@ -206,7 +167,7 @@ trait Contexts { self: Analyzer => case DefDef(_, _, _, _, _, _) => c.enclMethod = c case _ => - c.enclMethod = internIf(this.enclMethod) + c.enclMethod = this.enclMethod } c.variance = this.variance c.depth = if (scope == this.scope) this.depth else this.depth + 1 @@ -530,30 +491,6 @@ trait Contexts { self: Analyzer => } implicitsCache } - override def hashCode = { - var hc = 0 - implicit def b2i(b : Boolean) = if (b) 1 else 0 - // assum enclClass/enclMethod/outer are all interned already. - hc += tree.hashCodeStructure - def f(txt : Context) = if (txt eq this) 0 else System.identityHashCode(txt) - hc += f(enclClass) - hc += f(enclMethod) - hc += f(outer) - hc += owner.hashCode - hc += scope.hashCode - hc += variance.hashCode - hc += _undetparams.hashCode - hc += depth - hc += imports.hashCode - hc += prefix.hashCode - hc += inConstructorSuffix - hc += checking - hc += retyping - hc += savedTypeBounds.hashCode - hc += (if (unit eq null) 0 else unit.hashCode) - hc - } - } class ImportInfo(val tree: Import, val depth: Int) { /** The prefix expression */ @@ -603,23 +540,9 @@ trait Contexts { self: Analyzer => } override def toString() = tree.toString() - - override def hashCode = tree.hashCodeStructure + depth - override def equals(that : Any) = that match { - case that : ImportInfo => - depth == that.depth && (tree equalsStructure that.tree) - case _ => false - } } case class ImportType(expr: Tree) extends Type { - override def equals(that : Any) = that match { - case ImportType(expr) => this.expr == expr - case _ => false - } - override def hashCode = expr.hashCode override def safeToString = "ImportType("+expr+")" } - protected def intern(txt : Context) = txt - } diff --git a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala index 97a1d81323..304ae5cdea 100644 --- a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala +++ b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala @@ -177,7 +177,7 @@ abstract class DeVirtualize extends InfoTransform with TypingTransformers { /** The name of the field representing a constructor parameter of a virtual class */ protected def paramFieldName(clazz: Symbol, index: Int) = atPhase(ownPhase) { - clazz.expandedName(newTermName("param$"+index)) + nme.expandedName(newTermName("param$"+index), clazz) } /** The name of the field representing a constructor parameter of a virtual class */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 796d6f8134..6a94189284 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -97,7 +97,7 @@ abstract class Duplicators extends Analyzer { val tpe2: Type = (new FixInvalidSyms)(tpe1) val tpe3 = tpe2 match { case TypeRef(_, sym, _) if (sym.owner == oldClassOwner) => - log("seeing " + sym.fullNameString + " from a different angle") + log("seeing " + sym.fullName + " from a different angle") tpe2.asSeenFrom(newClassOwner.thisType, oldClassOwner) case _ => tpe2 } diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala index ee267690f1..bb9582b093 100644 --- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -114,9 +114,7 @@ trait EtaExpansion { self: Analyzer => * @return ... */ def expand(tree: Tree, tpe: Type): Tree = tpe match { - case mt: ImplicitMethodType => - tree - case MethodType(paramSyms, restpe) => + case mt @ MethodType(paramSyms, restpe) if !mt.isImplicit => val params = paramSyms map (sym => ValDef(Modifiers(SYNTHETIC | PARAM), sym.name, TypeTree(sym.tpe) , EmptyTree)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index eb04ab984b..14190a323e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -12,7 +12,7 @@ package scala.tools.nsc package typechecker import scala.collection.mutable.{LinkedHashMap, ListBuffer} -import scala.tools.nsc.util.{ HashSet, Position, Set, NoPosition, SourceFile } +import scala.tools.nsc.util.{HashSet, Set, SourceFile} import symtab.Flags._ import util.Statistics._ @@ -798,7 +798,7 @@ self: Analyzer => (if ((pre eq NoPrefix) || pre.typeSymbol.isStaticOwner) suffix else findSubManifest(pre) :: suffix): _*) } else if (sym.isAbstractType) { - if (sym.isExistential) + if (sym.isExistentiallyBound) EmptyTree // todo: change to existential parameter manifest else if (sym.isTypeParameterOrSkolem) EmptyTree // a manifest should have been found by normal searchImplicit diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index bde84827b2..8761420778 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package typechecker -import scala.tools.nsc.util.{Position, NoPosition} + import scala.collection.mutable.ListBuffer import scala.util.control.ControlException import symtab.Flags._ @@ -399,8 +399,6 @@ trait Infer { def isPlausiblyCompatible(tp: Type, pt: Type): Boolean = tp match { case PolyType(_, restpe) => isPlausiblyCompatible(restpe, pt) - case mt: ImplicitMethodType => - isPlausiblyCompatible(mt.resultType, pt) case ExistentialType(tparams, qtpe) => isPlausiblyCompatible(qtpe, pt) case mt @ MethodType(params, restpe) => @@ -565,7 +563,7 @@ trait Infer { // optimze type varianbles wrt to the implicit formals only; ignore the result type. // See test pos/jesper.scala val varianceType = restpe match { - case mt: ImplicitMethodType if isFullyDefined(pt) => + case mt: MethodType if mt.isImplicit && isFullyDefined(pt) => MethodType(mt.params, AnyClass.tpe) case _ => restpe @@ -937,7 +935,7 @@ trait Infer { case et: ExistentialType => isAsSpecific(ftpe1.skolemizeExistential, ftpe2) //et.withTypeVars(isAsSpecific(_, ftpe2)) - case mt: ImplicitMethodType => + case mt: MethodType if mt.isImplicit => isAsSpecific(ftpe1.resultType, ftpe2) case MethodType(params @ (x :: xs), _) => var argtpes = params map (_.tpe) @@ -945,7 +943,7 @@ trait Infer { argtpes = argtpes map (argtpe => if (isRepeatedParamType(argtpe)) argtpe.typeArgs.head else argtpe) isApplicable(List(), ftpe2, argtpes, WildcardType) - case PolyType(tparams, mt: ImplicitMethodType) => + case PolyType(tparams, mt: MethodType) if mt.isImplicit => isAsSpecific(PolyType(tparams, mt.resultType), ftpe2) case PolyType(_, MethodType(params @ (x :: xs), _)) => isApplicable(List(), ftpe2, params map (_.tpe), WildcardType) @@ -957,12 +955,10 @@ trait Infer { alts forall (alt => isAsSpecific(ftpe1, pre.memberType(alt))) case et: ExistentialType => et.withTypeVars(isAsSpecific(ftpe1, _)) - case mt: ImplicitMethodType => - isAsSpecific(ftpe1, mt.resultType) - case PolyType(tparams, mt: ImplicitMethodType) => - isAsSpecific(ftpe1, PolyType(tparams, mt.resultType)) - case MethodType(_, _) | PolyType(_, MethodType(_, _)) => - true + case mt: MethodType => + !mt.isImplicit || isAsSpecific(ftpe1, mt.resultType) + case PolyType(tparams, mt: MethodType) => + !mt.isImplicit || isAsSpecific(ftpe1, PolyType(tparams, mt.resultType)) case _ => isAsSpecificValueType(ftpe1, ftpe2, List(), List()) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 74c57c0fb7..e64a78e8e4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -8,7 +8,6 @@ package scala.tools.nsc package typechecker import scala.collection.mutable.HashMap -import scala.tools.nsc.util.Position import symtab.Flags import symtab.Flags._ @@ -29,7 +28,7 @@ trait Namers { self: Analyzer => case TypeRef(pre, sym, args) if (sym.isTypeSkolem && (tparams contains sym.deSkolemize)) => // println("DESKOLEMIZING "+sym+" in "+sym.owner) - mapOver(rawTypeRef(NoPrefix, sym.deSkolemize, args)) + mapOver(TypeRef(NoPrefix, sym.deSkolemize, args)) /* case PolyType(tparams1, restpe) => new DeSkolemizeMap(tparams1 ::: tparams).mapOver(tp) @@ -76,7 +75,7 @@ trait Namers { self: Analyzer => } def inConstructorFlag: Long = - if (context.owner.isConstructor && !context.inConstructorSuffix || context.owner.isEarly) INCONSTRUCTOR + if (context.owner.isConstructor && !context.inConstructorSuffix || context.owner.isEarlyInitialized) INCONSTRUCTOR else 0l def moduleClassFlags(moduleFlags: Long) = @@ -127,6 +126,7 @@ trait Namers { self: Analyzer => unsafeTypeParams foreach(sym => paramContext.scope.enter(sym)) newNamer(paramContext) } + def usePrimary = sym.isTerm && ( (sym hasFlag PARAMACCESSOR) || ((sym hasFlag PARAM) && sym.owner.isPrimaryConstructor) @@ -837,9 +837,7 @@ trait Namers { self: Analyzer => val params = vparams map (vparam => if (meth hasFlag JAVA) vparam.setInfo(objToAny(vparam.tpe)) else vparam) val restpe1 = convertToDeBruijn(vparams, 1)(restpe) // new dependent types: replace symbols in restpe with the ones in vparams - if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) - ImplicitMethodType(params, restpe1) - else if (meth hasFlag JAVA) JavaMethodType(params, restpe1) + if (meth hasFlag JAVA) JavaMethodType(params, restpe1) else MethodType(params, restpe1) } @@ -946,7 +944,7 @@ trait Namers { self: Analyzer => // match empty and missing parameter list if (vparamss.isEmpty && baseParamss == List(Nil)) baseParamss = Nil if (vparamss == List(Nil) && baseParamss.isEmpty) baseParamss = List(Nil) - assert(!overrides || vparamss.length == baseParamss.length, ""+ meth.fullNameString + ", "+ overridden.fullNameString) + assert(!overrides || vparamss.length == baseParamss.length, ""+ meth.fullName + ", "+ overridden.fullName) var ownerNamer: Option[Namer] = None var moduleNamer: Option[(ClassDef, Namer)] = None @@ -957,7 +955,7 @@ trait Namers { self: Analyzer => // denotes the parameter lists which are on the left side of the current one. these get added // to the default getter. Example: "def foo(a: Int)(b: Int = a)" gives "foo$default$1(a: Int) = a" (List[List[ValDef]]() /: (vparamss))((previous: List[List[ValDef]], vparams: List[ValDef]) => { - assert(!overrides || vparams.length == baseParamss.head.length, ""+ meth.fullNameString + ", "+ overridden.fullNameString) + assert(!overrides || vparams.length == baseParamss.head.length, ""+ meth.fullName + ", "+ overridden.fullName) var baseParams = if (overrides) baseParamss.head else Nil for (vparam <- vparams) { val sym = vparam.symbol diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index b41924c3bb..273e8b1d97 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -7,7 +7,6 @@ package scala.tools.nsc package typechecker -import scala.tools.nsc.util.Position import symtab.Flags._ import scala.collection.mutable.ListBuffer diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index fcc5a3cbf4..5234bb44f1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -10,7 +10,6 @@ package typechecker import symtab.Flags._ import collection.mutable.{HashSet, HashMap} import transform.InfoTransform -import scala.tools.nsc.util.{Position, NoPosition} import scala.collection.mutable.ListBuffer /** <p> @@ -385,7 +384,7 @@ abstract class RefChecks extends InfoTransform { val opc = new overridingPairs.Cursor(clazz) while (opc.hasNext) { - //Console.println(opc.overriding/* + ":" + opc.overriding.tpe*/ + " in "+opc.overriding.fullNameString + " overrides " + opc.overridden/* + ":" + opc.overridden.tpe*/ + " in "+opc.overridden.fullNameString + "/"+ opc.overridden.hasFlag(DEFERRED));//debug + //Console.println(opc.overriding/* + ":" + opc.overriding.tpe*/ + " in "+opc.overriding.fullName + " overrides " + opc.overridden/* + ":" + opc.overridden.tpe*/ + " in "+opc.overridden.fullName + "/"+ opc.overridden.hasFlag(DEFERRED));//debug if (!opc.overridden.isClass) checkOverride(clazz, opc.overriding, opc.overridden); opc.next @@ -493,7 +492,7 @@ abstract class RefChecks extends InfoTransform { /** validate all base types of a class in reverse linear order. */ def register(tp: Type) { -// if (clazz.fullNameString.endsWith("Collection.Projection")) +// if (clazz.fullName.endsWith("Collection.Projection")) // println("validate base type "+tp) val baseClass = tp.typeSymbol if (baseClass.isClass) { diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 257ab243b4..7012fa177a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -9,7 +9,6 @@ package typechecker import scala.collection.mutable.ListBuffer import symtab.Flags._ -import util.Position /** This phase adds super accessors for all super calls that * either appear in a trait or have as a target a member of some outer class. diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index cc8d39fc5f..c2b6e7adf2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -8,7 +8,6 @@ package scala.tools.nsc package typechecker import scala.tools.nsc.symtab.Flags._ -import scala.tools.nsc.util.{Position, NoPosition} abstract class TreeCheckers extends Analyzer { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index baa0f9a8be..5285322d1f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -14,7 +14,7 @@ package typechecker import scala.collection.mutable.{HashMap, ListBuffer} import scala.util.control.ControlException import scala.tools.nsc.interactive.RangePositions -import scala.tools.nsc.util.{ Position, Set, NoPosition, SourceFile, BatchSourceFile } +import scala.tools.nsc.util.{Set, SourceFile, BatchSourceFile} import symtab.Flags._ import util.Statistics @@ -334,7 +334,7 @@ trait Typers { self: Analyzer => tp match { case TypeRef(pre, sym, args) => (checkNotLocked(sym)) && ( - !sym.isTypeMember || + !sym.isNonClassType || checkNonCyclic(pos, appliedType(pre.memberInfo(sym), args), sym) // @M! info for a type ref to a type parameter now returns a polytype // @M was: checkNonCyclic(pos, pre.memberInfo(sym).subst(sym.typeParams, args), sym) ) @@ -817,7 +817,7 @@ trait Typers { self: Analyzer => TypeTree(tparam.tpeHK) setPos tree.pos.focus)) setPos tree.pos //@M/tcpolyinfer: changed tparam.tpe to tparam.tpeHK context.undetparams = context.undetparams ::: tparams1 adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt, original) - case mt: ImplicitMethodType if ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1) + case mt: MethodType if mt.isImplicit && ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1) if (!context.undetparams.isEmpty/* && (mode & POLYmode) == 0 disabled to make implicits in new collection work; we should revisit this. */) { // (9) // println("adapt IMT: "+(context.undetparams, pt)) //@MDEBUG context.undetparams = inferExprInstance( @@ -1255,9 +1255,9 @@ trait Typers { self: Analyzer => /* if (settings.Xshowcls.value != "" && - settings.Xshowcls.value == context.owner.fullNameString) + settings.Xshowcls.value == context.owner.fullName) println("INFO "+context.owner+ - ", baseclasses = "+(context.owner.info.baseClasses map (_.fullNameString))+ + ", baseclasses = "+(context.owner.info.baseClasses map (_.fullName))+ ", lin = "+(context.owner.info.baseClasses map (context.owner.thisType.baseType))) */ } @@ -2676,7 +2676,7 @@ trait Typers { self: Analyzer => for (name <- names) { if (!name.annotations.contains(AnnotationInfo(AnnotationDefaultAttr.tpe, List(), List())) && !name.hasFlag(DEFAULTPARAM)) - error(ann.pos, "annotation " + annType.typeSymbol.fullNameString + " is missing argument " + name.name) + error(ann.pos, "annotation " + annType.typeSymbol.fullName + " is missing argument " + name.name) } if (hasError) annotationError @@ -3085,14 +3085,9 @@ trait Typers { self: Analyzer => } def typedAssign(lhs: Tree, rhs: Tree): Tree = { - def mayBeVarGetter(sym: Symbol) = sym.info match { - case PolyType(List(), _) => sym.owner.isClass && !sym.isStable - case _: ImplicitMethodType => sym.owner.isClass && !sym.isStable - case _ => false - } val lhs1 = typed(lhs, EXPRmode | LHSmode, WildcardType) val varsym = lhs1.symbol - if ((varsym ne null) && mayBeVarGetter(varsym)) + if ((varsym ne null) && treeInfo.mayBeVarGetter(varsym)) lhs1 match { case Select(qual, name) => return typed( @@ -3305,10 +3300,14 @@ trait Typers { self: Analyzer => case fun1: Tree => val fun2 = if (stableApplication) stabilizeFun(fun1, mode, pt) else fun1 incCounter(typedApplyCount) + def isImplicitMethod(tpe: Type) = tpe match { + case mt: MethodType => mt.isImplicit + case _ => false + } val res = if (phase.id <= currentRun.typerPhase.id && fun2.isInstanceOf[Select] && - !fun2.tpe.isInstanceOf[ImplicitMethodType] && + !isImplicitMethod(fun2.tpe) && ((fun2.symbol eq null) || !fun2.symbol.isConstructor) && (mode & (EXPRmode | SNDTRYmode)) == EXPRmode) { tryTypedApply(fun2, args) @@ -3698,7 +3697,7 @@ trait Typers { self: Analyzer => //@M! the polytype denotes the expected kind } val argtypes = args1 map (_.tpe) - val owntype = if (tpt1.symbol.isClass || tpt1.symbol.isTypeMember) + val owntype = if (tpt1.symbol.isClass || tpt1.symbol.isNonClassType) // @M! added the latter condition appliedType(tpt1.tpe, argtypes) else tpt1.tpe.instantiateTypeParams(tparams, argtypes) diff --git a/src/library/scala/reflect/Code.scala b/src/library/scala/reflect/Code.scala index 71e148db81..61138f2495 100644 --- a/src/library/scala/reflect/Code.scala +++ b/src/library/scala/reflect/Code.scala @@ -12,7 +12,7 @@ package scala.reflect /** This type is required by the compiler and <b>should not be used in client code</b>. */ -class Code[Type](val tree: Tree) +class Code[T](val tree: Tree) /** This type is required by the compiler and <b>should not be used in client code</b>. */ object Code { diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala new file mode 100755 index 0000000000..0629c3a2f8 --- /dev/null +++ b/src/library/scala/reflect/NameTransformer.scala @@ -0,0 +1,155 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2010, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: NameTransformer.scala 20028 2009-12-07 11:49:19Z cunei $ + + +package scala.reflect + +/** + * @author Martin Odersky + */ +object NameTransformer { + private val nops = 128 + private val ncodes = 26 * 26 + + private class OpCodes(val op: Char, val code: String, val next: OpCodes) + + private val op2code = new Array[String](nops) + private val code2op = new Array[OpCodes](ncodes) + + private def enterOp(op: Char, code: String) = { + op2code(op) = code + val c = (code.charAt(1) - 'a') * 26 + code.charAt(2) - 'a' + code2op(c) = new OpCodes(op, code, code2op(c)) + } + + /* Note: decoding assumes opcodes are only ever lowercase. */ + enterOp('~', "$tilde") + enterOp('=', "$eq") + enterOp('<', "$less") + enterOp('>', "$greater") + enterOp('!', "$bang") + enterOp('#', "$hash") + enterOp('%', "$percent") + enterOp('^', "$up") + enterOp('&', "$amp") + enterOp('|', "$bar") + enterOp('*', "$times") + enterOp('/', "$div") + enterOp('+', "$plus") + enterOp('-', "$minus") + enterOp(':', "$colon") + enterOp('\\', "$bslash") + enterOp('?', "$qmark") + enterOp('@', "$at") + + /** Replace operator symbols by corresponding "<code>$op_name</code>". + * + * @param name ... + * @return ... + */ + def encode(name: String): String = { + var buf: StringBuilder = null + val len = name.length() + var i = 0 + while (i < len) { + val c = name charAt i + if (c < nops && (op2code(c) ne null)) { + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append(op2code(c)) + /* Handle glyphs that are not valid Java/JVM identifiers */ + } + else if (!Character.isJavaIdentifierPart(c)) { + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append("$u%04X".format(c.toInt)) + } + else if (buf ne null) { + buf.append(c) + } + i += 1 + } + if (buf eq null) name else buf.toString() + } + + /** Replace <code>$op_name</code> by corresponding operator symbol. + * + * @param name0 ... + * @return ... + */ + def decode(name0: String): String = { + //System.out.println("decode: " + name);//DEBUG + val name = if (name0.endsWith("<init>")) name0.substring(0, name0.length() - ("<init>").length()) + "this" + else name0; + var buf: StringBuilder = null + val len = name.length() + var i = 0 + while (i < len) { + var ops: OpCodes = null + var unicode = false + val c = name charAt i + if (c == '$' && i + 2 < len) { + val ch1 = name.charAt(i+1) + if ('a' <= ch1 && ch1 <= 'z') { + val ch2 = name.charAt(i+2) + if ('a' <= ch2 && ch2 <= 'z') { + ops = code2op((ch1 - 'a') * 26 + ch2 - 'a') + while ((ops ne null) && !name.startsWith(ops.code, i)) ops = ops.next + if (ops ne null) { + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append(ops.op) + i += ops.code.length() + } + /* Handle the decoding of Unicode glyphs that are + * not valid Java/JVM identifiers */ + } else if ((len - i) >= 6 && // Check that there are enough characters left + ch1 == 'u' && + ((Character.isDigit(ch2)) || + ('A' <= ch2 && ch2 <= 'F'))) { + /* Skip past "$u", next four should be hexadecimal */ + val hex = name.substring(i+2, i+6) + try { + val str = Integer.parseInt(hex, 16).toChar + if (buf eq null) { + buf = new StringBuilder() + buf.append(name.substring(0, i)) + } + buf.append(str) + /* 2 for "$u", 4 for hexadecimal number */ + i += 6 + unicode = true + } catch { + case _:NumberFormatException => + /* <code>hex</code> did not decode to a hexadecimal number, so + * do nothing. */ + } + } + } + } + /* If we didn't see an opcode or encoded Unicode glyph, and the + buffer is non-empty, write the current character and advance + one */ + if ((ops eq null) && !unicode) { + if (buf ne null) + buf.append(c) + i += 1 + } + } + //System.out.println("= " + (if (buf == null) name else buf.toString()));//DEBUG + if (buf eq null) name else buf.toString() + } +} diff --git a/src/library/scala/reflect/generic/AnnotationInfos.scala b/src/library/scala/reflect/generic/AnnotationInfos.scala new file mode 100755 index 0000000000..6239ca189c --- /dev/null +++ b/src/library/scala/reflect/generic/AnnotationInfos.scala @@ -0,0 +1,42 @@ +package scala.reflect +package generic + +trait AnnotationInfos { self: Universe => + + type AnnotationInfo <: AnyRef + val AnnotationInfo: AnnotationInfoExtractor + + abstract class AnnotationInfoExtractor { + def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo + def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] + } + + type ClassfileAnnotArg <: AnyRef + implicit def classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] // need a precise manifest to pass to UnPickle's toArray call + + type LiteralAnnotArg <: ClassfileAnnotArg + val LiteralAnnotArg: LiteralAnnotArgExtractor + + type ArrayAnnotArg <: ClassfileAnnotArg + val ArrayAnnotArg: ArrayAnnotArgExtractor + + type NestedAnnotArg <: ClassfileAnnotArg + val NestedAnnotArg: NestedAnnotArgExtractor + + abstract class LiteralAnnotArgExtractor { + def apply(const: Constant): LiteralAnnotArg + def unapply(arg: LiteralAnnotArg): Option[Constant] + } + + abstract class ArrayAnnotArgExtractor { + def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg + def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] + } + + abstract class NestedAnnotArgExtractor { + def apply(anninfo: AnnotationInfo): NestedAnnotArg + def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] + } +} + + diff --git a/src/compiler/scala/tools/nsc/symtab/Constants.scala b/src/library/scala/reflect/generic/Constants.scala index 9057c537a7..4b21823978 100644..100755 --- a/src/compiler/scala/tools/nsc/symtab/Constants.scala +++ b/src/library/scala/reflect/generic/Constants.scala @@ -2,18 +2,15 @@ * Copyright 2005-2010 LAMP/EPFL * @author Martin Odersky */ -// $Id$ - -package scala.tools.nsc -package symtab +// $Id: Constants.scala 20028 2009-12-07 11:49:19Z cunei $ +package scala.reflect +package generic import java.lang.Integer.toOctalString +import PickleFormat._ -import classfile.PickleFormat._ - -trait Constants { - self: SymbolTable => +trait Constants { self: Universe => import definitions._ @@ -33,8 +30,6 @@ trait Constants { // For supporting java enumerations inside java annotations (see ClassfileParser) final val EnumTag = LITERALenum - LITERAL - def isNumeric(tag: Int) = ByteTag <= tag && tag <= DoubleTag - case class Constant(value: Any) { val tag: Int = @@ -53,6 +48,8 @@ trait Constants { else if (value == null) NullTag else throw new Error("bad constant value: " + value) + def isNumeric: Boolean = ByteTag <= tag && tag <= DoubleTag + def tpe: Type = tag match { case UnitTag => UnitClass.tpe case BooleanTag => BooleanClass.tpe @@ -65,7 +62,7 @@ trait Constants { case DoubleTag => DoubleClass.tpe case StringTag => StringClass.tpe case NullTag => NullClass.tpe - case ClassTag => Predef_classOfType(value.asInstanceOf[Type]) + case ClassTag => ClassType(value.asInstanceOf[Type]) case EnumTag => // given (in java): "class A { enum E { VAL1 } }" // - symbolValue: the symbol of the actual enumeration value (VAL1) @@ -82,11 +79,11 @@ trait Constants { override def equals(other: Any): Boolean = other match { case that: Constant => this.tag == that.tag && - (this.value == that.value || isNaN(this.value) && isNaN(that.value)) + (this.value == that.value || this.isNaN && that.isNaN) case _ => false } - def isNaN(value: Any) = value match { + def isNaN = value match { case f: Float => f.isNaN case d: Double => d.isNaN case _ => false @@ -233,7 +230,7 @@ trait Constants { def symbolValue: Symbol = value.asInstanceOf[Symbol] - override def hashCode(): Int = + override def hashCode: Int = if (value == null) 0 else value.hashCode() * 41 + 17 } } diff --git a/src/library/scala/reflect/generic/Flags.scala b/src/library/scala/reflect/generic/Flags.scala new file mode 100755 index 0000000000..1cd9190f19 --- /dev/null +++ b/src/library/scala/reflect/generic/Flags.scala @@ -0,0 +1,198 @@ +package scala.reflect +package generic + +object Flags extends Flags + +class Flags { + + // modifiers + final val IMPLICIT = 0x00000200 + final val FINAL = 0x00000020 + final val PRIVATE = 0x00000004 + final val PROTECTED = 0x00000001 + + final val SEALED = 0x00000400 + final val OVERRIDE = 0x00000002 + final val CASE = 0x00000800 + final val ABSTRACT = 0x00000008 // abstract class, or used in conjunction + // with abstract override. + // Note difference to DEFERRED! + + final val DEFERRED = 0x00000010 // was `abstract' for members | trait is virtual + final val METHOD = 0x00000040 // a method + final val MODULE = 0x00000100 // symbol is module or class implementing a module + final val INTERFACE = 0x00000080 // symbol is an interface (i.e. a trait which defines only abstract methods) + + final val MUTABLE = 0x00001000 // symbol is a mutable variable. + final val PARAM = 0x00002000 // symbol is a (value or type) parameter to a method + final val PACKAGE = 0x00004000 // symbol is a java package + // available: 0x00008000 + + final val COVARIANT = 0x00010000 // symbol is a covariant type variable + final val CAPTURED = 0x00010000 // variable is accessed from nested function. + // Set by LambdaLift + final val BYNAMEPARAM = 0x00010000 // parameter is by name + final val CONTRAVARIANT = 0x00020000 // symbol is a contravariant type variable + final val LABEL = 0x00020000 // method symbol is a label. Set by TailCall + final val INCONSTRUCTOR = 0x00020000 // class symbol is defined in this/superclass + // constructor. + final val ABSOVERRIDE = 0x00040000 // combination of abstract & override + final val LOCAL = 0x00080000 // symbol is local to current class (i.e. private[this] or protected[this] + // pre: PRIVATE or PROTECTED are also set + final val JAVA = 0x00100000 // symbol was defined by a Java class + final val SYNTHETIC = 0x00200000 // symbol is compiler-generated + final val STABLE = 0x00400000 // functions that are assumed to be stable + // (typically, access methods for valdefs) + // or classes that do not contain abstract types. + final val STATIC = 0x00800000 // static field, method or class + + final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor) + final val TRAIT = 0x02000000 // symbol is a trait + final val DEFAULTPARAM = 0x02000000 // the parameter has a default value + final val BRIDGE = 0x04000000 // function is a bridge method. Set by Erasure + final val ACCESSOR = 0x08000000 // a value or variable accessor (getter or setter) + + final val SUPERACCESSOR = 0x10000000 // a super accessor + final val PARAMACCESSOR = 0x20000000 // for value definitions: is an access method + // for a final val parameter + // for parameters: is a val parameter + final val MODULEVAR = 0x40000000 // for variables: is the variable caching a module value + final val SYNTHETICMETH = 0x40000000 // for methods: synthetic method, but without SYNTHETIC flag + final val MONOMORPHIC = 0x40000000 // for type symbols: does not have type parameters + final val LAZY = 0x80000000L // symbol is a lazy val. can't have MUTABLE unless transformed by typer + + final val IS_ERROR = 0x100000000L // symbol is an error symbol + final val OVERLOADED = 0x200000000L // symbol is overloaded + final val LIFTED = 0x400000000L // class has been lifted out to package level + // local value has been lifted out to class level + // todo: make LIFTED = latePRIVATE? + final val MIXEDIN = 0x800000000L // term member has been mixed in + final val EXISTENTIAL = 0x800000000L // type is an existential parameter or skolem + + final val EXPANDEDNAME = 0x1000000000L // name has been expanded with class suffix + final val IMPLCLASS = 0x2000000000L // symbol is an implementation class + final val PRESUPER = 0x2000000000L // value is evaluated before super call + final val TRANS_FLAG = 0x4000000000L // transient flag guaranteed to be reset + // after each phase. + + final val LOCKED = 0x8000000000L // temporary flag to catch cyclic dependencies + final val SPECIALIZED = 0x10000000000L// symbol is a generated specialized member + final val DEFAULTINIT = 0x20000000000L// symbol is a generated specialized member + final val VBRIDGE = 0x40000000000L// symbol is a varargs bridge + + // pickling and unpickling of flags + + // The flags from 0x001 to 0x800 are different in the raw flags + // and in the pickled format. + + private final val IMPLICIT_PKL = 0x00000001 + private final val FINAL_PKL = 0x00000002 + private final val PRIVATE_PKL = 0x00000004 + private final val PROTECTED_PKL = 0x00000008 + + private final val SEALED_PKL = 0x00000010 + private final val OVERRIDE_PKL = 0x00000020 + private final val CASE_PKL = 0x00000040 + private final val ABSTRACT_PKL = 0x00000080 + + private final val DEFERRED_PKL = 0x00000100 + private final val METHOD_PKL = 0x00000200 + private final val MODULE_PKL = 0x00000400 + private final val INTERFACE_PKL = 0x00000800 + + private final val PKL_MASK = 0x00000FFF + + final val PickledFlags: Long = 0xFFFFFFFFL + + private val r2p = { + def rawFlagsToPickledAux(flags:Int) = { + var pflags=0 + if ((flags & IMPLICIT )!=0) pflags|=IMPLICIT_PKL + if ((flags & FINAL )!=0) pflags|=FINAL_PKL + if ((flags & PRIVATE )!=0) pflags|=PRIVATE_PKL + if ((flags & PROTECTED)!=0) pflags|=PROTECTED_PKL + if ((flags & SEALED )!=0) pflags|=SEALED_PKL + if ((flags & OVERRIDE )!=0) pflags|=OVERRIDE_PKL + if ((flags & CASE )!=0) pflags|=CASE_PKL + if ((flags & ABSTRACT )!=0) pflags|=ABSTRACT_PKL + if ((flags & DEFERRED )!=0) pflags|=DEFERRED_PKL + if ((flags & METHOD )!=0) pflags|=METHOD_PKL + if ((flags & MODULE )!=0) pflags|=MODULE_PKL + if ((flags & INTERFACE)!=0) pflags|=INTERFACE_PKL + pflags + } + val v=new Array[Int](PKL_MASK+1) + var i=0 + while (i<=PKL_MASK) { + v(i)=rawFlagsToPickledAux(i) + i+=1 + } + v + } + + private val p2r = { + def pickledToRawFlagsAux(pflags:Int) = { + var flags=0 + if ((pflags & IMPLICIT_PKL )!=0) flags|=IMPLICIT + if ((pflags & FINAL_PKL )!=0) flags|=FINAL + if ((pflags & PRIVATE_PKL )!=0) flags|=PRIVATE + if ((pflags & PROTECTED_PKL)!=0) flags|=PROTECTED + if ((pflags & SEALED_PKL )!=0) flags|=SEALED + if ((pflags & OVERRIDE_PKL )!=0) flags|=OVERRIDE + if ((pflags & CASE_PKL )!=0) flags|=CASE + if ((pflags & ABSTRACT_PKL )!=0) flags|=ABSTRACT + if ((pflags & DEFERRED_PKL )!=0) flags|=DEFERRED + if ((pflags & METHOD_PKL )!=0) flags|=METHOD + if ((pflags & MODULE_PKL )!=0) flags|=MODULE + if ((pflags & INTERFACE_PKL)!=0) flags|=INTERFACE + flags + } + val v=new Array[Int](PKL_MASK+1) + var i=0 + while (i<=PKL_MASK) { + v(i)=pickledToRawFlagsAux(i) + i+=1 + } + v + } + + def rawFlagsToPickled(flags:Long):Long = + (flags & ~PKL_MASK) | r2p(flags.toInt & PKL_MASK) + + def pickledToRawFlags(pflags:Long):Long = + (pflags & ~PKL_MASK) | p2r(pflags.toInt & PKL_MASK) + + // List of the raw flags, in pickled order + protected val pickledListOrder = { + def findBit(m:Long):Int = { + var mask=m + var i=0 + while (i <= 62) { + if ((mask&1) == 1L) return i + mask >>= 1 + i += 1 + } + throw new AssertionError() + } + val v=new Array[Long](63) + v(findBit(IMPLICIT_PKL ))=IMPLICIT + v(findBit(FINAL_PKL ))=FINAL + v(findBit(PRIVATE_PKL ))=PRIVATE + v(findBit(PROTECTED_PKL))=PROTECTED + v(findBit(SEALED_PKL ))=SEALED + v(findBit(OVERRIDE_PKL ))=OVERRIDE + v(findBit(CASE_PKL ))=CASE + v(findBit(ABSTRACT_PKL ))=ABSTRACT + v(findBit(DEFERRED_PKL ))=DEFERRED + v(findBit(METHOD_PKL ))=METHOD + v(findBit(MODULE_PKL ))=MODULE + v(findBit(INTERFACE_PKL))=INTERFACE + var i=findBit(PKL_MASK+1) + while (i <= 62) { + v(i)=1L << i + i += 1 + } + v.toList + } + +} diff --git a/src/library/scala/reflect/generic/Names.scala b/src/library/scala/reflect/generic/Names.scala new file mode 100755 index 0000000000..1b31726e3a --- /dev/null +++ b/src/library/scala/reflect/generic/Names.scala @@ -0,0 +1,21 @@ +package scala.reflect +package generic + +trait Names { + + type Name >: Null <: AnyRef + + def newTermName(cs: Array[Char], offset: Int, len: Int): Name + def newTermName(cs: Array[Byte], offset: Int, len: Int): Name + def newTermName(s: String): Name + + def mkTermName(name: Name): Name + + def newTypeName(cs: Array[Char], offset: Int, len: Int): Name + def newTypeName(cs: Array[Byte], offset: Int, len: Int): Name + def newTypeName(s: String): Name + + def mkTypeName(name: Name): Name +} + + diff --git a/src/library/scala/reflect/generic/PickleBuffer.scala b/src/library/scala/reflect/generic/PickleBuffer.scala new file mode 100755 index 0000000000..584b94578e --- /dev/null +++ b/src/library/scala/reflect/generic/PickleBuffer.scala @@ -0,0 +1,165 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Martin Odersky + */ +// $Id: PickleBuffer.scala 20028 2009-12-07 11:49:19Z cunei $ + +package scala.reflect +package generic + +/** Variable length byte arrays, with methods for basic pickling and unpickling. + * + * @param data The initial buffer + * @param from The first index where defined data are found + * @param to The first index where new data can be written + */ +class PickleBuffer(data: Array[Byte], from: Int, to: Int) { + + var bytes = data + var readIndex = from + var writeIndex = to + + /** Double bytes array */ + private def dble() { + val bytes1 = new Array[Byte](bytes.length * 2) + Array.copy(bytes, 0, bytes1, 0, writeIndex) + bytes = bytes1 + } + + def ensureCapacity(capacity: Int) = + while (bytes.length < writeIndex + capacity) dble() + + // -- Basic output routines -------------------------------------------- + + /** Write a byte of data */ + def writeByte(b: Int) { + if (writeIndex == bytes.length) dble() + bytes(writeIndex) = b.toByte + writeIndex += 1 + } + + /** Write a natural number in big endian format, base 128. + * All but the last digits have bit 0x80 set. + */ + def writeNat(x: Int) = + writeLongNat(x.toLong & 0x00000000FFFFFFFFL) + + /** + * Like writeNat, but for longs. This is not the same as + * writeLong, which writes in base 256. Note that the + * binary representation of LongNat is identical to Nat + * if the long value is in the range Int.MIN_VALUE to + * Int.MAX_VALUE. + */ + def writeLongNat(x: Long) { + def writeNatPrefix(x: Long) { + val y = x >>> 7 + if (y != 0L) writeNatPrefix(y) + writeByte(((x & 0x7f) | 0x80).toInt) + } + val y = x >>> 7 + if (y != 0L) writeNatPrefix(y) + writeByte((x & 0x7f).toInt) + } + + /** Write a natural number <code>x</code> at position <code>pos</code>. + * If number is more than one byte, shift rest of array to make space. + * + * @param pos ... + * @param x ... + */ + def patchNat(pos: Int, x: Int) { + def patchNatPrefix(x: Int) { + writeByte(0) + Array.copy(bytes, pos, bytes, pos+1, writeIndex - (pos+1)) + bytes(pos) = ((x & 0x7f) | 0x80).toByte + val y = x >>> 7 + if (y != 0) patchNatPrefix(y) + } + bytes(pos) = (x & 0x7f).toByte + val y = x >>> 7 + if (y != 0) patchNatPrefix(y) + } + + /** Write a long number <code>x</code> in signed big endian format, base 256. + * + * @param x The long number to be written. + */ + def writeLong(x: Long) { + val y = x >> 8 + val z = x & 0xff + if (-y != (z >> 7)) writeLong(y) + writeByte(z.toInt) + } + + // -- Basic input routines -------------------------------------------- + + /** Peek at the current byte without moving the read index */ + def peekByte(): Int = bytes(readIndex) + + /** Read a byte */ + def readByte(): Int = { + val x = bytes(readIndex); readIndex += 1; x + } + + /** Read a natural number in big endian format, base 128. + * All but the last digits have bit 0x80 set.*/ + def readNat(): Int = readLongNat().toInt + + def readLongNat(): Long = { + var b = 0L + var x = 0L + do { + b = readByte() + x = (x << 7) + (b & 0x7f) + } while ((b & 0x80) != 0L); + x + } + + /** Read a long number in signed big endian format, base 256. */ + def readLong(len: Int): Long = { + var x = 0L + var i = 0 + while (i < len) { + x = (x << 8) + (readByte() & 0xff) + i += 1 + } + val leading = 64 - (len << 3) + x << leading >> leading + } + + /** Perform operation <code>op</code> until the condition + * <code>readIndex == end</code> is satisfied. + * Concatenate results into a list. + * + * @param end ... + * @param op ... + * @return ... + */ + def until[T](end: Int, op: () => T): List[T] = + if (readIndex == end) List() else op() :: until(end, op); + + /** Perform operation <code>op</code> the number of + * times specified. Concatenate the results into a list. + */ + def times[T](n: Int, op: ()=>T): List[T] = + if (n == 0) List() else op() :: times(n-1, op) + + /** Pickle = majorVersion_Nat minorVersion_Nat nbEntries_Nat {Entry} + * Entry = type_Nat length_Nat [actual entries] + * + * Assumes that the ..Version_Nat are already consumed. + * + * @return an array mapping entry numbers to locations in + * the byte array where the entries start. + */ + def createIndex: Array[Int] = { + val index = new Array[Int](readNat()) // nbEntries_Nat + for (i <- 0 until index.length) { + index(i) = readIndex + readByte() // skip type_Nat + readIndex = readNat() + readIndex // read length_Nat, jump to next entry + } + index + } +} diff --git a/src/library/scala/reflect/generic/PickleFormat.scala b/src/library/scala/reflect/generic/PickleFormat.scala new file mode 100755 index 0000000000..d1e884f513 --- /dev/null +++ b/src/library/scala/reflect/generic/PickleFormat.scala @@ -0,0 +1,223 @@ +package scala.reflect +package generic + +/** This object provides constants for pickling attributes. + * + * If you extend the format, be sure to increase the + * version minor number. + * + * @author Martin Odersky + * @version 1.0 + */ +object PickleFormat { + +/*************************************************** + * Symbol table attribute format: + * Symtab = nentries_Nat {Entry} + * Entry = 1 TERMNAME len_Nat NameInfo + * | 2 TYPENAME len_Nat NameInfo + * | 3 NONEsym len_Nat + * | 4 TYPEsym len_Nat SymbolInfo + * | 5 ALIASsym len_Nat SymbolInfo + * | 6 CLASSsym len_Nat SymbolInfo [thistype_Ref] + * | 7 MODULEsym len_Nat SymbolInfo + * | 8 VALsym len_Nat [defaultGetter_Ref /* no longer needed*/] SymbolInfo [alias_Ref] + * | 9 EXTref len_Nat name_Ref [owner_Ref] + * | 10 EXTMODCLASSref len_Nat name_Ref [owner_Ref] + * | 11 NOtpe len_Nat + * | 12 NOPREFIXtpe len_Nat + * | 13 THIStpe len_Nat sym_Ref + * | 14 SINGLEtpe len_Nat type_Ref sym_Ref + * | 15 CONSTANTtpe len_Nat constant_Ref + * | 16 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} + * | 17 TYPEBOUNDStpe len_Nat tpe_Ref tpe_Ref + * | 18 REFINEDtpe len_Nat classsym_Ref {tpe_Ref} + * | 19 CLASSINFOtpe len_Nat classsym_Ref {tpe_Ref} + * | 20 METHODtpe len_Nat tpe_Ref {sym_Ref} + * | 21 POLYTtpe len_Nat tpe_Ref {sym_Ref} + * | 22 IMPLICITMETHODtpe len_Nat tpe_Ref {sym_Ref} /* no longer needed */ + * | 52 SUPERtpe len_Nat tpe_Ref tpe_Ref + * | 24 LITERALunit len_Nat + * | 25 LITERALboolean len_Nat value_Long + * | 26 LITERALbyte len_Nat value_Long + * | 27 LITERALshort len_Nat value_Long + * | 28 LITERALchar len_Nat value_Long + * | 29 LITERALint len_Nat value_Long + * | 30 LITERALlong len_Nat value_Long + * | 31 LITERALfloat len_Nat value_Long + * | 32 LITERALdouble len_Nat value_Long + * | 33 LITERALstring len_Nat name_Ref + * | 34 LITERALnull len_Nat + * | 35 LITERALclass len_Nat tpe_Ref + * | 36 LITERALenum len_Nat sym_Ref + * | 40 SYMANNOT len_Nat sym_Ref AnnotInfoBody + * | 41 CHILDREN len_Nat sym_Ref {sym_Ref} + * | 42 ANNOTATEDtpe len_Nat [sym_Ref /* no longer needed */] tpe_Ref {annotinfo_Ref} + * | 43 ANNOTINFO len_Nat AnnotInfoBody + * | 44 ANNOTARGARRAY len_Nat {constAnnotArg_Ref} + * | 47 DEBRUIJNINDEXtpe len_Nat level_Nat index_Nat + * | 48 EXISTENTIALtpe len_Nat type_Ref {symbol_Ref} + * | 49 TREE len_Nat 1 EMPTYtree + * | 49 TREE len_Nat 2 PACKAGEtree type_Ref sym_Ref mods_Ref name_Ref {tree_Ref} + * | 49 TREE len_Nat 3 CLASStree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 4 MODULEtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref + * | 49 TREE len_Nat 5 VALDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 6 DEFDEFtree type_Ref sym_Ref mods_Ref name_Ref numtparams_Nat {tree_Ref} numparamss_Nat {numparams_Nat {tree_Ref}} tree_Ref tree_Ref + * | 49 TREE len_Nat 7 TYPEDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 8 LABELtree type_Ref sym_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 9 IMPORTtree type_Ref sym_Ref tree_Ref {name_Ref name_Ref} + * | 49 TREE len_Nat 11 DOCDEFtree type_Ref sym_Ref string_Ref tree_Ref + * | 49 TREE len_Nat 12 TEMPLATEtree type_Ref sym_Ref numparents_Nat {tree_Ref} tree_Ref {tree_Ref} + * | 49 TREE len_Nat 13 BLOCKtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 14 CASEtree type_Ref tree_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 15 SEQUENCEtree type_Ref {tree_Ref} + * | 49 TREE len_Nat 16 ALTERNATIVEtree type_Ref {tree_Ref} + * | 49 TREE len_Nat 17 STARtree type_Ref {tree_Ref} + * | 49 TREE len_Nat 18 BINDtree type_Ref sym_Ref name_Ref tree_Ref + * | 49 TREE len_Nat 19 UNAPPLYtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 20 ARRAYVALUEtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 21 FUNCTIONtree type_Ref sym_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 22 ASSIGNtree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 23 IFtree type_Ref tree_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 24 MATCHtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 25 RETURNtree type_Ref sym_Ref tree_Ref + * | 49 TREE len_Nat 26 TREtree type_Ref tree_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 27 THROWtree type_Ref tree_Ref + * | 49 TREE len_Nat 28 NEWtree type_Ref tree_Ref + * | 49 TREE len_Nat 29 TYPEDtree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 30 TYPEAPPLYtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 31 APPLYtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 32 APPLYDYNAMICtree type_Ref sym_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 33 SUPERtree type_Ref sym_Ref tree_Ref name_Ref + * | 49 TREE len_Nat 34 THIStree type_Ref sym_Ref name_Ref + * | 49 TREE len_Nat 35 SELECTtree type_Ref sym_Ref tree_Ref name_Ref + * | 49 TREE len_Nat 36 IDENTtree type_Ref sym_Ref name_Ref + * | 49 TREE len_Nat 37 LITERALtree type_Ref constant_Ref + * | 49 TREE len_Nat 38 TYPEtree type_Ref + * | 49 TREE len_Nat 39 ANNOTATEDtree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 40 SINGLETONTYPEtree type_Ref tree_Ref + * | 49 TREE len_Nat 41 SELECTFROMTYPEtree type_Ref tree_Ref name_Ref + * | 49 TREE len_Nat 42 COMPOUNDTYPEtree type_Ref tree_Ref + * | 49 TREE len_Nat 43 APPLIEDTYPEtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 44 TYPEBOUNDStree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 45 EXISTENTIALTYPEtree type_Ref tree_Ref {tree_Ref} + * | 50 MODIFIERS len_Nat flags_Long privateWithin_Ref + * SymbolInfo = name_Ref owner_Ref flags_LongNat [privateWithin_Ref] info_Ref + * NameInfo = <character sequence of length len_Nat in Utf8 format> + * NumInfo = <len_Nat-byte signed number in big endian format> + * Ref = Nat + * AnnotInfoBody = info_Ref {annotArg_Ref} {name_Ref constAnnotArg_Ref} + * AnnotArg = Tree | Constant + * ConstAnnotArg = Constant | AnnotInfo | AnnotArgArray + * + * len is remaining length after `len'. + */ + val MajorVersion = 5 + val MinorVersion = 0 + + final val TERMname = 1 + final val TYPEname = 2 + final val NONEsym = 3 + final val TYPEsym = 4 + final val ALIASsym = 5 + final val CLASSsym = 6 + final val MODULEsym = 7 + final val VALsym = 8 + final val EXTref = 9 + final val EXTMODCLASSref = 10 + final val NOtpe = 11 + final val NOPREFIXtpe = 12 + final val THIStpe = 13 + final val SINGLEtpe = 14 + final val CONSTANTtpe = 15 + final val TYPEREFtpe = 16 + final val TYPEBOUNDStpe = 17 + final val REFINEDtpe = 18 + final val CLASSINFOtpe = 19 + final val METHODtpe = 20 + final val POLYtpe = 21 + final val IMPLICITMETHODtpe = 22 + + final val LITERAL = 23 // base line for literals + final val LITERALunit = 24 + final val LITERALboolean = 25 + final val LITERALbyte = 26 + final val LITERALshort = 27 + final val LITERALchar = 28 + final val LITERALint = 29 + final val LITERALlong = 30 + final val LITERALfloat = 31 + final val LITERALdouble = 32 + final val LITERALstring = 33 + final val LITERALnull = 34 + final val LITERALclass = 35 + final val LITERALenum = 36 + final val SYMANNOT = 40 + final val CHILDREN = 41 + final val ANNOTATEDtpe = 42 + final val ANNOTINFO = 43 + final val ANNOTARGARRAY = 44 + + final val SUPERtpe = 46 + final val DEBRUIJNINDEXtpe = 47 + final val EXISTENTIALtpe = 48 + + final val TREE = 49 // prefix code that means a tree is coming + final val EMPTYtree = 1 + final val PACKAGEtree = 2 + final val CLASStree = 3 + final val MODULEtree = 4 + final val VALDEFtree = 5 + final val DEFDEFtree = 6 + final val TYPEDEFtree = 7 + final val LABELtree = 8 + final val IMPORTtree = 9 + final val DOCDEFtree = 11 + final val TEMPLATEtree = 12 + final val BLOCKtree = 13 + final val CASEtree = 14 + // This node type has been removed. + // final val SEQUENCEtree = 15 + final val ALTERNATIVEtree = 16 + final val STARtree = 17 + final val BINDtree = 18 + final val UNAPPLYtree = 19 + final val ARRAYVALUEtree = 20 + final val FUNCTIONtree = 21 + final val ASSIGNtree = 22 + final val IFtree = 23 + final val MATCHtree = 24 + final val RETURNtree = 25 + final val TREtree = 26 + final val THROWtree = 27 + final val NEWtree = 28 + final val TYPEDtree = 29 + final val TYPEAPPLYtree = 30 + final val APPLYtree = 31 + final val APPLYDYNAMICtree = 32 + final val SUPERtree = 33 + final val THIStree = 34 + final val SELECTtree = 35 + final val IDENTtree = 36 + final val LITERALtree = 37 + final val TYPEtree = 38 + final val ANNOTATEDtree = 39 + final val SINGLETONTYPEtree = 40 + final val SELECTFROMTYPEtree = 41 + final val COMPOUNDTYPEtree = 42 + final val APPLIEDTYPEtree = 43 + final val TYPEBOUNDStree = 44 + final val EXISTENTIALTYPEtree = 45 + + final val MODIFIERS = 50 + + final val firstSymTag = NONEsym + final val lastSymTag = VALsym + final val lastExtSymTag = EXTMODCLASSref + + + //The following two are no longer accurate, because ANNOTATEDtpe, + //SUPERtpe, ... are not in the same range as the other types + //final val firstTypeTag = NOtpe + //final val lastTypeTag = POLYtpe +} diff --git a/src/library/scala/reflect/generic/Scopes.scala b/src/library/scala/reflect/generic/Scopes.scala new file mode 100755 index 0000000000..9f8a8ecd19 --- /dev/null +++ b/src/library/scala/reflect/generic/Scopes.scala @@ -0,0 +1,15 @@ +package scala.reflect +package generic + +trait Scopes { self: Universe => + + abstract class AbsScope extends Iterable[Symbol] { + def enter(sym: Symbol): Symbol + } + + type Scope <: AbsScope + + def newScope(): Scope +} + + diff --git a/src/library/scala/reflect/generic/StandardDefinitions.scala b/src/library/scala/reflect/generic/StandardDefinitions.scala new file mode 100755 index 0000000000..24dce7173a --- /dev/null +++ b/src/library/scala/reflect/generic/StandardDefinitions.scala @@ -0,0 +1,67 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Martin Odersky + */ +// $Id: Definitions.scala 20619 2010-01-20 10:55:56Z rytz $ + +package scala.reflect +package generic + +trait StandardDefinitions { self: Universe => + + val definitions: AbsDefinitions + + abstract class AbsDefinitions { + + // outer packages and their classes + def RootPackage: Symbol + def RootClass: Symbol + def EmptyPackage: Symbol + def EmptyPackageClass: Symbol + + def ScalaPackage: Symbol + def ScalaPackageClass: Symbol + + // top types + def AnyClass : Symbol + def AnyValClass: Symbol + def AnyRefClass: Symbol + def ObjectClass: Symbol + + // bottom types + def NullClass : Symbol + def NothingClass: Symbol + + // the scala value classes + def UnitClass : Symbol + def ByteClass : Symbol + def ShortClass : Symbol + def CharClass : Symbol + def IntClass : Symbol + def LongClass : Symbol + def FloatClass : Symbol + def DoubleClass : Symbol + def BooleanClass: Symbol + + // fundamental reference classes + def SymbolClass : Symbol + def StringClass : Symbol + def ClassClass : Symbol + + // fundamental modules + def PredefModule: Symbol + + // fundamental type constructions + def ClassType(arg: Type): Type + + /** The string representation used by the given type in the VM. + */ + def signature(tp: Type): String + + /** Is symbol one of the value classes? */ + def isValueClass(sym: Symbol): Boolean + + /** Is symbol one of the numeric value classes? */ + def isNumericValueClass(sym: Symbol): Boolean + } +} diff --git a/src/library/scala/reflect/generic/StdNames.scala b/src/library/scala/reflect/generic/StdNames.scala new file mode 100755 index 0000000000..7f48b5bf62 --- /dev/null +++ b/src/library/scala/reflect/generic/StdNames.scala @@ -0,0 +1,26 @@ +package scala.reflect +package generic + +trait StdNames { self: Universe => + + val nme: StandardNames + + class StandardNames { + val EXPAND_SEPARATOR_STRING = "$$" + val LOCAL_SUFFIX_STRING = " " + + val ANON_CLASS_NAME = newTermName("$anon") + val ANON_FUN_NAME = newTermName("$anonfun") + val EMPTY_PACKAGE_NAME = newTermName("<empty>") + val IMPORT = newTermName("<import>") + val REFINE_CLASS_NAME = newTermName("<refinement>") + val ROOT = newTermName("<root>") + val ROOTPKG = newTermName("_root_") + val EMPTY = newTermName("") + + /** The expanded name of `name' relative to this class `base` with given `seperator` + */ + def expandedName(name: Name, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): Name = + newTermName(base.fullName('$') + separator + name) + } +} diff --git a/src/library/scala/reflect/generic/Symbols.scala b/src/library/scala/reflect/generic/Symbols.scala new file mode 100755 index 0000000000..4f6e4402b9 --- /dev/null +++ b/src/library/scala/reflect/generic/Symbols.scala @@ -0,0 +1,199 @@ +package scala.reflect +package generic + +import Flags._ + +trait Symbols { self: Universe => + + type Symbol >: Null <: AbsSymbol + + abstract class AbsSymbol { this: Symbol => + + /** The owner of this symbol. + */ + def owner: Symbol + + /** The flags of this symbol */ + def flags: Long + + /** The name of the symbol as a member of the `Name` type. + */ + def name: Name + + /** The name of the symbol before decoding, e.g. `$eq$eq` instead of `==`. + */ + def encodedName: String + + /** The decoded name of the symbol, e.g. `==` instead of `$eq$eq`. + */ + def decodedName: String = stripLocalSuffix(NameTransformer.decode(encodedName)) + + /** The encoded full path name of this symbol, where outer names and inner names + * are separated by `separator` characters. + * Never translates expansions of operators back to operator symbol. + * Never adds id. + */ + final def fullName(separator: Char): String = stripLocalSuffix { + if (isRoot || isRootPackage || this == NoSymbol) this.toString + else if (owner.isEffectiveRoot) encodedName + else owner.enclClass.fullName(separator) + separator + encodedName + } + + private def stripLocalSuffix(s: String) = + if (s endsWith nme.LOCAL_SUFFIX_STRING) + s.substring(0, s.length - nme.LOCAL_SUFFIX_STRING.length) + else + s + + /** The encoded full path name of this symbol, where outer names and inner names + * are separated by periods. + */ + final def fullName: String = fullName('.') + + /** Does symbol have a flag in `mask` set? */ + final def hasFlag(mask: Long): Boolean = (flags & mask) != 0L + + /** Set when symbol has a modifier of the form private[X], NoSymbol otherwise. + */ + def privateWithin: Symbol + + /** The raw info of the type + */ + def rawInfo: Type + + /** The type of the symbol + */ + def tpe: Type = info + + /** The info of the symbol. This is like tpe, except for class symbols where the `info` + * describes the contents of the class whereas the `tpe` is a reference to the class. + */ + def info: Type = { + val tp = rawInfo + tp.complete(this) + tp + } + + /** If this symbol is a class or trait, its self type, otherwise the type of the symbol itse;lf + */ + def typeOfThis: Type + + def owner_=(sym: Symbol) { throw new UnsupportedOperationException("owner_= inapplicable for " + this) } + def flags_=(flags: Long) { throw new UnsupportedOperationException("flags_= inapplicable for " + this) } + def info_=(tp: Type) { throw new UnsupportedOperationException("info_= inapplicable for " + this) } + def typeOfThis_=(tp: Type) { throw new UnsupportedOperationException("typeOfThis_= inapplicable for " + this) } + def privateWithin_=(sym: Symbol) { throw new UnsupportedOperationException("privateWithin_= inapplicable for " + this) } + def sourceModule_=(sym: Symbol) { throw new UnsupportedOperationException("sourceModule_= inapplicable for " + this) } + def addChild(sym: Symbol) { throw new UnsupportedOperationException("addChild inapplicable for " + this) } + def addAnnotation(annot: AnnotationInfo) { throw new UnsupportedOperationException("addAnnotation inapplicable for " + this) } + + /** For a module class its linked class, for a plain class + * the module class of its linked module. + * For instance + * object Foo + * class Foo + * + * Then object Foo has a `moduleClass' (invisible to the user, the backend calls it Foo$ + * linkedClassOfClass goes from class Foo$ to class Foo, and back. + */ + def linkedClassOfClass: Symbol + + /** The module corresponding to this module class (note that this + * is not updated when a module is cloned), or NoSymbol if this is not a ModuleClass + */ + def sourceModule: Symbol = NoSymbol + + /** If symbol is an object defition, it's implied associated class, + * otherwise NoSymbol + */ + def moduleClass: Symbol + +// flags and kind tests + + def isTerm = false // to be overridden + def isType = false // to be overridden + def isClass = false // to be overridden + def isAliasType = false //to be overridden + def isAbstractType = false //to be overridden + private[scala] def isSkolem = false // to be overridden + + final def isImplicit = hasFlag(IMPLICIT) + final def isFinal = hasFlag(FINAL) + final def isPrivate = hasFlag(PRIVATE) + final def isProtected = hasFlag(PROTECTED) + + /** Is this symbol a sealed class? */ + final def isSealed = isClass && (hasFlag(SEALED) || definitions.isValueClass(this)) + final def isOverride = hasFlag(OVERRIDE) + final def isCase = hasFlag(CASE) + final def isAbstractClass = isClass && hasFlag(ABSTRACT) + final def isAbstractOverride = isTerm && hasFlag(ABSTRACT) && hasFlag(OVERRIDE) + final def isDeferred = hasFlag(DEFERRED) && !isClass + final def isMethod = isTerm && hasFlag(METHOD) + final def isSourceMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD // exclude all accessors!!! + final def isModule = isTerm && hasFlag(MODULE) + final def isModuleClass = isClass && hasFlag(MODULE) + final def isInterface = hasFlag(INTERFACE) + final def isMutable = hasFlag(MUTABLE) + final def isParameter = hasFlag(PARAM) + final def isPackage = isModule && hasFlag(PACKAGE) + final def isPackageClass = isClass && hasFlag(PACKAGE) + final def isCovariant = isType && hasFlag(COVARIANT) + final def isContravariant = isType && hasFlag(CONTRAVARIANT) + final def isJavaDefined = hasFlag(JAVA) + final def isSynthetic = hasFlag(SYNTHETIC) + def isTrait: Boolean = isClass && hasFlag(TRAIT) // refined later for virtual classes. + final def hasDefault = isParameter && hasFlag(DEFAULTPARAM) + final def isBridge = hasFlag(BRIDGE) + final def isGetterOrSetter = hasFlag(ACCESSOR) + final def isSuperAccessor = hasFlag(SUPERACCESSOR) + final def isParamAccessor = hasFlag(PARAMACCESSOR) + final def isCaseAccessor = hasFlag(CASEACCESSOR) + final def isLazy = hasFlag(LAZY) + final def isExistentiallyBound = isType && hasFlag(EXISTENTIAL) + final def isTypeParameter = isType && isParameter && !isSkolem + final def isRefinementClass = isClass && name == mkTypeName(nme.REFINE_CLASS_NAME) + final def isOverloaded = hasFlag(OVERLOADED) + + /** Is this symbol an implementation class for a mixin? */ + final def isImplClass = isClass && hasFlag(IMPLCLASS) + + /** Is this symbol early initialized */ + final def isEarlyInitialized: Boolean = isTerm && hasFlag(PRESUPER) + + final def isPrivateLocal = hasFlag(PRIVATE) && hasFlag(LOCAL) + final def isProtectedLocal = hasFlag(PROTECTED) && hasFlag(LOCAL) + final def isPublic = !hasFlag(PRIVATE | PROTECTED) && privateWithin == NoSymbol + + final def isRoot = isPackageClass && owner == NoSymbol + final def isRootPackage = isPackage && owner == NoSymbol + final def isEmptyPackage = isPackage && name == nme.EMPTY_PACKAGE_NAME + final def isEmptyPackageClass = isPackageClass && name == mkTypeName(nme.EMPTY_PACKAGE_NAME) + + /** Is this symbol an effective root for fullname string? + */ + def isEffectiveRoot = isRoot || isEmptyPackageClass + + // creators + + def newValue(name: Name, pos: Position = NoPosition): Symbol + def newAbstractType(name: Name, pos: Position = NoPosition): Symbol + def newAliasType(name: Name, pos: Position = NoPosition): Symbol + def newClass(name: Name, pos: Position = NoPosition): Symbol + def newModuleClass(name: Name, pos: Position = NoPosition): Symbol + def newMethod(name: Name, pos: Position = NoPosition): Symbol + def newModule(name: Name, clazz: Symbol, pos: Position = NoPosition): Symbol + + // access to related symbols + + /** The next enclosing class */ + def enclClass: Symbol = if (isClass) this else owner.enclClass + + /** The next enclosing method */ + def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod + } + + val NoSymbol: Symbol +} + + diff --git a/src/library/scala/reflect/generic/Trees.scala b/src/library/scala/reflect/generic/Trees.scala new file mode 100755 index 0000000000..7ff3b54ab9 --- /dev/null +++ b/src/library/scala/reflect/generic/Trees.scala @@ -0,0 +1,609 @@ +package scala.reflect +package generic + +import java.io.{PrintWriter, StringWriter} +import Flags._ + +trait Trees { self: Universe => + + abstract class AbsTreePrinter(out: PrintWriter) { + def print(tree: Tree) + def flush() + } + + def newTreePrinter(out: PrintWriter): AbsTreePrinter + + private[scala] var nodeCount = 0 + + /** @param privateWithin the qualifier for a private (a type name) + * or nme.EMPTY.toTypeName, if none is given. + * @param annotations the annotations for the definition. + * <strong>Note:</strong> the typechecker drops these annotations, + * use the AnnotationInfo's (Symbol.annotations) in later phases. + */ + case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree], positions: Map[Long, Position]) { + def isCovariant = hasFlag(COVARIANT ) // marked with `+' + def isContravariant = hasFlag(CONTRAVARIANT) // marked with `-' + def isPrivate = hasFlag(PRIVATE ) + def isProtected = hasFlag(PROTECTED) + def isVariable = hasFlag(MUTABLE ) + def isArgument = hasFlag(PARAM ) + def isAccessor = hasFlag(ACCESSOR ) + def isOverride = hasFlag(OVERRIDE ) + def isAbstract = hasFlag(ABSTRACT ) + def isDeferred = hasFlag(DEFERRED ) + def isCase = hasFlag(CASE ) + def isLazy = hasFlag(LAZY ) + def isSealed = hasFlag(SEALED ) + def isFinal = hasFlag(FINAL ) + def isTrait = hasFlag(TRAIT ) + def isImplicit = hasFlag(IMPLICIT ) + def isPublic = !isPrivate && !isProtected + def hasFlag(flag: Long) = (flag & flags) != 0L + def & (flag: Long): Modifiers = { + val flags1 = flags & flag + if (flags1 == flags) this + else Modifiers(flags1, privateWithin, annotations, positions) + } + def &~ (flag: Long): Modifiers = { + val flags1 = flags & (~flag) + if (flags1 == flags) this + else Modifiers(flags1, privateWithin, annotations, positions) + } + def | (flag: Long): Modifiers = { + val flags1 = flags | flag + if (flags1 == flags) this + else Modifiers(flags1, privateWithin, annotations, positions) + } + def withAnnotations(annots: List[Tree]) = + if (annots.isEmpty) this + else Modifiers(flags, privateWithin, annotations ::: annots, positions) + def withPosition(flag: Long, position: Position) = + Modifiers(flags, privateWithin, annotations, positions + (flag -> position)) + } + + def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List(), new Map.EmptyMap) + def Modifiers(flags: Long): Modifiers = Modifiers(flags, mkTypeName(nme.EMPTY)) + + lazy val NoMods = Modifiers(0) + + abstract class Tree extends Product { + val id = nodeCount +// assert(id != 1223) + nodeCount += 1 + + private[this] var rawpos: Position = NoPosition + + def pos = rawpos + def pos_=(pos: Position) = rawpos = pos + def setPos(pos: Position): this.type = { rawpos = pos; this } + + private[this] var rawtpe: Type = _ + + def tpe = rawtpe + def tpe_=(t: Type) = rawtpe = t + + /** Set tpe to give `tp` and return this. + */ + def setType(tp: Type): this.type = { rawtpe = tp; this } + + /** Like `setType`, but if this is a previously empty TypeTree + * that fact is remembered so that resetType will snap back. + */ + def defineType(tp: Type): this.type = setType(tp) + + def symbol: Symbol = null + def symbol_=(sym: Symbol) { throw new UnsupportedOperationException("symbol_= inapplicable for " + this) } + def setSymbol(sym: Symbol): this.type = { symbol = sym; this } + + def hasSymbol = false + def isDef = false + def isEmpty = false + + /** The direct child trees of this tree + * EmptyTrees are always omitted. Lists are collapsed. + */ + def children: List[Tree] = { + def subtrees(x: Any): List[Tree] = x match { + case EmptyTree => List() + case t: Tree => List(t) + case xs: List[_] => xs flatMap subtrees + case _ => List() + } + productIterator.toList flatMap subtrees + } + + /** In compiler: Make a copy of this tree, keeping all attributes, + * except that all positions are focussed (so nothing + * in this tree will be found when searching by position). + * If not in compiler may also return tree unchanged. + */ + private[scala] def duplicate: this.type = + duplicateTree(this).asInstanceOf[this.type] + + private[scala] def copyAttrs(tree: Tree): this.type = { + pos = tree.pos + tpe = tree.tpe + if (hasSymbol) symbol = tree.symbol + this + } + + override def toString(): String = { + val buffer = new StringWriter() + val printer = newTreePrinter(new PrintWriter(buffer)) + printer.print(this) + printer.flush() + buffer.toString + } + + override def hashCode(): Int = super.hashCode() + + override def equals(that: Any): Boolean = that match { + case t: Tree => this eq t + case _ => false + } + } + + private[scala] def duplicateTree(tree: Tree): Tree = tree + + trait SymTree extends Tree { + override def hasSymbol = true + override var symbol: Symbol = NoSymbol + } + + trait RefTree extends SymTree { + def name: Name + } + + abstract class DefTree extends SymTree { + def name: Name + override def isDef = true + } + + trait TermTree extends Tree + + /** A tree for a type. Note that not all type trees implement + * this trait; in particular, Ident's are an exception. */ + trait TypTree extends Tree + +// ----- tree node alternatives -------------------------------------- + + /** The empty tree */ + case object EmptyTree extends TermTree { + super.tpe_=(NoType) + override def tpe_=(t: Type) = + if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>") + override def isEmpty = true + } + + abstract class MemberDef extends DefTree { + def mods: Modifiers + def keyword: String = this match { + case TypeDef(_, _, _, _) => "type" + case ClassDef(mods, _, _, _) => if (mods.isTrait) "trait" else "class" + case DefDef(_, _, _, _, _, _) => "def" + case ModuleDef(_, _, _) => "object" + case PackageDef(_, _) => "package" + case ValDef(mods, _, _, _) => if (mods.isVariable) "var" else "val" + case _ => "" + } + final def hasFlag(mask: Long): Boolean = (mods.flags & mask) != 0L + } + + /** Package clause + */ + case class PackageDef(pid: RefTree, stats: List[Tree]) + extends MemberDef { + def name = pid.name + def mods = NoMods + } + + abstract class ImplDef extends MemberDef { + def impl: Template + } + + /** Class definition */ + case class ClassDef(mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) + extends ImplDef + + /** Singleton object definition + */ + case class ModuleDef(mods: Modifiers, name: Name, impl: Template) + extends ImplDef + + abstract class ValOrDefDef extends MemberDef { + def tpt: Tree + def rhs: Tree + } + + /** Value definition + */ + case class ValDef(mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) extends ValOrDefDef + + /** Method definition + */ + case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], + vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef + + /** Abstract type, type parameter, or type alias */ + case class TypeDef(mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) + extends MemberDef + + /** <p> + * Labelled expression - the symbols in the array (must be Idents!) + * are those the label takes as argument + * </p> + * <p> + * The symbol that is given to the labeldef should have a MethodType + * (as if it were a nested function) + * </p> + * <p> + * Jumps are apply nodes attributed with label symbol, the arguments + * will get assigned to the idents. + * </p> + * <p> + * Note: on 2005-06-09 Martin, Iuli, Burak agreed to have forward + * jumps within a Block. + * </p> + */ + case class LabelDef(name: Name, params: List[Ident], rhs: Tree) + extends DefTree with TermTree + + + /** Import selector + * + * Representation of an imported name its optional rename and their optional positions + * + * @param name the imported name + * @param namePos its position or -1 if undefined + * @param rename the name the import is renamed to (== name if no renaming) + * @param renamePos the position of the rename or -1 if undefined + */ + case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) + + /** Import clause + * + * @param expr + * @param selectors + */ + case class Import(expr: Tree, selectors: List[ImportSelector]) + extends SymTree + // The symbol of an Import is an import symbol @see Symbol.newImport + // It's used primarily as a marker to check that the import has been typechecked. + + /** Instantiation template of a class or trait + * + * @param parents + * @param body + */ + case class Template(parents: List[Tree], self: ValDef, body: List[Tree]) + extends SymTree { + // the symbol of a template is a local dummy. @see Symbol.newLocalDummy + // the owner of the local dummy is the enclosing trait or class. + // the local dummy is itself the owner of any local blocks + // For example: + // + // class C { + // def foo // owner is C + // { + // def bar // owner is local dummy + // } + // System.err.println("TEMPLATE: " + parents) + } + + /** Block of expressions (semicolon separated expressions) */ + case class Block(stats: List[Tree], expr: Tree) + extends TermTree + + /** Case clause in a pattern match, eliminated by TransMatch + * (except for occurences in switch statements) + */ + case class CaseDef(pat: Tree, guard: Tree, body: Tree) + extends Tree + + /** Alternatives of patterns, eliminated by TransMatch, except for + * occurences in encoded Switch stmt (=remaining Match(CaseDef(...)) + */ + case class Alternative(trees: List[Tree]) + extends TermTree + + /** Repetition of pattern, eliminated by TransMatch */ + case class Star(elem: Tree) + extends TermTree + + /** Bind of a variable to a rhs pattern, eliminated by TransMatch + * + * @param name + * @param body + */ + case class Bind(name: Name, body: Tree) + extends DefTree + + case class UnApply(fun: Tree, args: List[Tree]) + extends TermTree + + /** Array of expressions, needs to be translated in backend, + */ + case class ArrayValue(elemtpt: Tree, elems: List[Tree]) + extends TermTree + + /** Anonymous function, eliminated by analyzer */ + case class Function(vparams: List[ValDef], body: Tree) + extends TermTree with SymTree + // The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME + // It is the owner of the function's parameters. + + /** Assignment */ + case class Assign(lhs: Tree, rhs: Tree) + extends TermTree + + /** Conditional expression */ + case class If(cond: Tree, thenp: Tree, elsep: Tree) + extends TermTree + + /** <p> + * Pattern matching expression (before <code>TransMatch</code>) + * Switch statements (after TransMatch) + * </p> + * <p> + * After <code>TransMatch</code>, cases will satisfy the following + * constraints: + * </p> + * <ul> + * <li>all guards are EmptyTree,</li> + * <li>all patterns will be either <code>Literal(Constant(x:Int))</code> + * or <code>Alternative(lit|...|lit)</code></li> + * <li>except for an "otherwise" branch, which has pattern + * <code>Ident(nme.WILDCARD)</code></li> + * </ul> + */ + case class Match(selector: Tree, cases: List[CaseDef]) + extends TermTree + + /** Return expression */ + case class Return(expr: Tree) + extends TermTree with SymTree + // The symbol of a Return node is the enclosing method. + + case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) + extends TermTree + + /** Throw expression */ + case class Throw(expr: Tree) + extends TermTree + + /** Object instantiation + * One should always use factory method below to build a user level new. + * + * @param tpt a class type + */ + case class New(tpt: Tree) extends TermTree + + /** Type annotation, eliminated by explicit outer */ + case class Typed(expr: Tree, tpt: Tree) + extends TermTree + + // Martin to Sean: Should GenericApply/TypeApply/Apply not be SymTree's? After all, + // ApplyDynamic is a SymTree. + abstract class GenericApply extends TermTree { + val fun: Tree + val args: List[Tree] + } + + /** Type application */ + case class TypeApply(fun: Tree, args: List[Tree]) + extends GenericApply { + override def symbol: Symbol = fun.symbol + override def symbol_=(sym: Symbol) { fun.symbol = sym } + } + + /** Value application */ + case class Apply(fun: Tree, args: List[Tree]) + extends GenericApply { + override def symbol: Symbol = fun.symbol + override def symbol_=(sym: Symbol) { fun.symbol = sym } + } + + /** Dynamic value application. + * In a dynamic application q.f(as) + * - q is stored in qual + * - as is stored in args + * - f is stored as the node's symbol field. + */ + case class ApplyDynamic(qual: Tree, args: List[Tree]) + extends TermTree with SymTree + // The symbol of an ApplyDynamic is the function symbol of `qual', or NoSymbol, if there is none. + + /** Super reference */ + case class Super(qual: Name, mix: Name) + extends TermTree with SymTree + // The symbol of a Super is the class _from_ which the super reference is made. + // For instance in C.super(...), it would be C. + + /** Self reference */ + case class This(qual: Name) + extends TermTree with SymTree + // The symbol of a This is the class to which the this refers. + // For instance in C.this, it would be C. + + /** Designator <qualifier> . <name> */ + case class Select(qualifier: Tree, name: Name) + extends RefTree + + /** Identifier <name> */ + case class Ident(name: Name) + extends RefTree + + class BackQuotedIdent(name: Name) extends Ident(name) + + /** Literal */ + case class Literal(value: Constant) + extends TermTree { + assert(value ne null) + } + + def Literal(value: Any): Literal = + Literal(Constant(value)) + + type TypeTree <: AbsTypeTree + val TypeTree: TypeTreeExtractor + + abstract class TypeTreeExtractor { + def apply(): TypeTree + def unapply(tree: TypeTree): Boolean + } + + /** A synthetic term holding an arbitrary type. Not to be confused with + * with TypTree, the trait for trees that are only used for type trees. + * TypeTree's are inserted in several places, but most notably in + * <code>RefCheck</code>, where the arbitrary type trees are all replaced by + * TypeTree's. */ + abstract class AbsTypeTree extends TypTree { + override def symbol = if (tpe == null) null else tpe.typeSymbol + override def isEmpty = (tpe eq null) || tpe == NoType + } + + /** A tree that has an annotation attached to it. Only used for annotated types and + * annotation ascriptions, annotations on definitions are stored in the Modifiers. + * Eliminated by typechecker (typedAnnotated), the annotations are then stored in + * an AnnotatedType. + */ + case class Annotated(annot: Tree, arg: Tree) extends Tree + + /** Singleton type, eliminated by RefCheck */ + case class SingletonTypeTree(ref: Tree) + extends TypTree + + /** Type selection <qualifier> # <name>, eliminated by RefCheck */ + case class SelectFromTypeTree(qualifier: Tree, name: Name) + extends TypTree with RefTree + + /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */ + case class CompoundTypeTree(templ: Template) + extends TypTree + + /** Applied type <tpt> [ <args> ], eliminated by RefCheck */ + case class AppliedTypeTree(tpt: Tree, args: List[Tree]) + extends TypTree { + override def symbol: Symbol = tpt.symbol + override def symbol_=(sym: Symbol) { tpt.symbol = sym } + } + + case class TypeBoundsTree(lo: Tree, hi: Tree) + extends TypTree + + case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree]) + extends TypTree + + /** Array selection <qualifier> . <name> only used during erasure */ + case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type) + extends TermTree with RefTree + +/* A standard pattern match + case EmptyTree => + case PackageDef(pid, stats) => + // package pid { stats } + case ClassDef(mods, name, tparams, impl) => + // mods class name [tparams] impl where impl = extends parents { defs } + case ModuleDef(mods, name, impl) => (eliminated by refcheck) + // mods object name impl where impl = extends parents { defs } + case ValDef(mods, name, tpt, rhs) => + // mods val name: tpt = rhs + // note missing type information is expressed by tpt = TypeTree() + case DefDef(mods, name, tparams, vparamss, tpt, rhs) => + // mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs + // note missing type information is expressed by tpt = TypeTree() + case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure) + // mods type name[tparams] = rhs + // mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree, + and DEFERRED is set in mods + case LabelDef(name, params, rhs) => + // used for tailcalls and like + // while/do are desugared to label defs as follows: + // while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ()) + // do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ()) + case Import(expr, selectors) => (eliminated by typecheck) + // import expr.{selectors} + // Selectors are a list of pairs of names (from, to). + // The last (and maybe only name) may be a nme.WILDCARD + // for instance + // import qual.{x, y => z, _} would be represented as + // Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null))) + case Template(parents, self, body) => + // extends parents { self => body } + // if self is missing it is represented as emptyValDef + case Block(stats, expr) => + // { stats; expr } + case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter) + // case pat if guard => body + case Alternative(trees) => (eliminated by transmatch/explicitouter) + // pat1 | ... | patn + case Star(elem) => (eliminated by transmatch/explicitouter) + // pat* + case Bind(name, body) => (eliminated by transmatch/explicitouter) + // name @ pat + case UnApply(fun: Tree, args) (introduced by typer, eliminated by transmatch/explicitouter) + // used for unapply's + case ArrayValue(elemtpt, trees) => (introduced by uncurry) + // used to pass arguments to vararg arguments + // for instance, printf("%s%d", foo, 42) is translated to after uncurry to: + // Apply( + // Ident("printf"), + // Literal("%s%d"), + // ArrayValue(<Any>, List(Ident("foo"), Literal(42)))) + case Function(vparams, body) => (eliminated by lambdaLift) + // vparams => body where vparams:List[ValDef] + case Assign(lhs, rhs) => + // lhs = rhs + case If(cond, thenp, elsep) => + // if (cond) thenp else elsep + case Match(selector, cases) => + // selector match { cases } + case Return(expr) => + // return expr + case Try(block, catches, finalizer) => + // try block catch { catches } finally finalizer where catches: List[CaseDef] + case Throw(expr) => + // throw expr + case New(tpt) => + // new tpt always in the context: (new tpt).<init>[targs](args) + case Typed(expr, tpt) => (eliminated by erasure) + // expr: tpt + case TypeApply(fun, args) => + // fun[args] + case Apply(fun, args) => + // fun(args) + // for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args) + case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup) + // fun(args) + case Super(qual, mix) => + // qual.super[mix] if qual and/or mix is empty, ther are nme.EMPTY.toTypeName + case This(qual) => + // qual.this + case Select(qualifier, selector) => + // qualifier.selector + case Ident(name) => + // name + // note: type checker converts idents that refer to enclosing fields or methods + // to selects; name ==> this.name + case Literal(value) => + // value + case TypeTree() => (introduced by refcheck) + // a type that's not written out, but given in the tpe attribute + case Annotated(annot, arg) => (eliminated by typer) + // arg @annot for types, arg: @annot for exprs + case SingletonTypeTree(ref) => (eliminated by uncurry) + // ref.type + case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry) + // qualifier # selector, a path-dependent type p.T is expressed as p.type # T + case CompoundTypeTree(templ: Template) => (eliminated by uncurry) + // parent1 with ... with parentN { refinement } + case AppliedTypeTree(tpt, args) => (eliminated by uncurry) + // tpt[args] + case TypeBoundsTree(lo, hi) => (eliminated by uncurry) + // >: lo <: hi + case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry) + // tpt forSome { whereClauses } + +*/ +} diff --git a/src/library/scala/reflect/generic/Types.scala b/src/library/scala/reflect/generic/Types.scala new file mode 100755 index 0000000000..a42e79a3fe --- /dev/null +++ b/src/library/scala/reflect/generic/Types.scala @@ -0,0 +1,156 @@ +package scala.reflect +package generic + +trait Types { self: Universe => + + abstract class AbsType { + def typeSymbol: Symbol + def decl(name: Name): Symbol + + /** Is this type completed (i.e. not a lazy type)? + */ + def isComplete: Boolean = true + + /** If this is a lazy type, assign a new type to `sym'. */ + def complete(sym: Symbol) {} + + /** Convert toString avoiding infinite recursions by cutting off + * after `maxTostringRecursions` recursion levels. Uses `safeToString` + * to produce a string on each level. + */ + override def toString: String = + if (tostringRecursions >= maxTostringRecursions) + "..." + else + try { + tostringRecursions += 1 + safeToString + } finally { + tostringRecursions -= 1 + } + + /** Metod to be implemented in subclasses. + * Converts this type to a string in calling toString for its parts. + */ + def safeToString: String = super.toString + } + + type Type >: Null <: AbsType + + val NoType: Type + val NoPrefix: Type + + type ThisType <: Type + val ThisType: ThisTypeExtractor + + type TypeRef <: Type + val TypeRef: TypeRefExtractor + + type SingleType <: Type + val SingleType: SingleTypeExtractor + + type SuperType <: Type + val SuperType: SuperTypeExtractor + + type TypeBounds <: Type + val TypeBounds: TypeBoundsExtractor + + type CompoundType <: Type + + type RefinedType <: CompoundType + val RefinedType: RefinedTypeExtractor + + type ClassInfoType <: CompoundType + val ClassInfoType: ClassInfoTypeExtractor + + type ConstantType <: Type + val ConstantType: ConstantTypeExtractor + + type MethodType <: Type + val MethodType: MethodTypeExtractor + + type PolyType <: Type + val PolyType: PolyTypeExtractor + + type ExistentialType <: Type + val ExistentialType: ExistentialTypeExtractor + + type AnnotatedType <: Type + val AnnotatedType: AnnotatedTypeExtractor + + type LazyType <: Type with AbsLazyType + + trait AbsLazyType extends AbsType { + override def isComplete: Boolean = false + override def complete(sym: Symbol) + override def safeToString = "<?>" + } + + abstract class ThisTypeExtractor { + def apply(sym: Symbol): Type + def unapply(tpe: ThisType): Option[Symbol] + } + + abstract class SingleTypeExtractor { + def apply(pre: Type, sym: Symbol): Type + def unapply(tpe: SingleType): Option[(Type, Symbol)] + } + + abstract class SuperTypeExtractor { + def apply(thistpe: Type, supertpe: Type): Type + def unapply(tpe: SuperType): Option[(Type, Type)] + } + + abstract class TypeRefExtractor { + def apply(pre: Type, sym: Symbol, args: List[Type]): Type + def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] + } + + abstract class TypeBoundsExtractor { + def apply(lo: Type, hi: Type): TypeBounds + def unapply(tpe: TypeBounds): Option[(Type, Type)] + } + + abstract class RefinedTypeExtractor { + def apply(parents: List[Type], decls: Scope): RefinedType + def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType + def unapply(tpe: RefinedType): Option[(List[Type], Scope)] + } + + abstract class ClassInfoTypeExtractor { + def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType + def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] + } + + abstract class ConstantTypeExtractor { + def apply(value: Constant): ConstantType + def unapply(tpe: ConstantType): Option[Constant] + } + + abstract class MethodTypeExtractor { + def apply(params: List[Symbol], resultType: Type): MethodType + def unapply(tpe: MethodType): Option[(List[Symbol], Type)] + } + + abstract class PolyTypeExtractor { + def apply(typeParams: List[Symbol], resultType: Type): PolyType + def unapply(tpe: PolyType): Option[(List[Symbol], Type)] + } + + abstract class ExistentialTypeExtractor { + def apply(quantified: List[Symbol], underlying: Type): ExistentialType + def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] + } + + abstract class AnnotatedTypeExtractor { + def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType + def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] + } + + /** The maximum number of recursions allowed in toString + */ + final val maxTostringRecursions = 50 + + private var tostringRecursions = 0 +} + diff --git a/src/library/scala/reflect/generic/UnPickler.scala b/src/library/scala/reflect/generic/UnPickler.scala new file mode 100755 index 0000000000..3f2c8800e3 --- /dev/null +++ b/src/library/scala/reflect/generic/UnPickler.scala @@ -0,0 +1,773 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Martin Odersky + */ +// $Id: UnPickler.scala 20716 2010-01-28 14:14:20Z rytz $ + +package scala.reflect +package generic + +import java.io.IOException +import java.lang.{Float, Double} + +import Flags._ +import PickleFormat._ +import collection.mutable.{HashMap, ListBuffer} +import annotation.switch + +/** @author Martin Odersky + * @version 1.0 + */ +abstract class UnPickler { + + val global: Universe + import global._ + + /** Unpickle symbol table information descending from a class and/or module root + * from an array of bytes. + * @param bytes bytearray from which we unpickle + * @param offset offset from which unpickling starts + * @param classroot the top-level class which is unpickled, or NoSymbol if unapplicable + * @param moduleroot the top-level module which is unpickled, or NoSymbol if unapplicable + * @param filename filename associated with bytearray, only used for error messages + */ + def unpickle(bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String) { + try { + scan(bytes, offset, classRoot, moduleRoot, filename) + } catch { + case ex: IOException => + throw ex + case ex: Throwable => + /*if (settings.debug.value)*/ ex.printStackTrace() + throw new RuntimeException("error reading Scala signature of "+filename+": "+ex.getMessage()) + } + } + + def scan(bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String) + + abstract class Scan(bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String) extends PickleBuffer(bytes, offset, -1) { + //println("unpickle " + classRoot + " and " + moduleRoot)//debug + + protected def debug = false + + checkVersion() + + /** A map from entry numbers to array offsets */ + private val index = createIndex + + /** A map from entry numbers to symbols, types, or annotations */ + private val entries = new Array[AnyRef](index.length) + + /** A map from symbols to their associated `decls' scopes */ + private val symScopes = new HashMap[Symbol, Scope] + + //println("unpickled " + classRoot + ":" + classRoot.rawInfo + ", " + moduleRoot + ":" + moduleRoot.rawInfo);//debug + + def run() { + for (i <- 0 until index.length) { + if (isSymbolEntry(i)) + at(i, readSymbol) + else if (isSymbolAnnotationEntry(i)) + at(i, {() => readSymbolAnnotation(); null}) + else if (isChildrenEntry(i)) + at(i, {() => readChildren(); null}) + } + } + + private def checkVersion() { + val major = readNat() + val minor = readNat() + if (major != MajorVersion || minor > MinorVersion) + throw new IOException("Scala signature " + classRoot.decodedName + + " has wrong version\n expected: " + + MajorVersion + "." + MinorVersion + + "\n found: " + major + "." + minor + + " in "+filename) + } + + /** The `decls' scope associated with given symbol */ + protected def symScope(sym: Symbol) = symScopes.get(sym) match { + case None => val s = newScope; symScopes(sym) = s; s + case Some(s) => s + } + + /** Does entry represent an (internal) symbol */ + protected def isSymbolEntry(i: Int): Boolean = { + val tag = bytes(index(i)).toInt + (firstSymTag <= tag && tag <= lastSymTag && + (tag != CLASSsym || !isRefinementSymbolEntry(i))) + } + + /** Does entry represent an (internal or external) symbol */ + protected def isSymbolRef(i: Int): Boolean = { + val tag = bytes(index(i)) + (firstSymTag <= tag && tag <= lastExtSymTag) + } + + /** Does entry represent a name? */ + protected def isNameEntry(i: Int): Boolean = { + val tag = bytes(index(i)).toInt + tag == TERMname || tag == TYPEname + } + + /** Does entry represent a symbol annotation? */ + protected def isSymbolAnnotationEntry(i: Int): Boolean = { + val tag = bytes(index(i)).toInt + tag == SYMANNOT + } + + /** Does the entry represent children of a symbol? */ + protected def isChildrenEntry(i: Int): Boolean = { + val tag = bytes(index(i)).toInt + tag == CHILDREN + } + + /** Does entry represent a refinement symbol? + * pre: Entry is a class symbol + */ + protected def isRefinementSymbolEntry(i: Int): Boolean = { + val savedIndex = readIndex + readIndex = index(i) + val tag = readByte().toInt + assert(tag == CLASSsym) + + readNat(); // read length + val result = readNameRef() == mkTypeName(nme.REFINE_CLASS_NAME) + readIndex = savedIndex + result + } + + /** If entry at <code>i</code> is undefined, define it by performing + * operation <code>op</code> with <code>readIndex at start of i'th + * entry. Restore <code>readIndex</code> afterwards. + */ + protected def at[T <: AnyRef](i: Int, op: () => T): T = { + var r = entries(i) + if (r eq null) { + val savedIndex = readIndex + readIndex = index(i) + r = op() + assert(entries(i) eq null, entries(i)) + entries(i) = r + readIndex = savedIndex + } + r.asInstanceOf[T] + } + + /** Read a name */ + protected def readName(): Name = { + val tag = readByte() + val len = readNat() + tag match { + case TERMname => newTermName(bytes, readIndex, len) + case TYPEname => newTypeName(bytes, readIndex, len) + case _ => errorBadSignature("bad name tag: " + tag) + } + } + + /** Read a symbol */ + protected def readSymbol(): Symbol = { + val tag = readByte() + val end = readNat() + readIndex + var sym: Symbol = NoSymbol + tag match { + case EXTref | EXTMODCLASSref => + val name = readNameRef() + val owner = if (readIndex == end) definitions.RootClass else readSymbolRef() + def fromName(name: Name) = + if (mkTermName(name) == nme.ROOT) definitions.RootClass + else if (name == nme.ROOTPKG) definitions.RootPackage + else if (tag == EXTref) owner.info.decl(name) + else owner.info.decl(name).moduleClass + sym = fromName(name) + // If sym not found try with expanded name. + // This can happen if references to private symbols are + // read from outside; for instance when checking the children of a class + // (see t1722) + if (sym == NoSymbol) sym = fromName(nme.expandedName(name, owner)) + + // If the owner is overloaded (i.e. a method), it's not possible to select the + // right member => return NoSymbol. This can only happen when unpickling a tree. + // the "case Apply" in readTree() takes care of selecting the correct alternative + // after parsing the arguments. + if (sym == NoSymbol && !owner.isOverloaded) errorMissingRequirement(name, owner) + + case NONEsym => + sym = NoSymbol + + case _ => // symbols that were pickled with Pickler.writeSymInfo + var defaultGetter: Symbol = NoSymbol // @deprecated, to be removed for 2.8 final + var nameref = readNat() + if (tag == VALsym && isSymbolRef(nameref)) { // @deprecated, to be removed for 2.8 final + defaultGetter = at(nameref, readSymbol) + nameref = readNat() + } + val name = at(nameref, readName) + val owner = readSymbolRef() + val flags = pickledToRawFlags(readLongNat()) + var privateWithin: Symbol = NoSymbol + var inforef = readNat() + if (isSymbolRef(inforef)) { + privateWithin = at(inforef, readSymbol) + inforef = readNat() + } + tag match { + case TYPEsym => + sym = owner.newAbstractType(name) + case ALIASsym => + sym = owner.newAliasType(name) + case CLASSsym => + sym = + if (name == classRoot.name && owner == classRoot.owner) + (if ((flags & MODULE) != 0L) moduleRoot.moduleClass + else classRoot) + else + if ((flags & MODULE) != 0L) owner.newModuleClass(name) + else owner.newClass(name) + if (readIndex != end) sym.typeOfThis = newLazyTypeRef(readNat()) + case MODULEsym => + val clazz = at(inforef, readType).typeSymbol + sym = + if (name == moduleRoot.name && owner == moduleRoot.owner) moduleRoot + else { + val m = owner.newModule(name, clazz) + clazz.sourceModule = m + m + } + case VALsym => + sym = if (name == moduleRoot.name && owner == moduleRoot.owner) { assert(false); NoSymbol } + else if ((flags & METHOD) != 0) owner.newMethod(name) + else owner.newValue(name) + case _ => + noSuchSymbolTag(tag, end, name, owner) + } + sym.flags = flags & PickledFlags + sym.privateWithin = privateWithin + if (readIndex != end) assert(sym hasFlag (SUPERACCESSOR | PARAMACCESSOR), sym) + if (sym hasFlag SUPERACCESSOR) assert(readIndex != end) + sym.info = + if (readIndex != end) newLazyTypeRefAndAlias(inforef, readNat()) + else newLazyTypeRef(inforef) + if (sym.owner.isClass && sym != classRoot && sym != moduleRoot && + !sym.isModuleClass && !sym.isRefinementClass && !sym.isTypeParameter && !sym.isExistentiallyBound) + symScope(sym.owner) enter sym + } + sym + } + + def noSuchSymbolTag(tag: Int, end: Int, name: Name, owner: Symbol) = + errorBadSignature("bad symbol tag: " + tag) + + /** Read a type */ + protected def readType(): Type = { + val tag = readByte() + val end = readNat() + readIndex + (tag: @switch) match { + case NOtpe => + NoType + case NOPREFIXtpe => + NoPrefix + case THIStpe => + ThisType(readSymbolRef()) + case SINGLEtpe => + SingleType(readTypeRef(), readSymbolRef()) // !!! was singleType + case SUPERtpe => + val thistpe = readTypeRef() + val supertpe = readTypeRef() + SuperType(thistpe, supertpe) + case CONSTANTtpe => + ConstantType(readConstantRef()) + case TYPEREFtpe => + val pre = readTypeRef() + val sym = readSymbolRef() + var args = until(end, readTypeRef) + TypeRef(pre, sym, args) + case TYPEBOUNDStpe => + TypeBounds(readTypeRef(), readTypeRef()) + case REFINEDtpe => + val clazz = readSymbolRef() + RefinedType(until(end, readTypeRef), symScope(clazz), clazz) + case CLASSINFOtpe => + val clazz = readSymbolRef() + ClassInfoType(until(end, readTypeRef), symScope(clazz), clazz) + case METHODtpe | IMPLICITMETHODtpe => + val restpe = readTypeRef() + val params = until(end, readSymbolRef) + // if the method is overloaded, the params cannot be determined (see readSymbol) => return NoType. + // Only happen for trees, "case Apply" in readTree() takes care of selecting the correct + // alternative after parsing the arguments. + if (params.contains(NoSymbol) || restpe == NoType) NoType + else MethodType(params, restpe) + case POLYtpe => + val restpe = readTypeRef() + val typeParams = until(end, readSymbolRef) + PolyType(typeParams, restpe) + case EXISTENTIALtpe => + val restpe = readTypeRef() + ExistentialType(until(end, readSymbolRef), restpe) + case ANNOTATEDtpe => + var typeRef = readNat() + val selfsym = if (isSymbolRef(typeRef)) { + val s = at(typeRef, readSymbol) + typeRef = readNat() + s + } else NoSymbol // selfsym can go. + val tp = at(typeRef, readType) + val annots = until(end, readAnnotationRef) + if (selfsym == NoSymbol) AnnotatedType(annots, tp, selfsym) + else tp + case _ => + noSuchTypeTag(tag, end) + } + } + + def noSuchTypeTag(tag: Int, end: Int): Type = + errorBadSignature("bad type tag: " + tag) + + /** Read a constant */ + protected def readConstant(): Constant = { + val tag = readByte().toInt + val len = readNat() + (tag: @switch) match { + case LITERALunit => Constant(()) + case LITERALboolean => Constant(readLong(len) != 0L) + case LITERALbyte => Constant(readLong(len).toByte) + case LITERALshort => Constant(readLong(len).toShort) + case LITERALchar => Constant(readLong(len).toChar) + case LITERALint => Constant(readLong(len).toInt) + case LITERALlong => Constant(readLong(len)) + case LITERALfloat => Constant(Float.intBitsToFloat(readLong(len).toInt)) + case LITERALdouble => Constant(Double.longBitsToDouble(readLong(len))) + case LITERALstring => Constant(readNameRef().toString()) + case LITERALnull => Constant(null) + case LITERALclass => Constant(readTypeRef()) + case LITERALenum => Constant(readSymbolRef()) + case _ => noSuchConstantTag(tag, len) + } + } + + def noSuchConstantTag(tag: Int, len: Int): Constant = + errorBadSignature("bad constant tag: " + tag) + + /** Read children and store them into the corresponding symbol. + */ + protected def readChildren() { + val tag = readByte() + assert(tag == CHILDREN) + val end = readNat() + readIndex + val target = readSymbolRef() + while (readIndex != end) target addChild readSymbolRef() + } + + /** Read an annotation argument, which is pickled either + * as a Constant or a Tree. + */ + protected def readAnnotArg(i: Int): Tree = { + if (bytes(index(i)) == TREE) { + at(i, readTree) + } else { + val const = at(i, readConstant) + global.Literal(const).setType(const.tpe) + } + } + + /** Read a ClassfileAnnotArg (argument to a classfile annotation) + */ + protected def readClassfileAnnotArg(i: Int): ClassfileAnnotArg = bytes(index(i)) match { + case ANNOTINFO => + NestedAnnotArg(at(i, readAnnotation)) + case ANNOTARGARRAY => + at(i, () => { + readByte() // skip the `annotargarray` tag + val end = readNat() + readIndex + ArrayAnnotArg(until(end, () => readClassfileAnnotArg(readNat())).toArray(classfileAnnotArgManifest)) + }) + case _ => + LiteralAnnotArg(at(i, readConstant)) + } + + /** Read an AnnotationInfo. Not to be called directly, use + * readAnnotation or readSymbolAnnotation + */ + protected def readAnnotationInfo(end: Int): AnnotationInfo = { + val atp = readTypeRef() + val args = new ListBuffer[Tree] + val assocs = new ListBuffer[(Name, ClassfileAnnotArg)] + while (readIndex != end) { + val argref = readNat() + if (isNameEntry(argref)) { + val name = at(argref, readName) + val arg = readClassfileAnnotArg(readNat()) + assocs += ((name, arg)) + } + else + args += readAnnotArg(argref) + } + AnnotationInfo(atp, args.toList, assocs.toList) + } + + /** Read an annotation and as a side effect store it into + * the symbol it requests. Called at top-level, for all + * (symbol, annotInfo) entries. */ + protected def readSymbolAnnotation() { + val tag = readByte() + if (tag != SYMANNOT) + errorBadSignature("symbol annotation expected ("+ tag +")") + val end = readNat() + readIndex + val target = readSymbolRef() + target.addAnnotation(readAnnotationInfo(end)) + } + + /** Read an annotation and return it. Used when unpickling + * an ANNOTATED(WSELF)tpe or a NestedAnnotArg */ + protected def readAnnotation(): AnnotationInfo = { + val tag = readByte() + if (tag != ANNOTINFO) + errorBadSignature("annotation expected (" + tag + ")") + val end = readNat() + readIndex + readAnnotationInfo(end) + } + + /* Read an abstract syntax tree */ + protected def readTree(): Tree = { + val outerTag = readByte() + if (outerTag != TREE) + errorBadSignature("tree expected (" + outerTag + ")") + val end = readNat() + readIndex + val tag = readByte() + val tpe = if (tag == EMPTYtree) NoType else readTypeRef() + + // Set by the three functions to follow. If symbol is non-null + // after the the new tree 't' has been created, t has its Symbol + // set to symbol; and it always has its Type set to tpe. + var symbol: Symbol = null + var mods: Modifiers = null + var name: Name = null + + /** Read a Symbol, Modifiers, and a Name */ + def setSymModsName() { + symbol = readSymbolRef() + mods = readModifiersRef() + name = readNameRef() + } + /** Read a Symbol and a Name */ + def setSymName() { + symbol = readSymbolRef() + name = readNameRef() + } + /** Read a Symbol */ + def setSym() { + symbol = readSymbolRef() + } + + val t = tag match { + case EMPTYtree => + EmptyTree + + case PACKAGEtree => + setSym() + // val discardedSymbol = readSymbolRef() // XXX is symbol intentionally not set? + val pid = readTreeRef().asInstanceOf[RefTree] + val stats = until(end, readTreeRef) + PackageDef(pid, stats) + + case CLASStree => + setSymModsName() + val impl = readTemplateRef() + val tparams = until(end, readTypeDefRef) + ClassDef(mods, name, tparams, impl) + + case MODULEtree => + setSymModsName() + ModuleDef(mods, name, readTemplateRef()) + + case VALDEFtree => + setSymModsName() + val tpt = readTreeRef() + val rhs = readTreeRef() + ValDef(mods, name, tpt, rhs) + + case DEFDEFtree => + setSymModsName() + val tparams = times(readNat(), readTypeDefRef) + val vparamss = times(readNat(), () => times(readNat(), readValDefRef)) + val tpt = readTreeRef() + val rhs = readTreeRef() + + DefDef(mods, name, tparams, vparamss, tpt, rhs) + + case TYPEDEFtree => + setSymModsName() + val rhs = readTreeRef() + val tparams = until(end, readTypeDefRef) + TypeDef(mods, name, tparams, rhs) + + case LABELtree => + setSymName() + val rhs = readTreeRef() + val params = until(end, readIdentRef) + LabelDef(name, params, rhs) + + case IMPORTtree => + setSym() + val expr = readTreeRef() + val selectors = until(end, () => { + val from = readNameRef() + val to = readNameRef() + ImportSelector(from, -1, to, -1) + }) + + Import(expr, selectors) + + case TEMPLATEtree => + setSym() + val parents = times(readNat(), readTreeRef) + val self = readValDefRef() + val body = until(end, readTreeRef) + + Template(parents, self, body) + + case BLOCKtree => + val expr = readTreeRef() + val stats = until(end, readTreeRef) + Block(stats, expr) + + case CASEtree => + val pat = readTreeRef() + val guard = readTreeRef() + val body = readTreeRef() + CaseDef(pat, guard, body) + + case ALTERNATIVEtree => + Alternative(until(end, readTreeRef)) + + case STARtree => + Star(readTreeRef()) + + case BINDtree => + setSymName() + Bind(name, readTreeRef()) + + case UNAPPLYtree => + val fun = readTreeRef() + val args = until(end, readTreeRef) + UnApply(fun, args) + + case ARRAYVALUEtree => + val elemtpt = readTreeRef() + val trees = until(end, readTreeRef) + ArrayValue(elemtpt, trees) + + case FUNCTIONtree => + setSym() + val body = readTreeRef() + val vparams = until(end, readValDefRef) + Function(vparams, body) + + case ASSIGNtree => + val lhs = readTreeRef() + val rhs = readTreeRef() + Assign(lhs, rhs) + + case IFtree => + val cond = readTreeRef() + val thenp = readTreeRef() + val elsep = readTreeRef() + If(cond, thenp, elsep) + + case MATCHtree => + val selector = readTreeRef() + val cases = until(end, readCaseDefRef) + Match(selector, cases) + + case RETURNtree => + setSym() + Return(readTreeRef()) + + case TREtree => + val block = readTreeRef() + val finalizer = readTreeRef() + val catches = until(end, readCaseDefRef) + Try(block, catches, finalizer) + + case THROWtree => + Throw(readTreeRef()) + + case NEWtree => + New(readTreeRef()) + + case TYPEDtree => + val expr = readTreeRef() + val tpt = readTreeRef() + Typed(expr, tpt) + + case TYPEAPPLYtree => + val fun = readTreeRef() + val args = until(end, readTreeRef) + TypeApply(fun, args) + + case APPLYtree => + val fun = readTreeRef() + val args = until(end, readTreeRef) + if (fun.symbol.isOverloaded) { + fun.setType(fun.symbol.info) + inferMethodAlternative(fun, args map (_.tpe), tpe) + } + Apply(fun, args) + + case APPLYDYNAMICtree => + setSym() + val qual = readTreeRef() + val args = until(end, readTreeRef) + ApplyDynamic(qual, args) + + case SUPERtree => + setSym() + val qual = readNameRef() + val mix = readNameRef() + Super(qual, mix) + + case THIStree => + setSym() + This(readNameRef()) + + case SELECTtree => + setSym() + val qualifier = readTreeRef() + val selector = readNameRef() + Select(qualifier, selector) + + case IDENTtree => + setSymName() + Ident(name) + + case LITERALtree => + global.Literal(readConstantRef()) + + case TYPEtree => + TypeTree() + + case ANNOTATEDtree => + val annot = readTreeRef() + val arg = readTreeRef() + Annotated(annot, arg) + + case SINGLETONTYPEtree => + SingletonTypeTree(readTreeRef()) + + case SELECTFROMTYPEtree => + val qualifier = readTreeRef() + val selector = readNameRef() + SelectFromTypeTree(qualifier, selector) + + case COMPOUNDTYPEtree => + CompoundTypeTree(readTemplateRef()) + + case APPLIEDTYPEtree => + val tpt = readTreeRef() + val args = until(end, readTreeRef) + AppliedTypeTree(tpt, args) + + case TYPEBOUNDStree => + val lo = readTreeRef() + val hi = readTreeRef() + TypeBoundsTree(lo, hi) + + case EXISTENTIALTYPEtree => + val tpt = readTreeRef() + val whereClauses = until(end, readTreeRef) + ExistentialTypeTree(tpt, whereClauses) + + case _ => + noSuchTreeTag(tag, end) + } + + if (symbol == null) t setType tpe + else t setSymbol symbol setType tpe + } + + def noSuchTreeTag(tag: Int, end: Int) = + errorBadSignature("unknown tree type (" + tag + ")") + + def readModifiers(): Modifiers = { + val tag = readNat() + if (tag != MODIFIERS) + errorBadSignature("expected a modifiers tag (" + tag + ")") + val end = readNat() + readIndex + val pflagsHi = readNat() + val pflagsLo = readNat() + val pflags = (pflagsHi.toLong << 32) + pflagsLo + val flags = pickledToRawFlags(pflags) + val privateWithin = readNameRef() + Modifiers(flags, privateWithin, Nil, new Map.EmptyMap) + } + + /* Read a reference to a pickled item */ + protected def readNameRef(): Name = at(readNat(), readName) + protected def readSymbolRef(): Symbol = at(readNat(), readSymbol) + protected def readTypeRef(): Type = at(readNat(), readType) + protected def readConstantRef(): Constant = at(readNat(), readConstant) + protected def readAnnotationRef(): AnnotationInfo = + at(readNat(), readAnnotation) + protected def readModifiersRef(): Modifiers = + at(readNat(), readModifiers) + protected def readTreeRef(): Tree = + at(readNat(), readTree) + + protected def readTemplateRef(): Template = + readTreeRef() match { + case templ:Template => templ + case other => + errorBadSignature("expected a template (" + other + ")") + } + protected def readCaseDefRef(): CaseDef = + readTreeRef() match { + case tree:CaseDef => tree + case other => + errorBadSignature("expected a case def (" + other + ")") + } + protected def readValDefRef(): ValDef = + readTreeRef() match { + case tree:ValDef => tree + case other => + errorBadSignature("expected a ValDef (" + other + ")") + } + protected def readIdentRef(): Ident = + readTreeRef() match { + case tree:Ident => tree + case other => + errorBadSignature("expected an Ident (" + other + ")") + } + protected def readTypeDefRef(): TypeDef = + readTreeRef() match { + case tree:TypeDef => tree + case other => + errorBadSignature("expected an TypeDef (" + other + ")") + } + + protected def errorBadSignature(msg: String) = + throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg) + + protected def errorMissingRequirement(msg: String): Nothing = + if (debug) errorBadSignature(msg) + else throw new IOException("class file needed by "+classRoot.name+" is missing.\n"+msg) + + protected def errorMissingRequirement(name: Name, owner: Symbol): Nothing = + errorMissingRequirement("reference " + NameTransformer.decode(name.toString) + " of " + owner.tpe + " refers to nonexisting symbol.") + + /** pre: `fun` points to a symbol with an overloaded type. + * Selects the overloaded alternative of `fun` which best matches given + * argument types `argtpes` and result type `restpe`. Stores this alternative as + * the symbol of `fun`. + */ + def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) + + /** Create a lazy type which when completed returns type at index `i`. */ + def newLazyTypeRef(i: Int): LazyType + + /** Create a lazy type which when completed returns type at index `i` and sets alias + * of completed symbol to symbol at index `j` + */ + def newLazyTypeRefAndAlias(i: Int, j: Int): LazyType + } +} diff --git a/src/library/scala/reflect/generic/Universe.scala b/src/library/scala/reflect/generic/Universe.scala new file mode 100755 index 0000000000..101295ae79 --- /dev/null +++ b/src/library/scala/reflect/generic/Universe.scala @@ -0,0 +1,16 @@ +package scala.reflect +package generic + +abstract class Universe extends Symbols + with Types + with Constants + with Scopes + with Names + with StdNames + with Trees + with AnnotationInfos + with StandardDefinitions { + type Position + val NoPosition: Position +} + |