From 3d141a01305f45c4ec14e119006218ceb6994c00 Mon Sep 17 00:00:00 2001 From: Sean McDirmid Date: Wed, 7 Dec 2005 16:33:48 +0000 Subject: Set source file in ClassSym symbols. --- sources/scala/tools/nsc/CompilationUnits.scala | 4 + sources/scala/tools/nsc/Global.scala | 11 +- .../scala/tools/nsc/models/SemanticTokens.scala | 186 ++++++++++----------- .../scala/tools/nsc/reporters/StoreReporter.scala | 1 + sources/scala/tools/nsc/symtab/SymbolLoaders.scala | 11 +- sources/scala/tools/nsc/symtab/Symbols.scala | 2 + sources/scala/tools/nsc/typechecker/Infer.scala | 8 + 7 files changed, 119 insertions(+), 104 deletions(-) (limited to 'sources/scala/tools/nsc') diff --git a/sources/scala/tools/nsc/CompilationUnits.scala b/sources/scala/tools/nsc/CompilationUnits.scala index e0793a6d9c..0c39d99c16 100644 --- a/sources/scala/tools/nsc/CompilationUnits.scala +++ b/sources/scala/tools/nsc/CompilationUnits.scala @@ -7,6 +7,8 @@ package scala.tools.nsc; import scala.tools.nsc.util.{SourceFile, Position}; import scala.tools.nsc.util.FreshNameCreator; +import scala.tools.util.AbstractFile; +import scala.collection.mutable.HashSet; [_trait_] abstract class CompilationUnits: Global { @@ -21,6 +23,8 @@ import scala.tools.nsc.util.FreshNameCreator; /** the content of the compilation unit in tree form */ var body: Tree = EmptyTree; + val depends = new HashSet[AbstractFile]; + def position(pos: int) = new Position(source, pos); def error(pos: int, msg: String) = reporter.error(position(pos), msg); diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index dc709117de..d0a35b8aa8 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -160,14 +160,19 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable abstract class GlobalPhase(prev: Phase) extends Phase(prev) { phaseWithId(id) = this; def run: unit = currentRun.units foreach applyPhase; + def apply(unit: CompilationUnit): unit; private val isErased = prev.name == "erasure" || prev.erasedTypes; override def erasedTypes: boolean = isErased; private val isFlat = prev.name == "flatten" || prev.flatClasses; override def flatClasses: boolean = isFlat; - def applyPhase(unit: CompilationUnit): unit = { + final def applyPhase(unit: CompilationUnit): unit = { if (settings.debug.value) inform("[running phase " + name + " on " + unit + "]"); - apply(unit) + val unit0 = currentRun.currentUnit; + currentRun.currentUnit = unit; + apply(unit); + assert(currentRun.currentUnit == unit); + currentRun.currentUnit = unit0; } } @@ -278,6 +283,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable override val terminalPhase : Phase = typerPhase.next; } class Run extends CompilerRun { + var currentUnit : CompilationUnit = _; curRun = this; override val firstPhase = syntaxAnalyzer.newPhase(NoPhase); phase = firstPhase; @@ -333,7 +339,6 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable def compileSources(sources: List[SourceFile]): unit = { val startTime = System.currentTimeMillis(); reporter.reset; - for (val source <- sources) addUnit(new CompilationUnit(source)); diff --git a/sources/scala/tools/nsc/models/SemanticTokens.scala b/sources/scala/tools/nsc/models/SemanticTokens.scala index 4520001a1b..46763040aa 100644 --- a/sources/scala/tools/nsc/models/SemanticTokens.scala +++ b/sources/scala/tools/nsc/models/SemanticTokens.scala @@ -68,18 +68,20 @@ class SemanticTokens(val compiler: Compiler) { new Pair(0,gap); } } - } - final class Gap extends Actual { - def this(prev1 : HasNext) = { - this(); + def insert(prev1 : HasNext) = { next0 = prev1.next; prev0 = prev1; prev0.next0 = this; next0.prev0 = this; } + } + 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; @@ -102,6 +104,7 @@ class SemanticTokens(val compiler: Compiler) { abstract class Semantic(val symbol : Symbol) extends Actual { val name = NameTransformer.decode(symbol.name.toString()).toString().trim(); + assert(symbol != NoSymbol); def length = name.length(); @@ -126,19 +129,22 @@ class SemanticTokens(val compiler: Compiler) { class Def(tree0 : DefTree) extends Semantic(tree0.symbol) { // if (info.defined != null) throw new Error("old=" + info.defined + " vs. new=" + this); info.defined = this; - override def toString() = "def-" + name; + override def toString() = "def-" + name + "-" + symbol.getClass(); // if (name.equals("x$0")) throw new Error("SYM=" + symbol + " TREE: " + tree0); } + def Def(tree : DefTree) = if (tree.symbol == NoSymbol) { + val gap = new Gap(); + gap.setLength(1); + gap; + } else new Def(tree); + class Use(symbol0 : Symbol) extends Semantic(symbol0) { info.uses += this; override def toString() = "use-" + name; } - - - val list = new TokenList; build(unit.body); @@ -148,49 +154,44 @@ class SemanticTokens(val compiler: Compiler) { def build(tree0 : Tree) : Unit = if (tree0.pos != Position.NOPOS) tree0 match { case tree : ImplDef => - list.put(tree.namePos(unit.source), new Def(tree)); + list.put(tree.namePos(unit.source), Def(tree)); tree match { case cdef : ClassDef => build(cdef.tparams); case _ => ; } build(tree.impl0.parents); build(tree.impl0.body); - case tree : ValOrDefDef => - // System.err.println("VAL: " + tree + " @ " + tree.pos); - - - if (tree.name0.toString().equals("")) { - //System.err.println("IGNORE: " + tree.name0.toString() + " " + tree.pos); - } else if (tree.symbol.hasFlag(Flags.ACCESSOR)) { + if (tree.symbol.hasFlag(Flags.ACCESSOR)) { // ignore ; } else { - val pos = tree.namePos(unit.source); - if (pos != Position.NOPOS) { - - if (!tree.hasFlag(Flags.SYNTHETIC)) - list.put(pos, new Def(tree)); + { + val pos = if (tree.name0.toString().equals("")) Position.NOPOS else tree.namePos(unit.source); + if (pos != Position.NOPOS) { + if (!tree.hasFlag(Flags.SYNTHETIC)) + list.put(pos, Def(tree)); + } + } - if (tree.isInstanceOf[DefDef]) { - val ddef = tree.asInstanceOf[DefDef]; - build(ddef.tparams); + if (tree.isInstanceOf[DefDef]) { + val ddef = tree.asInstanceOf[DefDef]; + build(ddef.tparams); - for (val l0 <- ddef.vparamss; val arg <- l0) { + for (val l0 <- ddef.vparamss; val arg <- l0) { - val pos0 = if (!unit.source.beginsWith(arg.pos, "val ")) arg.pos; - else unit.source.skipWhitespace(arg.pos + ("val ").length()); - list.put(pos0, new Def(arg)); - build(arg.tpt0); - } + val pos0 = if (!unit.source.beginsWith(arg.pos, "val ")) arg.pos; + else unit.source.skipWhitespace(arg.pos + ("val ").length()); + list.put(pos0, Def(arg)); + build(arg.tpt0); } - build(tree.tpt0); - build(tree.rhs0); } + build(tree.tpt0); + build(tree.rhs0); } case tree : PackageDef => val pos = tree.namePos(unit.source); - list.put(pos, new Def(tree)); + list.put(pos, Def(tree)); build(tree.stats); case tree : Function => for (val arg <- tree.vparams) if (arg.pos != Position.NOPOS) { @@ -202,53 +203,55 @@ class SemanticTokens(val compiler: Compiler) { while (Character.isWhitespace(unit.source.content(posx - 1))) posx = posx - 1; posx - name.length(); } else arg.pos; - list.put(pos, new Def(arg)); + list.put(pos, Def(arg)); build(arg.tpt0); } build(tree.body); case tree : TypeTree => val tree1 = if (tree.original != null) tree.original; else tree; - build(tree1, tree.tpe); - def build( tree : Tree, tpe : Type) : Unit = if (tree.pos != Position.NOPOS) tpe match { + buildT(tree1, tree.tpe); + def buildT( tree : Tree, tpe : Type) : Unit = if (tree.pos != Position.NOPOS) tpe match { case tpe0 : TypeRef => tree match { case apt : AppliedTypeTree => - buildSym(tpe0.sym, apt.tpt.pos); + build(apt.tpt); + //buildSym(tpe0.sym, apt.tpt.pos); buildTs (apt.args, tpe0.args); case ident : Ident => buildSym(tpe0.sym, ident.pos); case select : Select => - val pos = selectPos(select); - buildSym(tpe0.sym, pos); + // System.err.println("BUILD_SELECT: " + select + " @ " + tpe0); + build(select); case tpt : TypeTree => - // System.err.println("UNKNOWN TPT: " + tree + " vs. " + tpe0 + " " + tpt.original + " " + unit.source.content(tree.pos)); - case _ => System.err.println("UNKNOWN TPE: " + tree + " vs. " + tpe0 + " " + tree.getClass() + " " + unit.source.content(tree.pos)); + // System.err.println("UNKNOWN TPT0: " + tpe0 + " vs. " + tpt); + case _ => System.err.println("UNKNOWN TPT2: " + tree + " vs. " + tpe0 + " " + tree.getClass() + " " + unit.source.content(tree.pos)); } case tpe0 : MethodType => tree match { case tpt: TypeTree => - if (tpt.original != null) build(tpt.original, tpe); + if (tpt.original != null) buildT(tpt.original, tpe); else { - System.err.println("UNKNOWN TPT: " + tree + " vs. " + tpe0 + " " + unit.source.content(tree.pos)); + System.err.println("UNKNOWN TPT3: " + tree + " vs. " + tpe0 + " " + unit.source.content(tree.pos)); } - case ident : Ident => build(ident, tpe0.resultType); - case select : Select => build(select, tpe0.resultType); + case ident : Ident => buildT(ident, tpe0.resultType); + case select : Select => buildT(select, tpe0.resultType); case _ => System.err.println("UNKNOWN TPE: " + tree + " vs. " + tpe0 + " " + tree.getClass()); } - case _ => System.err.println("UNKNOWN: " + tree + " " + (if (tree != null) tree.getClass() else null) + " vs. " + tpe + " " + (if (tpe != null) tpe.getClass() else null) + " " + (if (tree != null) tree.pos else null)); + case _ => // System.err.println("UNKNOWN: " + tree + " " + (if (tree != null) tree.getClass() else null) + " vs. " + tpe + " " + (if (tpe != null) tpe.getClass() else null) + " " + (if (tree != null) tree.pos else null)); }; def buildTs(trees : List[Tree], types : List[Type]): Unit = if (!trees.isEmpty || !types.isEmpty) { - build (trees.head, types.head); + buildT (trees.head, types.head); buildTs(trees.tail, types.tail); }; case tree : AbsTypeDef => - list.put(tree.namePos, new Def(tree)); + list.put(tree.namePos, Def(tree)); case tree : Bind => - list.put(tree.pos, new Def(tree)); + list.put(tree.pos, Def(tree)); build(tree.body); case tree : Ident => buildSym(tree.symbol, tree.pos); case tree : Select => + // System.err.println("SELECT: " + tree.qualifier + " ** " + tree.symbol + " " + selectPos(tree)); build(tree.qualifier); buildSym(tree.symbol, selectPos(tree)); case tree : GenericApply => - // System.err.println("APPLY: " + tree.fun0 + " " + tree.args0); + // System.err.println("APPLY: " + tree.fun0 + " " + tree.args0); build(tree.fun0); build(tree.args0); case tree : Typed => build(tree.expr); build(tree.tpt); case tree : Import => build(tree.expr); @@ -263,6 +266,7 @@ class SemanticTokens(val compiler: Compiler) { case tree : Return => build(tree.expr); case tree : Literal => ; case tree : This => ; + case tree : Super => ; case _ => ; if (tree0 != EmptyTree) System.err.println("BAIL: " + tree0.pos + " " + tree0 + " " + tree0.getClass()); @@ -312,9 +316,8 @@ class SemanticTokens(val compiler: Compiler) { begin.next0 = end; end.prev0 = begin; - private var length : Int = 0; - def tokenAt(offset : Int) = if (offset >= length) null else { + def tokenAt(offset : Int) = { //System.err.println("CURSOR-0: " + cursor.offset); cursor.seek(offset); //System.err.println("CURSOR-1: " + cursor.offset + " " + cursor.token + " " + offset); @@ -322,13 +325,34 @@ class SemanticTokens(val compiler: Compiler) { if (cursor.token.isInstanceOf[Semantic]) cursor.token.asInstanceOf[Semantic]; else null; }; - def put(offset : Int, tok : Semantic) = { - grow(offset); - if (offset == length) append(tok); - else { - grow(offset + tok.length); - cursor.seek(offset); - assert(cursor.token.isInstanceOf[Gap]); + def put(offset : Int, tok : Actual) : Unit = tok match { + case tok0 : Semantic => put(offset, tok0); + case gap : Gap => ; + } + + + def put(offset : Int, tok : Semantic) :Unit = { + 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; + System.err.println("NOT_GAP: " + sem.symbol + " " + sem.symbol.getClass()); + System.err.println("NOT_GAP: " + tok.symbol + " " + tok.symbol.getClass()); + System.err.println("LIST: " + this); + throw new Error(); + } else { val gap = cursor.token.asInstanceOf[Gap]; if (!(offset - cursor.offset + tok.length <= gap.length)) { System.err.println("LIST =" + this); @@ -374,39 +398,6 @@ class SemanticTokens(val compiler: Compiler) { } str; }; - def grow(length0 : Int) = if (length0 > length) { - if (false) { - System.err.println("GROW: " + length + " -> " + length0); - System.err.println(" " + this); - } - - assert(length < length0); - - if (end.prev.isInstanceOf[Gap]) { - val gap = end.prev.asInstanceOf[Gap]; - gap.setLength(gap.length + (length0 - length)); - } else { - val gap = new Gap; - gap.setLength(length0 - length); - gap.prev0 = end.prev; - gap.next0 = end; - gap.prev0.next0 = gap; - end.prev0 = gap; - } - if (cursor.token == end) { - assert(cursor.offset == length); - cursor.offset = length0; - } - length = length0; - } - def append(tok : Semantic) : Unit = { - tok.prev0 = end.prev; - tok.next0 = end; - tok.prev0.next0 = tok; - end.prev0 = tok; - length = length + tok.length; - if (cursor.token == end) cursor.offset = length; - } private object cursor { var token : Token = end; var offset : Int = 0; @@ -422,14 +413,13 @@ class SemanticTokens(val compiler: Compiler) { def seek(soffset : Int) : Unit = if (soffset == 0) { token = begin.next; offset = 0; - } else if (soffset >= length) { - token = end; - offset = length; } else { assert(soffset > 0); - assert(soffset < length); while (offset > soffset) prev; - while (offset + token.length <= soffset) next; + while (offset + token.length <= soffset && token != end) { + val len0 = offset; + next; + } } def convertToGap = if (token.isInstanceOf[Actual]) { val ret = token.asInstanceOf[Actual].convertToGap; diff --git a/sources/scala/tools/nsc/reporters/StoreReporter.scala b/sources/scala/tools/nsc/reporters/StoreReporter.scala index 3011487e39..c4aa973dab 100644 --- a/sources/scala/tools/nsc/reporters/StoreReporter.scala +++ b/sources/scala/tools/nsc/reporters/StoreReporter.scala @@ -30,6 +30,7 @@ class StoreReporter extends Reporter { incr(severity); } override def reset = { + super.reset; infos.clear; } } diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala index 09b1f4b9f7..11f0c21c4f 100755 --- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -89,11 +89,12 @@ abstract class SymbolLoaders { root.info.decls.enter(pkg) } - def enterClassAndModule(str: String, completer: SymbolLoader): unit = { + def enterClassAndModule(str: String, completer: SymbolLoader, sfile : AbstractFile): unit = { val owner = if (root.isRoot) definitions.EmptyPackageClass else root; val name = newTermName(str); val clazz = owner.newClass(Position.NOPOS, name.toTypeName); val module = owner.newModule(Position.NOPOS, name); + clazz.sourceFile = sfile; clazz.setInfo(completer); module.setInfo(completer); module.moduleClass.setInfo(moduleClassLoader); @@ -132,10 +133,14 @@ abstract class SymbolLoaders { for (val Pair(name, sfile) <- sources.elements) { classes.get(name) match { case Some(cfile) if (cfile.lastModified() >= sfile.lastModified()) => {} - case _ => enterClassAndModule(name, new SourcefileLoader(sfile)); + case _ => enterClassAndModule(name, new SourcefileLoader(sfile), sfile); } } for (val Pair(name, cfile) <- classes.elements) { + val sfile = sources.get(name) match { + case Some(sfile0) => sfile0; + case _ => null; + } sources.get(name) match { case Some(sfile) if (sfile.lastModified() > cfile.lastModified()) => {} case _ => @@ -143,7 +148,7 @@ abstract class SymbolLoaders { /* if (cfile.getName().endsWith(".symbl")) new SymblfileLoader(cfile) else */ new ClassfileLoader(cfile); - enterClassAndModule(name, loader) + enterClassAndModule(name, loader, sfile) } } for (val Pair(name, file) <- packages.elements) { diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index fe423d0fa8..dcaa8519c7 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -932,6 +932,8 @@ import Flags._; /** A class for class symbols */ class ClassSymbol(initOwner: Symbol, initPos: int, initName: Name) extends TypeSymbol(initOwner, initPos, initName) { + + var sourceFile: AbstractFile = null; private var thissym: Symbol = this; override def isClass: boolean = true; diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala index 8f2472041a..43283b4d12 100755 --- a/sources/scala/tools/nsc/typechecker/Infer.scala +++ b/sources/scala/tools/nsc/typechecker/Infer.scala @@ -217,6 +217,14 @@ package scala.tools.nsc.typechecker; if (sym.isError) { tree setSymbol sym setType ErrorType } else { + sym.toplevelClass match { + case clazz : ClassSymbol => + // System.err.println("TOP: " + clazz + " " + clazz.sourceFile); + if (clazz.sourceFile != null) + global.currentRun.currentUnit.depends += clazz.sourceFile; + + case _ => + } val sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super])); if (sym1 == NoSymbol) { if (settings.debug.value) { -- cgit v1.2.3