diff options
Diffstat (limited to 'src/attic')
-rw-r--r-- | src/attic/README | 2 | ||||
-rw-r--r-- | src/attic/scala/tools/nsc/models/Models.scala | 423 | ||||
-rw-r--r-- | src/attic/scala/tools/nsc/models/SemanticTokens.scala | 714 | ||||
-rw-r--r-- | src/attic/scala/tools/nsc/models/Signatures.scala | 86 | ||||
-rw-r--r-- | src/attic/scala/tools/nsc/symtab/SymbolWalker.scala | 253 |
5 files changed, 1478 insertions, 0 deletions
diff --git a/src/attic/README b/src/attic/README new file mode 100644 index 0000000000..9fb600ae57 --- /dev/null +++ b/src/attic/README @@ -0,0 +1,2 @@ +This is a holding area for source files which aren't used in +trunk anymore but which we're keeping available for a time.
\ No newline at end of file diff --git a/src/attic/scala/tools/nsc/models/Models.scala b/src/attic/scala/tools/nsc/models/Models.scala new file mode 100644 index 0000000000..a45d0d8877 --- /dev/null +++ b/src/attic/scala/tools/nsc/models/Models.scala @@ -0,0 +1,423 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Martin Odersky + */ +// $Id$ + +package scala.tools.nsc +package models + +import scala.tools.nsc.Global + +/** This abstract class ... + * + * @author Sean McDirmid + * @version 1.0 + */ +abstract class Models { + val global: Global + import global._ + + def acceptPrivate = true + + object Kinds extends Enumeration { + type Kind = Value + val CONSTRUCTOR = Value("Constructor") + val OBJECT = Value("Object") + val CLASS = Value("Class") + val TRAIT = Value("Trait") + val DEF = Value("Def") + val VAL = Value("Val") + val VAR = Value("Var") + val ARG = Value("Arg") + val TPARAM = Value("Type") + } + import Kinds._ + + def KINDS = List(CLASS, TRAIT, OBJECT, CONSTRUCTOR, TPARAM, VAL, VAR, DEF) + + def labelFor(kind: Kind): String = kind.toString + + def stringsFor(mods: Modifiers) = { + var modString: List[String] = Nil + if (mods.isPrivate ) modString = "private" :: modString + if (mods.isProtected) modString = "protected" :: modString + if (mods.isOverride ) modString = "override" :: modString + if (mods.isAbstract ) modString = "abstract" :: modString + if (mods.isDeferred ) modString = "abstract" :: modString + if (mods.isCase ) modString = "case" :: modString + if (mods.isSealed ) modString = "sealed" :: modString + if (mods.isFinal ) modString = "final" :: modString + if (mods.isImplicit ) modString = "implicit" :: modString + modString + } + + def codeFor(kind: Kind): String = kind match { + case CONSTRUCTOR => codeFor(DEF) + case _ => labelFor(kind).toLowerCase() + } + + def pluralFor(kind: Kind): String = kind match { + case CLASS => "Classes" + case _ => labelFor(kind) + "s" + } + + def kindOf(tree: Tree) = { + val term0 = tree.symbol; + if (term0 != NoSymbol) { + if (term0.isVariable) VAR + else if (term0.isValueParameter) ARG + else if (term0.isMethod) { + if (term0.nameString.equals("this")) CONSTRUCTOR + else DEF + } + else if (term0.isClass) { + if (tree.asInstanceOf[MemberDef].mods.isTrait) TRAIT + else CLASS + } + else if (term0.isModule) OBJECT + else if (term0.isValue) VAL + else if (term0.isTypeParameter) TPARAM + else if (term0.isType) TPARAM + else { + // Console.err.println("UNRECOGNIZED SYMBOL: " + term0 + " " + name); + null + } + } else { + val ddef = tree.asInstanceOf[ValOrDefDef]; + if (ddef.mods.hasFlag(symtab.Flags.MUTABLE)) VAR; + else VAL; + } + } + + abstract class Model + + // def textFor(tp : AbsTypeDef) : String = tp.toString() + + /** + * @param tree ... + * @return ... + */ + def textFor(tree: Tree): String = { + var ret = "" + if (tree.symbol != NoSymbol) tree.symbol.name.toString() + if (ret.equals("<init>")) ret = "this" + tree match { + case cdef: ClassDef => + ret = ret + "[" + + (for (tparam <- cdef.tparams) yield textFor(tparam)) + "]"; + cdef.mods + case vdef: ValOrDefDef => + vdef match { + case ddef: DefDef => + ret = ret + "[" + + (for (tparam <- ddef.tparams) yield textFor(tparam)) + "]"; + for (vparams <- ddef.vparamss) { + ret = ret + "(" + + (for (vparam <- vparams) yield textFor(vparam)) + ")"; + } + case _ => + } + ret = ret + " : " + textFor(vdef.tpt) +/* Martin to Sean: Please check whether this can be dropped or does it need to be adapted? + case atd: AbsTypeDef => + ret = ret + "[" + (for (tparam <- atd.tparams) yield textFor(tparam)) + "]" + + ((if(atd.hi ne null) " <: " + textFor(atd.hi) else "") + + (if(atd.lo ne null) " >: " + textFor(atd.lo) else "")); +*/ + case _ => + ret = ret + tree.toString() + } + ret + } + + def mods1(tree: Tree) = tree match { + case mdef: MemberDef => mdef.mods + case _ => NoMods + } + + abstract class HasTree(val parent: Composite) extends Model with Ordered[HasTree] { + var tree : Tree = _ + def update(tree0: Tree): Boolean = { + tree = tree0 + false + } + def replacedBy(tree0: Tree): Boolean = true + def text: String = textFor(tree) + var mods0 = NoMods + + def mods = if (mods0 != NoMods) mods0 else mods1(tree) + + override def toString(): String = tree.toString() + + def compare(that: HasTree): Int = { + val idx = KINDS.indexOf(kind) + val jdx = KINDS.indexOf(that.kind) + if (idx != jdx) return idx - jdx + val result = tree.symbol.nameString.compare(that.tree.symbol.nameString) + if (result != 0) result + else toString().compare(that.toString()) + } + def compare [b >: HasTree <% Ordered[b]](that: b): Int = { + if (that.isInstanceOf[HasTree]) + compare(that.asInstanceOf[HasTree]) + else -1 + } + + def kind = kindOf(tree) + + //override def add(from: Composite, model: HasTree): Unit = { parent.add(from, model) } + //override def remove(from: Composite, model: HasTree): Unit = { parent.remove(from, model) } + } + + class ImportMod(parent0: Composite) extends HasTree(parent0) { + def treex = tree.asInstanceOf[Import] + + override def replacedBy(tree0: Tree): Boolean = + if (super.replacedBy(tree0) && tree0.isInstanceOf[Import]) { + val tree1 = tree0.asInstanceOf[Import] + tree1.tpe == treex.tpe + } else + false + } + + class PackageMod(parent0: Composite) extends HasTree(parent0) { + def treex = tree.asInstanceOf[PackageDef] + } + + trait Composite extends Model { + import scala.collection.mutable._ + + class Members extends HashSet[HasTree] + // val members = new Members + object members extends Members + + def isMember(tree: Tree): Boolean = tree.isInstanceOf[Import] // imports welcome anywhere. + + def member(tree: Tree, members: List[Tree]): Tree = tree + + def update0(members1: List[Tree]): Boolean = { + // Console.err.println("update0 " + this + " " + members1) + // Martin: This is rather ugly code. We should use pattern matching here! + if (members1.length == 1 && members1.head.isInstanceOf[PackageDef]) + return update0(members1.head.asInstanceOf[PackageDef].stats) + val marked = new HashSet[HasTree] + var updated = false + for (mmbr1 <- members1) if (mmbr1.isInstanceOf[PackageDef]) { + Console.err.println("PACKAGE: " + mmbr1.symbol + " " + members1.length) + } else if (isMember(mmbr1)) { + val mmbr2 = member(mmbr1, members1) + if (mmbr2 ne null) { + var found = false + for (mmbr <- members) if (!found && mmbr.replacedBy(mmbr2)) { + //Console.err.println("REPLACE: " + mmbr + " with " + mmbr2) + mmbr.mods0 = mods1(mmbr1) + found = true + updated = mmbr.update(mmbr2) || updated + marked += mmbr + } + if (!found) { + updated = true + val add = modelFor(mmbr2, this) + add.update(mmbr2) + add.mods0 = mods1(mmbr1) & + ~symtab.Flags.ACCESSOR & ~symtab.Flags.SYNTHETIC + val sz = members.size + members += (add) + assert(members.size == sz + 1) + marked += add + } + } + // Console.err.println("update1 " + this + " " + members + " " + marked) + } + val sz = members.size + members.intersect(marked) + updated = updated || sz < members.size + // check if anything was removed! + updated + } + } + abstract class MemberMod(parent0: Composite) extends HasTree(parent0) { + def treex = tree.asInstanceOf[MemberDef] + + def name: Name = treex.name + + override def replacedBy(tree0: Tree): Boolean = + if (super.replacedBy(tree0) && tree0.isInstanceOf[MemberDef]) { + val tree1 = tree0.asInstanceOf[MemberDef] + treex.toString().equals(tree1.toString()) + } else false + + override def update(tree0: Tree): Boolean = { + val updated = (tree eq null) || (treex.mods != tree0.asInstanceOf[MemberDef].mods) + super.update(tree0) || updated; + } + } + + abstract class MemberComposite(parent0: Composite) extends MemberMod(parent0) with Composite + + trait HasClassObjects extends Composite { + override def isMember(tree: Tree): Boolean = + super.isMember(tree) || tree.isInstanceOf[ImplDef] + } + + abstract class ValOrDefMod(parent0: Composite) extends MemberComposite(parent0) with HasClassObjects { + def treey = tree.asInstanceOf[ValOrDefDef] + override def replacedBy(tree0: Tree): Boolean = + super.replacedBy(tree0) && tree0.isInstanceOf[ValOrDefDef] + + override def update(tree0: Tree): Boolean = { + val tree1 = tree0.asInstanceOf[ValOrDefDef] + val updated = (tree eq null) || treex.tpe != tree1.tpe + update0(flatten(tree1.rhs, (tree2: Tree) => isMember(tree2))) + super.update(tree0) || updated + } + } + + class ValMod(parent0: Composite) extends ValOrDefMod(parent0) { + def treez = tree.asInstanceOf[ValDef] + override def replacedBy(tree0: Tree): Boolean = + super.replacedBy(tree0) && tree0.isInstanceOf[ValDef] + } + + class DefMod(parent0: Composite) extends ValOrDefMod(parent0) { + def treez = tree.asInstanceOf[DefDef] + + override def replacedBy(tree0: Tree) : Boolean = + if (super.replacedBy(tree0) && tree0.isInstanceOf[DefDef]) { + val tree1 = tree0.asInstanceOf[DefDef] + if (tree1.vparamss.length == treez.vparamss.length) { + val tpz = for (vd <- treez.vparamss) yield for (xd <- vd) yield xd.tpe; + val tp1 = for (vd <- tree1.vparamss) yield for (xd <- vd) yield xd.tpe; + tpz == tp1 + } else false + } else false + } + + abstract class ImplMod(parent0: Composite) + extends MemberComposite(parent0) with HasClassObjects { + def treey = tree.asInstanceOf[ImplDef] + override def replacedBy(tree0: Tree): Boolean = + super.replacedBy(tree0) && tree0.isInstanceOf[ImplDef] + override def isMember(tree: Tree): Boolean = (super.isMember(tree) || + (tree.isInstanceOf[ValOrDefDef] && + (acceptPrivate || !tree.asInstanceOf[ValOrDefDef].mods.isPrivate) + /* && !tree.asInstanceOf[ValOrDefDef].mods.isPrivate */ + /* && !tree.asInstanceOf[ValOrDefDef].mods.isAccessor */) || + treeInfo.isAliasTypeDef(tree)) + + override def member(tree: Tree, members: List[Tree]): Tree = { + val tree0 = if (tree.isInstanceOf[DefDef]) { + val ddef = tree.asInstanceOf[DefDef] + ddef.mods + if (ddef.mods.isAccessor && (ddef.symbol ne null)) { + val sym0 = ddef.symbol; + if (sym0.isSetter) return null; + assert(sym0.isGetter); + val sym = sym0.accessed + val ret = if (sym == NoSymbol) { + val sym = analyzer.underlying(sym0) + //val name = nme.getterToSetter(sym0.name) + //val setter = sym0.owner.info.decl(name); + val isVar = sym.isVariable; + val mods = (ddef.mods | + (if (isVar) symtab.Flags.MUTABLE else 0) | symtab.Flags.DEFERRED) & + ~symtab.Flags.ACCESSOR & ~symtab.Flags.SYNTHETIC + val tree = + ValDef(mods, ddef.name, ddef.tpt, ddef.rhs).setPos(ddef.pos).setSymbol(sym); + tree :: Nil; + } else for (member <- members if member.symbol == sym) yield member + if (ret.isEmpty) null + else ret.head + } else tree + } else super.member(tree, members) + + def sym = tree0.symbol + if ((tree0 eq null) || tree0.pos == NoPosition) null + else if (!acceptPrivate && + tree0.isInstanceOf[ValOrDefDef] && + tree.asInstanceOf[ValOrDefDef].mods.isPrivate) null + else tree0 + } + + def children(tree0: Tree): List[Tree] = + tree0.asInstanceOf[ImplDef].impl.body + + override def update(tree0: Tree): Boolean = { + var updated = update0(children(tree0)) + super.update(tree0) || updated + } + } + + class ClassMod(parent0: Composite) extends ImplMod(parent0) { + def treez = tree.asInstanceOf[ClassDef] + override def replacedBy(tree0: Tree): Boolean = + super.replacedBy(tree0) && tree0.isInstanceOf[ClassDef] + } + + class ObjectMod(parent0: Composite) extends ImplMod(parent0) { + def treez = tree.asInstanceOf[ModuleDef] + override def replacedBy(tree0: Tree): Boolean = + super.replacedBy(tree0) && tree0.isInstanceOf[ModuleDef] + } + class TypeMod(parent0: Composite) extends MemberMod(parent0) { + def treey = tree.asInstanceOf[TypeDef]; + override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[TypeDef]); + } + def SourceMod(original: CompilationUnit) = new SourceMod(original) + + class SourceMod(val original: CompilationUnit) extends Composite with HasClassObjects { + update(original) + //var listener : Listener = null; + def update(unit: CompilationUnit) = unit.body match { + case pdef: PackageDef => try { + update0(pdef.stats) + } catch { + case e: Error => members.clear; update0(pdef.stats) + } + case _ => + } + + override def isMember(tree: Tree): Boolean = + super.isMember(tree) || tree.isInstanceOf[Import] + } + + def flatten0(exprs: List[Tree], filter: (Tree) => Boolean): List[Tree] = + for (expr <- exprs; t: Tree <- flatten(expr,filter)) yield t + + def flatten(expr: Tree, filter: (Tree) => Boolean): List[Tree] = + if (filter(expr)) expr :: Nil; else expr match { + case Block(stats, last) => + flatten0(stats, filter) ::: flatten(last, filter) + case If(cond, thenp, elsep) => + flatten(cond,filter) ::: flatten(thenp,filter) ::: flatten(elsep,filter); + case Assign(lhs, rhs) => + flatten(rhs, filter) + case CaseDef(pat, guard, body) => + flatten(body, filter) + case Return(expr0) => + flatten(expr0, filter) + case Throw(expr0) => + flatten(expr0,filter) + case Try(block, catches, finalizer) => + flatten(block, filter) ::: flatten(finalizer, filter) ::: flatten0(catches, filter) + case Match(selector, cases) => + flatten(selector, filter) ::: flatten0(cases, filter) + case Apply(fun, args) => + flatten(fun, filter) ::: flatten0(args, filter) + case TypeApply(fun, args) => + flatten(fun, filter) ::: flatten0(args, filter) + case _ => + Nil + } + + def modelFor(tree: Tree, parent: Composite): HasTree = tree match { + case _: ValDef => new ValMod(parent) + case _: DefDef => new DefMod(parent) + case _: ClassDef => new ClassMod(parent) + case _: ModuleDef => new ObjectMod(parent) + case _: TypeDef => new TypeMod(parent) + case _: Import => new ImportMod(parent) + } + +} diff --git a/src/attic/scala/tools/nsc/models/SemanticTokens.scala b/src/attic/scala/tools/nsc/models/SemanticTokens.scala new file mode 100644 index 0000000000..4da23b358b --- /dev/null +++ b/src/attic/scala/tools/nsc/models/SemanticTokens.scala @@ -0,0 +1,714 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Martin Odersky + */ +// $Id$ + +package scala.tools.nsc +package models + +import java.lang.Character.isJavaIdentifierPart +import java.lang.Thread + +import scala.collection.mutable.{HashMap, HashSet} +import scala.tools.nsc.Global +import scala.tools.nsc.symtab.{Flags, Names} +import scala.tools.nsc.symtab.Flags.DEFERRED +import scala.tools.nsc.util.{BatchSourceFile, SourceFile} +import scala.reflect.NameTransformer + +class SemanticTokens(val compiler: Global) { + import compiler._ + object walker extends symtab.SymbolWalker { + lazy val global : compiler.type = compiler + } + + abstract class Kind {} + object OBJECT extends Kind + object CLASS extends Kind + object TRAIT extends Kind + object DEF extends Kind + object VAL extends Kind + object VAR extends Kind + object ARG extends Kind + object TPARAM extends Kind + + type AnyClass = Class[_] + + // static constants here + + abstract class Token { + def length: Int + def prev: HasNext + def next: HasPrev + } + + def eatKeyword(source: BatchSourceFile, pos: Int, keywords: List[String]) : Int = { + if (keywords.isEmpty) + pos + else if (pos == source.length) + -1 + else if (source.beginsWith(pos, " ")) + eatKeywords(source, pos + 1) + else if (source.beginsWith(pos, keywords.head + " ")) + eatKeywords(source, pos + keywords.head.length + 1) + else + eatKeyword(source, pos, keywords.tail) + } + + def eatKeywords(source: BatchSourceFile, pos: Int): Int = { + val keywords = + "package" :: "val" :: "var" :: "def" :: "class" :: "trait" :: "override" :: "case" :: + "object" :: "sealed" :: "private" :: "protected" :: Nil + if (pos != -1) eatKeyword(source, pos, keywords) + else pos + } + + trait HasNext extends Token { + var next0: HasPrev = _ + def next = next0 + } + + trait HasPrev extends Token { + var prev0: HasNext = _ + def prev = prev0 + } + + abstract class Actual extends HasNext with HasPrev { + def convertToGap: (Int, Actual) = { + val nextGap = next.isInstanceOf[Gap] + val prevGap = prev.isInstanceOf[Gap] + + if (prevGap) { + val ret = prev.length + val gap = prev.asInstanceOf[Gap] + gap.setLength(gap.length + length) + if (nextGap) { + gap.setLength(gap.length + next.length) + gap.next0 = next.next + next.next.prev0 = gap + } else { + gap.next0 = next + next.prev0 = gap + } + (ret, gap) + } + else if (nextGap) { + val gap = next.asInstanceOf[Gap] + gap.setLength(gap.length + length) + gap.prev0 = prev + prev.next0 = gap + (0, gap) + } + else { + prev.next0 = next + next.prev0 = prev + val gap = new Gap(prev) + gap.setLength(length) + (0, gap) + } + + } + def insert(prev1: HasNext) { + next0 = prev1.next + prev0 = prev1 + prev0.next0 = this + next0.prev0 = this + } + + } // Actual + + final class Gap extends Actual { + def this(prev1: HasNext) = { + this() + insert(prev1) + } + override def toString() = "gap-" + length + + var length0: Int = -1 + def length: Int = length0 + def setLength(length1: Int) = length0 = length1 + + // already gap + override def convertToGap: (Int, Actual) = (0, this) + } + + def Process(unit: CompilationUnit) = new Process(unit) + class Process(val unit: CompilationUnit) { + private var doLog = true + def source = unit.source + + def dbg(tree: Tree) = { + def treePos: Position = if (tree ne null) tree.pos else NoPosition; + ( + "TREE=" + tree + + (if (tree ne null) (" CLASS=" + tree.getClass()) else "") + + " SYM=" + tree.symbol + + " POS=" + + treePos.dbgString + )} + + val symbols = new HashMap[Symbol, Info] + + class Info(val symbol: Symbol) { + var defined : Def = _ + val uses = new HashSet[Use] + symbols.update(symbol, this) + } + + def info(symbol: Symbol): Info = + if (symbols.contains(symbol)) symbols(symbol) + else new Info(symbol) + + abstract class Semantic(val symbol: Symbol) extends Actual { + val name = NameTransformer.decode(symbol.name.toString).trim() + assert(symbol != NoSymbol) + def myOuter = Process.this + + def tpe: Type = symbol.tpe + + def length = name.length() + def info: Info = if (symbols.contains(symbol)) symbols(symbol) else new Info(symbol) + + def kind = { + val term0 = symbol + if (false) null + else if (term0.isVariable) VAR + else if (term0.isValueParameter) ARG + else if (term0.isMethod) DEF + else if (term0.isClass) CLASS + else if (term0.isModule) OBJECT + else if (term0.isValue) VAL + else if (term0.isTypeParameter) TPARAM + else if (term0.isType ) TPARAM + else { + // Console.err.println("UNRECOGNIZED SYMBOL: " + term0 + " " + name); + null + } + } + } + + class Def(symbol0: Symbol) extends Semantic(symbol0) { + info.defined = this + override def toString() = "def-" + name + "-" + symbol.getClass() + } + class Use(symbol0: Symbol, tpe0: Type) extends Semantic(symbol0) { + info.uses += this + + override def tpe : Type = if (tpe0 ne null) tpe0 else super.tpe; + override def toString() = "use-" + name + "-" + symbol.getClass(); + } + val list = new TokenList + + //build(unit.body) + val map = new scala.collection.mutable.LinkedHashMap[Int,Symbol] + map.clear // populate the map. + class visitor extends walker.Visitor { + def contains(pos : Position) = map.contains(pos.point) + def apply(pos : Position) = map(pos.point) + def update(pos : Position, sym : Symbol) : Unit = if (pos.isDefined) { + val offset = pos.point + map(offset) = sym + val isDef = pos.point == sym.pos.point + list.put(offset, (if (isDef) new Def(sym) else new Use(sym, NoType))); + } + } + walker.walk(unit.body, new visitor)(offset => unit.source.identifier(offset, compiler)) + + + // ok start building.... + def build[T <: Tree](trees: List[T]) { + for (tree <- trees) build(tree) + } + + def build(tree0: Tree): Unit = try { + /* if (tree0.pos != NoPosition) */ tree0 match { + case tree: ImplDef => + val pos = eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.point) + if (pos == -1) { + + } else buildDef(tree.symbol, eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.point)); + tree match { + case cdef: ClassDef => build(cdef.tparams) + case _ => ; + } + build(tree.impl.parents) + build(tree.impl.body) + case tree: ValOrDefDef => + if (!tree.symbol.hasFlag(Flags.ACCESSOR) || tree.symbol.hasFlag(DEFERRED)) { + // MO: I added !tree.symbol.hasFlag(DEFERRED) in a refactoring where + // getters now can be abstract whereas before they could not. + // Adding the condition thus keeps the old behavior. + // todo: review whether this is correct, or whether abstract getters should be included. + { + val pos : Int = if (tree.name.toString().equals("<init>")) -1 else + eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.point); + if (false) Console.err.println("VALDEF: tree=" + tree + " sym=" + tree.symbol + " pos0=" + + tree.symbol.pos + " alias=" + tree.symbol.alias + " pos1=" + + pos + " pos2=" + tree.pos.dbgString + " " + tree.symbol.hasFlag(Flags.SYNTHETIC)); + + if (pos != -1 && !tree.hasFlag(Flags.SYNTHETIC)) + buildDef(tree.symbol, pos); + } + + if (tree.isInstanceOf[DefDef]) { + val ddef = tree.asInstanceOf[DefDef]; + build(ddef.tparams); + + for (l0 <- ddef.vparamss; arg <- l0) { + val pos0 : Int = if (!unit.source.beginsWith(arg.pos.point, "val ")) arg.pos.point; + else unit.source.skipWhitespace(arg.pos.point + ("val ").length()); + buildDef(arg.symbol, pos0); + build(arg.tpt); + } + } + //TPT=scala.Iterator[DocGenerator.this.compiler0.CompilationUnit] 260 class scala.tools.nsc.ast.Trees$TypeTree scala.Iterator[DocGenerator.this.compiler0.CompilationUnit] class scala.tools.nsc.symtab.Types$$anon$5 + if ((tree.tpt eq null) || (tree.tpt.tpe eq null)) { + //Console.err.println("BAD: " + tree.tpt + " in " + tree); + } else { + //Console.err.println("TPT=" + tree.tpt + " " + tree.tpt.pos + " " + tree.tpt.getClass() + " " + tree.tpt.tpe + " " + tree.tpt.tpe.getClass() + " " + tree.tpt.tpe.getClass().getSuperclass()); + build(tree.tpt); + } + //Console.err.println("RHS: " + tree.rhs + " " + tree.rhs.getClass() + " " + tree.rhs.getClass().getSuperclass()); + build(tree.rhs); + } + case tree: PackageDef => + //Console.err.println("PACKAGE: " + tree.name); + if (false) { + val pos = eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.pointOrElse(-1)) + if (pos != -1) + buildDef(tree.symbol, pos) + } + build(tree.stats) + case tree: Function => + for (arg <- tree.vparams if arg.pos != NoPosition) { + val name = arg.name.toString().trim() + val pos: Int = + if (unit.source.beginsWith(arg.pos.pointOrElse(-1), "val ")) + unit.source.skipWhitespace(arg.pos.pointOrElse(-1) + ("val ").length()) + else if (unit.source.asInstanceOf[BatchSourceFile].content(arg.pos.point) == ':') { + var posx : Int = arg.pos.point + while (unit.source.asInstanceOf[BatchSourceFile].content(posx - 1).isWhitespace) posx = posx - 1 + posx - name.length() + } else arg.pos.point + buildDef(arg.symbol, pos) + build(arg.tpt) + } + build(tree.body) + case tree : TypeTree => + val treex = tree + val tree1 = if (tree.original ne null) tree.original else tree + def classes(clazz: AnyClass): List[AnyClass] = + if (clazz eq null) Nil + else clazz :: classes(clazz.getSuperclass()) + if (tree.original eq null) { + if (false) Console.err.println("NO_ORIGINAL: " + tree + " " + tree.tpe + " " + classes(tree.tpe.getClass())); + } + if (tree.tpe ne null) buildT(tree1, tree.tpe); + def buildT( tree : Tree, tpe : Type) : Unit = if (tree.pos != NoPosition) tpe match { + case tpe0 : TypeRef => tree match { + case apt : AppliedTypeTree => + buildUse(tpe.typeSymbol, apt.tpt.pos.pointOrElse(-1), tpe0); + //Console.err.println("APT: " + treex + " vs. " + treex.original); + //Console.err.println("APT: " + treex.pos + " vs. " + treex.original.pos + " " + unit.source.dbg(treex.original.pos)); + //Console.err.println("APT: " + apt.tpt + " sym0=" + apt.tpt.symbol + " sym1=" + tpe0.sym + " apt.args=" + apt.args + " tpe0.args=" + tpe0.args); + + buildTs (apt.args, tpe0.args); + case ident : Ident => buildUse(tpe0.sym, ident.pos.pointOrElse(-1), tpe0); + case select : Select => + if (select.symbol == NoSymbol) + try { + // build(select); + buildUse(tpe0.typeSymbol, selectPos(select), tpe0); + //Console.err.println("QUALIFIER: " + select.qualifier + " " + unit.source.dbg(select.qualifier.pos) + " " + tpe0.prefix + " " + tpe0.prefix.getClass() + " " + tpe0.prefix.getClass().getSuperclass() +" " + tpe0.prefix.widen + " " + tpe0.prefix.toLongString); + buildT(select.qualifier, tpe0.prefix); + } catch { + case e : Error => + Console.err.println("BUILD_SELECT: " + select + " @ " + tpe0 + " " + (select.pos).dbgString); + throw e; + } + case tpt : TypeTree => + if (tpt.symbol ne null) { + Console.err.println("SYM0 " + tpt.symbol + " " + (tpt.pos).dbgString); + buildUse(tpt.symbol, tpt.pos.pointOrElse(-1), tpe0); + } else if (tpe0.typeSymbol ne null) { + //Console.err.println("TYPE_SYM1 " + tpe0.symbol + " " + unit.source.dbg(tpt.pos)); + buildUse(tpe0.typeSymbol, tpt.pos.pointOrElse(-1), tpe0); + } else { + Console.err.println("UNKNOWN TPT0: " + (tpt.pos).dbgString + " tpt=" + tpt + " " + tpt.symbol + " tpe0="+ tpe0 + " " + tpe0.typeSymbol + " tpe0.args=" + tpe0.args); + } + case sft : SelectFromTypeTree => + build(sft.qualifier); // XXX: broken + if (false) Console.err.println("SFTT: " + sft + " sym=" + sft.symbol + " name=" + sft.name + " qual=" + sft.qualifier + " qual.sym=" + + sft.qualifier.symbol + + " qual.pos=" + (sft.qualifier.pos).dbgString + " symbol=" + sft.symbol + " type=" + tpe0 + + " type.sym=" + tpe0.typeSymbol); + case _ => Console.err.println("UNKNOWN TPT2: " + tree + " vs. " + tpe0 + " " + tree.getClass() + " " + (tree.pos).dbgString); + } + case tpe0 : MethodType => tree match { + case tpt: TypeTree => + if (tpt.original ne null) buildT(tpt.original, tpe); + else { + Console.err.println("UNKNOWN TPT3: " + tree + " vs. " + tpe0 + " " + (tree.pos).dbgString); + } + case ident : Ident => buildT(ident, tpe0.resultType); + case select : Select => buildT(select, tpe0.resultType); + case _ => Console.err.println("UNKNOWN TPE: " + tree + " vs. " + tpe0 + " " + tree.getClass()); + } + case tpe0 : RefinedType => tree match { + case cpt : CompoundTypeTree => + buildTs(cpt.templ.parents, tpe0.parents); + + case _ : TypeTree => + // Console.err.println("UNKNOWN TPE13: " + dbg(tree) + " tpe0=" + tpe0 + " " + tpe0.parents); + case _ => + if (false) Console.err.println("UNKNOWN TPE5: " + dbg(tree) + " tpe0=" + tpe0 + " " + tpe0.parents); + } + case tpe0 : ThisType => tree match { + case stt : SingletonTypeTree => stt.ref match { + case ths : This => build(ths); + + case _ => Console.err.println("UNKNOWN TPE11: " + tpe0 + " " + stt + " " + stt.ref + " " + stt.ref.getClass() + " " + (tree.pos).dbgString); + } + case tt : This => + case _ : Ident => + case _ : Select => + case tt : TypeTree => + if (false) Console.err.println("UNKNOWN TPE12: " + tpe0 + " " + tree + " " + tree.getClass() + " " + (tree.pos).dbgString); + case _ => + if (false) Console.err.println("UNKNOWN TPE10: " + tpe0 + " " + tree + " " + tree.getClass() + " " + (tree.pos).dbgString); + } + case tpe0 : SingleType => tree match { + case ident : Ident => buildUse(tpe0.sym, ident.pos.pointOrElse(-1), tpe0); + case select : Select => + buildUse(tpe0.termSymbol, selectPos(select), tpe0); + //Console.err.println("QUALIFIER-0: " + select.qualifier + " " + unit.source.dbg(select.qualifier.pos) + " " + tpe0.prefix + " " + tpe0.prefix.getClass() + " " + tpe0.prefix.getClass().getSuperclass() +" " + tpe0.prefix.widen + " " + tpe0.prefix.toLongString); + buildT(select.qualifier, tpe0.prefix); + + case _ => + if (false) Console.err.println("UNKNOWN TPE8: " + tree + " " + (tree.pos).dbgString + " TPE=" + tpe0 + " PRE=" + tpe0.pre + " SYM=" + tpe0.sym); + + } + case ctype : ConstantType => + case ErrorType => + case _ => { + if (false) Console.err.println("UNKNOWN TPE4: " + tree + " " + tpe + " " + tpe.getClass() + " " + (tree.pos).dbgString); + } + }; + def buildTs(trees : List[Tree], types : List[Type]): Unit = if (!trees.isEmpty && !types.isEmpty) { + buildT (trees.head, types.head); + buildTs(trees.tail, types.tail); + } else if (trees.isEmpty != types.isEmpty) { + if (false && doLog) { + Console.println("" + treex + " vs. " + treex.original); + if (treex.original ne null) + Console.println("" + treex.tpe + " vs. " + treex.original.tpe); + logError("Tree vs. Type mismatch: " + trees + " " + types + " " + (tree.pos).dbgString, null); + doLog = false; + } + }; +/* + Martin to Sean: I don't understand why AbsTypeDef is different from AliasTypeDef. + Why is the order reversed? Why two buildDefs for tree.symbol vs one for AliasTypeDef? + case tree: AbsTypeDef => + //Console.err.println("ABS: " + tree.symbol + " " + unit.source.dbg(tree.namePos) + " " + tree.pos.dbgString); + buildDef(tree.symbol, tree.namePos) + buildDef(tree.symbol, tree.pos.pointOrElse(-1)) + build(tree.tparams); //@M + build(tree.lo) + build(tree.hi) +*/ + case tree: Bind => + buildDef(tree.symbol, tree.pos.pointOrElse(-1)) + build(tree.body) + case tree: Ident => + buildUse(tree.symbol, tree.pos.pointOrElse(-1), tree.tpe) + case tree: Select => + try { + build(tree.qualifier) + } catch { + case e : Error => Console.err.println("SELECTQ: " + tree + " " + tree.qualifier + " " + (tree.qualifier.pos).dbgString); throw e; + } + try { + if (tree.pos.isDefined && tree.pos.point >= unit.source.length) { + if (false) Console.err.println("BAD_SELECT_QUALIFIER " + tree + " @ " + (tree.pos).dbgString); + + } else { + //Console.err.println("SELECT-0: " + tree.symbol + " " + tree.pos.dbgString + " " + (tree.pos - selectPos(tree))); + buildUse(tree.symbol, selectPos(tree), tree.tpe); + } + } catch { + case e : Error => Console.err.println("SELECTU: " + tree + " " + tree.symbol + " " + tree.pos.dbgString); throw e; + } + case tree: TypeApply => + //Console.err.println("TYPE_APPLY: " + tree + " " + tree.pos.dbgString); + if (!tree.args.isEmpty) { + //Console.err.println("ARGS: " + unit.source.dbg(tree.args0.head.pos)); + } + build(tree.fun) + build(tree.args) + case tree: Apply => + + build(tree.fun) + build(tree.args) + case tree: GenericApply => + + build(tree.fun) + build(tree.args) + case tree: Typed => + build(tree.expr) + build(tree.tpt) + case tree: Block => + if (false) { + if (!tree.stats.isEmpty) + Console.err.println("BLOCKS: " + tree.stats.head + " " + tree.stats.head.getClass()); + Console.err.println("BLOCKE: " + tree.expr + " " + tree.expr.getClass()) + } + build(tree.stats) + build(tree.expr) + case tree: CaseDef => + build(tree.pat) + build(tree.guard) + build(tree.body) + case tree : Assign => build(tree.lhs); build(tree.rhs); + case tree : If => build(tree.cond); build(tree.thenp); build(tree.elsep); + case tree : New => + //Console.err.println("NEW: " + tree.tpt + " " + tree.tpt.getClass()); + build(tree.tpt); + case tree : Match => build(tree.selector); build(tree.cases); + case tree : Return => build(tree.expr); + case tree : LabelDef => build(tree.rhs); + case tree : Throw => build(tree.expr); + case tree : Try => build(tree.block); build(tree.catches); build(tree.finalizer); + case tree : Alternative => build(tree.trees); + case tree : This => + + if (tree.symbol ne null) buildUse(tree.symbol, tree.pos.pointOrElse(-1), tree.tpe); + //Thread.dumpStack(); + case tree : TypeDef => + //Console.err.println("ALIAS: " + tree); + build(tree.rhs); build(tree.tparams); buildDef(tree.symbol, tree.pos.pointOrElse(-1)); + case tree : DocDef => build(tree.definition); + case tree: Import => build(tree.expr) + case tree: AppliedTypeTree => ; + case tree: Annotated => ; + case tree: SingletonTypeTree => ; + case tree: Super => ; + case tree: Literal => ; + case EmptyTree => ; + case _ => ; + Console.err.println("BAIL: " + (tree0.pos) + " " + tree0 + " " + tree0.getClass()); + } + } catch { + case t: Throwable => + logError("Error occured at " + (tree0.pos), t) + } + + def buildUse(term: Symbol, pos: Int, tpe: Type) = buildSym(term, pos, false, tpe) + def buildDef(term: Symbol, pos: Int) = buildSym(term, pos, true, null) + + def buildSym(term: Symbol, pos: Int, isDef: Boolean, tpe: Type): Unit = + if (term.hasFlag(Flags.ACCESSOR)) + buildSym(analyzer.underlying(term), pos, isDef, tpe) + else if (pos == -1) { + //Console.err.println("NOPOS: " + term) + //Thread.dumpStack() + } + else if (term != NoSymbol) { + val name = NameTransformer.decode(term.name.toString).trim() + val buf = unit.source.asInstanceOf[BatchSourceFile].content + val cs = name.toChars + var idx = 0 + if (cs.length + pos > buf.length) return + else while (idx < cs.length) { + if (buf(pos + idx) != cs(idx)) { + //Console.err.println("MISMATCH: " + name + "[" + idx + "] " + unit.source.dbg(pos)); + //Thread.dumpStack(); + return; + } + else idx = idx + 1; + } + if (cs.length + pos + 1 < buf.length) { + if (isJavaIdentifierPart(buf(pos + cs.length))) { + //Console.err.println("MISMATCH: " + name + "[last] " + unit.source.dbg(pos)); + return; + } + } + try { + list.put(pos, (if (isDef) new Def(term) else new Use(term, tpe))); + } catch { + case e : Error => e.printStackTrace(); + } + } + + def selectPos(tree: Select): Int = if (tree.pos == NoPosition) -1 else { + val buf = unit.source.asInstanceOf[BatchSourceFile].content + if (tree.pos.point >= buf.length) { + if (false) { + Console.err.println("" + tree + "@" + tree.pos + " not in " + + unit.source.file.name + "[" + buf.length + "]"); + Thread.dumpStack() + abort() + } + return 0 + } + + val pos : Int = + if (buf(tree.pos.point) != '.') tree.pos.point + else { + def f(x : Int) : Int = { + if (buf(x).isWhitespace) f(x + 1) + else x + } + f(tree.pos.point + 1) + } + pos + }; + + class TokenList { + object begin extends HasNext { + def prev = this + def length = 0 + } + object end extends HasPrev { + def next = this + def length = 0 + } + // initialize + begin.next0 = end + end.prev0 = begin + + def tokenAt(offset: Int) = { + cursor.seek(offset) + if (cursor.token.isInstanceOf[Semantic]) cursor.token.asInstanceOf[Semantic] + else null + } + + def put(offset: Int, tok: Actual): Unit = tok match { + case tok0: Semantic => put(offset, tok0) + case gap: Gap => + } + + def put(offset: Int, tok: Semantic) { + cursor.seek(offset); + if (cursor.token == end) { + assert(offset >= cursor.offset); + if (offset > cursor.offset) { + // add a gap. + val gap = new Gap(end.prev); + gap.setLength(offset - cursor.offset); + cursor.offset = offset; + } + // append. + tok.insert(end.prev); + cursor.offset = cursor.offset + tok.length; + } else if (!cursor.token.isInstanceOf[Gap]) { + val sem = cursor.token.asInstanceOf[Semantic]; + if (sem.symbol == tok.symbol) return; + if (sem.symbol != tok.symbol && + sem.symbol.getClass() == tok.symbol.getClass() && + sem.symbol.pos == tok.symbol.pos) return; + } else { + val gap = cursor.token.asInstanceOf[Gap]; + if (!(offset - cursor.offset + tok.length <= gap.length)) { + Console.err.println("LIST =" + this); + Console.err.println("OFFSET=" + offset + " " + tok + " " + tok.length); + Console.err.println(" " + cursor.offset + " " + gap.length); + gap.length0 = offset - cursor.offset + tok.length + //abort(); + } + if (offset == cursor.offset) { + // replace or prepend + tok.prev0 = gap.prev0; + if (tok.length == gap.length) { // replace gap + tok.next0 = gap.next0; + } else { + gap.setLength(gap.length - tok.length); + tok.next0 = gap; + } + tok.next0.prev0 = tok; + tok.prev0.next0 = tok; + cursor.token = tok; + } else { + // append + val diff = (cursor.offset + gap.length) - (offset + tok.length); + + gap.setLength(gap.length - tok.length - diff); + tok.prev0 = gap; + tok.next0 = gap.next; + tok.next0.prev0 = tok; + tok.prev0.next0 = tok; + if (diff != 0) { + val gap0 = new Gap(tok); + gap0.setLength(diff); + } + } + } + } + + override def toString(): String = { + var node = begin.next + var str = "" + while (node != end) { + str = str + " " + node + node = node.next + } + str + } + + object cursor { + var token: Token = end + var offset: Int = 0 + + def next: Unit = if (token == end) end else { + offset = offset + token.length + token = token.next + } + def prev: Unit = if (token.prev == begin) token else { + offset = offset - token.prev.length + token = token.prev + } + def seek(soffset: Int): Unit = if (soffset == 0) { + token = begin.next + offset = 0 + } else { + assert(soffset > 0) + while (offset > soffset) prev; + while (offset + token.length <= soffset && token != end) { + val len0 = offset; + next; + } + } + def convertToGap = if (token.isInstanceOf[Actual]) { + val ret = token.asInstanceOf[Actual].convertToGap; + offset = offset - ret._1; + token = ret._2; + } + } + + // add or delete characters + def adjust(offset: Int, /* where */ + length: Int, /* how many characters are modified */ + to : Int /* length of new string */) = { + cursor.seek(offset) + if (cursor.token != end) { + cursor.convertToGap + while (cursor.offset + cursor.token.length < offset + length && cursor.token.next != end) { + val save = cursor.offset + cursor.next + cursor.convertToGap + assert(cursor.offset == save) + } + if (length != to && cursor.token != end) { + val diff = to - length; + val gap = cursor.token.asInstanceOf[Gap]; + gap.setLength(gap.length + diff); + }; + } + } + + } // TokenList + + } +} + diff --git a/src/attic/scala/tools/nsc/models/Signatures.scala b/src/attic/scala/tools/nsc/models/Signatures.scala new file mode 100644 index 0000000000..2a94a1cfae --- /dev/null +++ b/src/attic/scala/tools/nsc/models/Signatures.scala @@ -0,0 +1,86 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Martin Odersky + */ +// $Id$ + +package scala.tools.nsc +package models + +import scala.collection.mutable.{HashMap, HashSet} +import scala.tools.nsc.{Global => Compiler} +import scala.tools.nsc.symtab.{Flags, Names} +import scala.tools.nsc.util.{ Position, SourceFile } +import scala.reflect.NameTransformer + +/** This class ... + * + * @author Sean McDirmid + * @version 1.0 + */ +class Signatures(val compiler: Compiler) { + import compiler._ + + class Signature(val name: String, val children: List[Signature]) { + def asString: String = name + "[" + asString0(children) + "]" + } + + def sort(sigs: List[Signature]) = sigs sortBy (_.name) reverse + + def asString0(sigs: List[Signature]): String = + sort(sigs) map (_.asString) mkString + + def signature(unit: CompilationUnit): String = + asString0(signature(unit.body, Nil)) + + def signature(trees: List[Tree]): List[Signature] = { + var ret : List[Signature] = Nil + for (tree <- trees) ret = signature(tree, ret) + ret + } + + /** + * @param tree0 ... + * @param rest ... + * @return ... + */ + def signature(tree0: Tree, rest: List[Signature]): List[Signature] = tree0 match { + case tree: MemberDef => if (!tree.mods.isPrivate) { + val name = "" + tree.name + "::" + + (tree.mods &~ Flags.SYNTHETIC) + + val children: List[Signature] = tree match { + case impl: ImplDef + //if (!impl.name.toString.contains("$anonfun$")) => + if (impl.name.pos("$anonfun$") == name.length) => + val supers = new Signature("$$supers", signature(impl.impl.parents)) + val body = new Signature("$$body", signature(impl.impl.body)) + val ret = supers :: body :: Nil + impl match { + case cdef: ClassDef => + new Signature("$$tparams", signature(cdef.tparams)) :: ret + case _ => + ret + } + case vdef: ValOrDefDef => + val ret = signature(vdef.tpt, Nil) + vdef match { + case ddef : DefDef => + val tparams = new Signature("$$tparams", signature(ddef.tparams)) + var vparamss : List[Signature] = Nil + for (list <- ddef.vparamss) + vparamss = signature(list) ::: vparamss + new Signature("$$ret", ret) :: tparams :: vparamss + case _ => + ret + } + case pdef: PackageDef => signature(pdef.stats) + case _ => Nil + } + new Signature(name, children) :: rest + + } else rest + case tree: TypeTree => new Signature("" + tree.tpe, Nil) :: rest + case _ => rest + } +} diff --git a/src/attic/scala/tools/nsc/symtab/SymbolWalker.scala b/src/attic/scala/tools/nsc/symtab/SymbolWalker.scala new file mode 100644 index 0000000000..8c111875dd --- /dev/null +++ b/src/attic/scala/tools/nsc/symtab/SymbolWalker.scala @@ -0,0 +1,253 @@ +package scala.tools.nsc +package symtab + +trait SymbolWalker { + val global : Global + import global._ + import scala.collection.mutable.LinkedHashSet + trait Visitor { + def update(pos : Position, sym : Symbol) : Unit + def contains(pos : Position) : Boolean + def apply(pos : Position) : Symbol + def putDef(sym : Symbol, pos : Position) : Unit = () + } + import scala.collection.mutable.Map + /* + implicit def map2use(map : Map[Position,Symbol]) = new Visitor { + def update(pos : Position, sym : Symbol) : Unit = map.update(pos, sym) + def contains(pos : Position) : Boolean = map.contains(pos) + def apply(pos : Position) : Symbol = map.apply(pos) + } + */ + private def validSym(t: Tree) = t.symbol != NoSymbol && t.symbol != null + private def validSym(tp: Type) = tp != null && tp.typeSymbol != NoSymbol && tp.typeSymbol != null + private def notNull(tp: Type) = tp.typeSymbol != null + private def isNoSymbol(t: Tree) = t.symbol eq NoSymbol + + def walk(tree: Tree, visitor : Visitor)(fid : (util.Position) => Option[String]) : Unit = { + val visited = new LinkedHashSet[Tree] + def f(t : Tree) : Unit = { + if (visited.add(t)) return + + def fs(l: List[Tree]) = l foreach f + def fss(l: List[List[Tree]]) = l foreach fs + + val sym = (t, t.tpe) match { + case (Super(_,_),SuperType(_,supertp)) if validSym(supertp) => supertp.typeSymbol + case _ if validSym(t) => t.symbol + case (t: TypeTree, tp) if validSym(tp) => tp.typeSymbol + case (t: TypeTree, tp) if validSym(tp.resultType) => tp.resultType.typeSymbol + case (t, tpe: Type) if isNoSymbol(t) && tpe.termSymbol != null => + if (t.isTerm) tpe.termSymbol + else t.tpe match { + case x: TypeRef => x.sym // XXX: looks like a bug + case _ => tpe.typeSymbol + } + case _ => NoSymbol + } + + if (sym != null && sym != NoSymbol /* && !sym.hasFlag(SYNTHETIC) */) { + var id = fid(t.pos) + val doAdd = if (id.isDefined) { + if (id.get.charAt(0) == '`') id = Some(id.get.substring(1, id.get.length - 1)) + val name = sym.name.decode.trim + if ((name startsWith id.get) || (id.get startsWith name)) true + else { + false + } + } else false + if (doAdd) { + + if (!visitor.contains(t.pos)) { + visitor(t.pos) = sym + } else { + val existing = visitor(t.pos) + if (sym.sourceFile != existing.sourceFile || sym.pos != existing.pos) { + (sym,existing) match { + case (sym,existing) if sym.pos == existing.pos => + case (sym : TypeSymbol ,_ : ClassSymbol) => visitor(t.pos) = sym + case (_ : ClassSymbol,_ : TypeSymbol) => // nothing + case _ if sym.isModule && existing.isValue => // nothing + case _ if sym.isClass && existing.isMethod => // nothing + case _ => + assert(true) + } + } + }} + } + t match { + case t : DefTree if t.symbol != NoSymbol => + if (t.pos != NoPosition) + visitor.putDef(t.symbol, t.pos) + if (t.symbol.isClass) { + val factory = NoSymbol // XXX: t.symbol.caseFactory + if (factory != NoSymbol) { + visitor.putDef(factory, t.pos) + } + } + case t : TypeBoundsTree => f(t.lo); f(t.hi) + case t : TypeTree if t.original != null => + def h(original : Tree, tpe : Type): Unit = try { + if (original.tpe == null) + original.tpe = tpe + (original) match { + case (AppliedTypeTree(_,trees)) if tpe.isInstanceOf[TypeRef] => + val types = tpe.asInstanceOf[TypeRef].args + trees.zip(types).foreach{ + case (tree,tpe) => assert(tree != null && tpe != null); h(tree, tpe) + } + case _ => + } + } + if (t.original.tpe == null) { + val dup = t.original.duplicate + h(dup,t.tpe) + f(dup) + } else f(t.original) + () + case _ => + } + (t) match { + case (t : MemberDef) if t.symbol != null && t.symbol != NoSymbol => + val annotated = if (sym.isModule) sym.moduleClass else sym + val i = t.mods.annotations.iterator + val j = annotated.annotations.iterator + while (i.hasNext && j.hasNext) { + val tree = i.next + val ainfo = j.next + val sym = ainfo.atp.typeSymbol + tree.setType(ainfo.atp) + tree.setSymbol(sym) + f(tree) + } + + case _ => + } + t match { + case tree: ImplDef => + fs(tree.impl.parents); f(tree.impl.self); fs(tree.impl.body) + tree match { + case tree : ClassDef => fs(tree.tparams) + case _ => + } + case tree: PackageDef => fs(tree.stats) + case tree: ValOrDefDef => + f(tree.rhs); + if (tree.tpt != null) { + f(tree.tpt) + } + tree match { + case tree : DefDef => fs(tree.tparams); fss(tree.vparamss) + case _ => + } + case tree: Function => fs(tree.vparams); f(tree.body) + case tree : Bind => f(tree.body) + case tree : Select => + val qualifier = if (tree.tpe != null && tree.qualifier.tpe == null) { + val pre = tree.tpe.prefix + val qualifier = tree.qualifier.duplicate + qualifier.tpe = pre + qualifier + } else tree.qualifier + + f(qualifier) + case tree : Annotated => f(tree.annot); f(tree.arg) + case tree : GenericApply => f(tree.fun); fs(tree.args) + case tree : UnApply => f(tree.fun); fs(tree.args) + case tree : AppliedTypeTree => + if (tree.tpe != null) { + val i = tree.tpe.typeArgs.iterator + val j = tree.args.iterator + while (i.hasNext && j.hasNext) { + val tpe = i.next + val arg = j.next + if (arg.tpe == null) { + arg.tpe = tpe + } + } + if (tree.tpt.tpe == null) { + tree.tpt.tpe = tree.tpe + } + + } + f(tree.tpt); fs(tree.args) + + case tree : ExistentialTypeTree=> + if (tree.tpt.tpe == null) { + tree.tpt.tpe = tree.tpe + } + + f(tree.tpt) + fs(tree.whereClauses) + case tree : SingletonTypeTree => + if (tree.ref.tpe == null) { + val dup = tree.ref.duplicate + dup.tpe = tree.tpe + f(dup) + } else f(tree.ref) + case tree : CompoundTypeTree => + if (tree.tpe != null && tree.tpe.typeSymbol != null && tree.tpe.typeSymbol.isRefinementClass) tree.tpe.typeSymbol.info match { + case tpe : RefinedType => + tpe.parents.zip(tree.templ.parents).foreach{ + case (tpe,tree) => + if (tree.hasSymbol && (tree.symbol == NoSymbol || tree.symbol == null)) { + tree.symbol = tpe.typeSymbol + } + } + + case _ => + } + + f(tree.templ) + case tree : Template => fs(tree.parents); f(tree.self); fs(tree.body) + case tree : SelectFromTypeTree => { + if (tree.qualifier.tpe == null) tree.tpe match { + case tpe : TypeRef => + // give it a type! + tree.qualifier.tpe = tpe.prefix + case _ => + // tree.tpe.pre + } + f(tree.qualifier) + } + case tree : Literal => + /* + if (tree.tpe != null && tree.tpe.typeSymbol == definitions.ClassClass) { + // nothing we can do without original tree. + } + */ + + case tree : Typed => f(tree.expr); f(tree.tpt) + case tree : Block => fs(tree.stats); f(tree.expr) + case tree: CaseDef => f(tree.pat);f(tree.guard);f(tree.body) + case tree : Assign => f(tree.lhs); f(tree.rhs); + case tree : If => f(tree.cond); f(tree.thenp); f(tree.elsep); + case tree : New => f(tree.tpt); + case tree : Match => f(tree.selector); fs(tree.cases); + case tree : Return => f(tree.expr); + case tree : LabelDef => f(tree.rhs); + case tree : Throw => f(tree.expr); + case tree : Try => f(tree.block); fs(tree.catches); f(tree.finalizer); + case tree : Alternative => fs(tree.trees); + case tree : TypeDef => + (tree.tpe,sym) match { + case (null,sym : TypeSymbol) if (sym.rawInfo.isComplete) => + if (tree.tparams.isEmpty) { + if (tree.rhs.tpe == null) tree.rhs.tpe = sym.info + f(tree.rhs) + } else { + val tree0 = AppliedTypeTree(tree.rhs, tree.tparams) + tree0.tpe = sym.info + f(tree0) + } + case _ => f(tree.rhs); fs(tree.tparams) + } + case tree : DocDef => f(tree.definition); + case tree: Import => f(tree.expr) + case _ => + } + } + f(tree) + } + +} |