From 65fa4b28064614f446f34b3278361a270bcc93f3 Mon Sep 17 00:00:00 2001 From: Sean McDirmid Date: Wed, 18 Jan 2006 17:13:01 +0000 Subject: --- src/compiler/scala/tools/nsc/Global.scala | 4 +- src/compiler/scala/tools/nsc/models/Models.scala | 8 +- .../scala/tools/nsc/models/SemanticTokens.scala | 594 +++++++++++---------- .../scala/tools/nsc/symtab/SymbolLoaders.scala | 64 ++- src/compiler/scala/tools/nsc/util/ClassPath.scala | 170 +++--- 5 files changed, 416 insertions(+), 424 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index a7d9fd779a..30a1217945 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -142,9 +142,9 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable def getSourceFile(clazz: Symbol): SourceFile = { val ret = classPath.root.find(clazz.fullNameString(File.separatorChar), false); - if (ret.sources.isEmpty) throw new FileNotFoundException( + if (!ret.isSourceFile) throw new FileNotFoundException( "source file for " + clazz + " could not be found"); - getSourceFile(ret.sources.head.location); + getSourceFile(ret.sourceFile); } object loaders extends SymbolLoaders { diff --git a/src/compiler/scala/tools/nsc/models/Models.scala b/src/compiler/scala/tools/nsc/models/Models.scala index 7e9ec40b12..39412a1024 100644 --- a/src/compiler/scala/tools/nsc/models/Models.scala +++ b/src/compiler/scala/tools/nsc/models/Models.scala @@ -55,6 +55,8 @@ class Models(val global : Global) { object subscriber extends Subscriber[Message[HasTree] with Undoable, Members] { def notify(pub: Members, event: Message[HasTree] with Undoable): Unit = event match { + //case Include(elem) => add(Composite.this, i.elem); + //case Remove(elem) => remove(Composite.this, i.elem); case i : Include[HasTree] with Undoable => add(Composite.this, i.elem); case r : Remove [HasTree] with Undoable => remove(Composite.this, r.elem); } @@ -173,8 +175,8 @@ class Models(val global : Global) { else ret.head; } else tree; } else super.member(tree, members); - val sym = tree0.symbol; - if (sym.pos == Position.NOPOS) null; + def sym = tree0.symbol; + if (tree0 == null || sym.pos == Position.NOPOS) null; else tree0; } @@ -203,7 +205,7 @@ class Models(val global : Global) { override def replacedBy(tree0 : Tree) : Boolean = (super.replacedBy(tree0) && tree0.isInstanceOf[AbsTypeDef]); } class SourceMod(val original : CompilationUnit) extends Composite with HasClassObjects { - // update(unit); + update(original); var listener : Listener = null; def update(unit : CompilationUnit) = unit.body match { case pdef : PackageDef => update0(pdef.stats); diff --git a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala index 2d087af4c5..42d802929e 100644 --- a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala +++ b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala @@ -92,6 +92,14 @@ class SemanticTokens(val compiler: Compiler) { class Process(val unit : CompilationUnit) { def source = unit.source; + def dbg(tree : Tree) = {( + "TREE=" + tree + + (if (tree != null) (" CLASS=" + tree.getClass()) else "") + + " SYM=" + tree.symbol + + " POS=" + + (new Position(source, if (tree != null) tree.pos else -1)).dbgString + )} + val symbols = new HashMap[Symbol,Info]; @@ -106,33 +114,35 @@ class SemanticTokens(val compiler: Compiler) { val name = NameTransformer.decode(symbol.name.toString()).toString().trim(); assert(symbol != NoSymbol); + 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 { - // System.err.println("UNRECOGNIZED SYMBOL: " + term0 + " " + name); - null; - } + 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 { + // System.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) extends Semantic(symbol0) { + class Use(symbol0 : Symbol, tpe0 : Type) extends Semantic(symbol0) { info.uses += this; + override def tpe : Type = if (tpe0 != null) tpe0 else super.tpe; override def toString() = "use-" + name; } val list = new TokenList; @@ -143,67 +153,59 @@ class SemanticTokens(val compiler: Compiler) { def build[T <: Tree](trees : List[T]) : Unit = for (val tree : T <- trees) build(tree); def build(tree0 : Tree) : Unit = { - tree0 match { - //case tree: SymTree => System.err.println("TREE: " + tree.getClass() + " " + tree.symbol + " " + (new Position(unit.source, tree.pos)).dbgString); - case _ => - } if (tree0.pos != Position.NOPOS) tree0 match { case tree : ImplDef => - val pos = tree.namePos(unit.source); - if (pos == Position.NOPOS) { - // inner types. - // System.err.println("NOPOS: " + tree.getClass() + " " + (new Position(unit.source, tree.pos)).dbgString); - //Thread.dumpStack(); - } else buildDef(tree.symbol, tree.namePos(unit.source)); - 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)) { - // ignore - ; - } else { - { - val pos = if (tree.name.toString().equals("")) Position.NOPOS else tree.namePos(unit.source); - if (pos != Position.NOPOS) { - if (!tree.hasFlag(Flags.SYNTHETIC)) - buildDef(tree.symbol, pos); - } - } + val pos = tree.namePos(unit.source); + if (pos == Position.NOPOS) { + // inner types. + // System.err.println("NOPOS: " + tree.getClass() + " " + (new Position(unit.source, tree.pos)).dbgString); + //Thread.dumpStack(); + } else buildDef(tree.symbol, tree.namePos(unit.source)); + 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)) { + { + val pos = if (tree.name.toString().equals("")) Position.NOPOS else tree.namePos(unit.source); + if (pos != Position.NOPOS) { + if (!tree.hasFlag(Flags.SYNTHETIC)) + buildDef(tree.symbol, pos); + } + } - 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) { - val pos0 = if (!unit.source.beginsWith(arg.pos, "val ")) arg.pos; - else unit.source.skipWhitespace(arg.pos + ("val ").length()); - buildDef(arg.symbol, pos0); - build(arg.tpt); - } - } - try { - build(tree.tpt); - } catch { - case e: Error => - System.err.println("VALDEF: " + tree + " " + tree.tpt + " " + tree.pos + " " + tree.tpt.pos); - throw e; - } - build(tree.rhs); - } - case tree : PackageDef => - //System.err.println("PACKAGE: " + tree.name); - if (false) { - val pos = tree.namePos(unit.source); - if (pos != Position.NOPOS) - buildDef(tree.symbol, pos); - } - build(tree.stats); - case tree : Function => - for (val arg <- tree.vparams) if (arg.pos != Position.NOPOS) { + 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()); + buildDef(arg.symbol, pos0); + build(arg.tpt); + } + } + try { + build(tree.tpt); + } catch { + case e: Error => + System.err.println("VALDEF: " + tree + " " + tree.tpt + " " + tree.pos + " " + tree.tpt.pos); + throw e; + } + build(tree.rhs); + } + case tree : PackageDef => + //System.err.println("PACKAGE: " + tree.name); + if (false) { + val pos = tree.namePos(unit.source); + if (pos != Position.NOPOS) + buildDef(tree.symbol, pos); + } + build(tree.stats); + case tree : Function => + for (val arg <- tree.vparams) if (arg.pos != Position.NOPOS) { val name = arg.name.toString().trim(); val pos : Int = if (unit.source.beginsWith(arg.pos, "val ")) unit.source.skipWhitespace(arg.pos + ("val ").length()); @@ -215,137 +217,164 @@ class SemanticTokens(val compiler: Compiler) { buildDef(arg.symbol, pos); build(arg.tpt); } - build(tree.body); - case tree : TypeTree => - val tree1 = if (tree.original != null) tree.original; else tree; - if (tree.tpe != null) 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 => - buildUse(tpe.symbol, apt.tpt.pos); - //System.err.println("APT: " + apt.tpt + " sym0=" + apt.tpt.symbol + " sym1=" + tpe0.sym + " " + " " + apt.args + " " + tpe0.args); - - buildTs (apt.args, tpe0.args); - case ident : Ident => buildUse(tpe0.sym, ident.pos); - case select : Select => - // System.err.println("BUILD_SELECT: " + select + " @ " + tpe0); - try { - build(select); - } catch { - case e : Error => - System.err.println("BUILD_SELECT: " + select + " @ " + tpe0 + " " + unit.source.dbg(select.pos)); - throw e; - } - - case tpt : TypeTree => - //System.err.println("UNKNOWN TPT0: " + tpe0 + " " + tpe0.args + " " + tpt); - case sft : SelectFromTypeTree => - build(sft.qualifier); // XXX: broken - if (false) System.err.println("SFTT: " + sft + " sym=" + sft.symbol + " selector=" + sft.selector + " qual=" + sft.qualifier + " qual.sym=" + - sft.qualifier.symbol + - " qual.pos=" + unit.source.dbg(sft.qualifier.pos) + " symbol=" + sft.symbol + " type=" + tpe0 + - " type.sym=" + tpe0.symbol); - 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) buildT(tpt.original, tpe); - else { - System.err.println("UNKNOWN TPT3: " + tree + " vs. " + tpe0 + " " + unit.source.content(tree.pos)); - } - 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 tpe0 : RefinedType => tree match { - case cpt : CompoundTypeTree => - buildTs(cpt.templ.parents, tpe0.parents); - case _ => - System.err.println("UNKNOWN TPE5: " + tree + " " + (if (tree != null) tree.getClass() else null)); + build(tree.body); + case tree : TypeTree => + val tree1 = if (tree.original != null) tree.original; else tree; + if (tree.tpe != null) 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 => + buildUse(tpe.symbol, apt.tpt.pos, tpe0); + //System.err.println("APT: " + apt.tpt + " sym0=" + apt.tpt.symbol + " sym1=" + tpe0.sym + " " + " " + apt.args + " " + tpe0.args); + + buildTs (apt.args, tpe0.args); + case ident : Ident => buildUse(tpe0.sym, ident.pos, tpe0); + case select : Select => + // System.err.println("BUILD_SELECT: " + select + " @ " + tpe0); + try { + build(select); + } catch { + case e : Error => + System.err.println("BUILD_SELECT: " + select + " @ " + tpe0 + " " + unit.source.dbg(select.pos)); + throw e; + } + case tpt : TypeTree => + //System.err.println("UNKNOWN TPT0: " + tpe0 + " " + tpe0.args + " " + tpt); + case sft : SelectFromTypeTree => + build(sft.qualifier); // XXX: broken + if (false) System.err.println("SFTT: " + sft + " sym=" + sft.symbol + " selector=" + sft.selector + " qual=" + sft.qualifier + " qual.sym=" + + sft.qualifier.symbol + + " qual.pos=" + unit.source.dbg(sft.qualifier.pos) + " symbol=" + sft.symbol + " type=" + tpe0 + + " type.sym=" + tpe0.symbol); + 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) buildT(tpt.original, tpe); + else { + System.err.println("UNKNOWN TPT3: " + tree + " vs. " + tpe0 + " " + unit.source.content(tree.pos)); + } + 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 tpe0 : RefinedType => tree match { + case cpt : CompoundTypeTree => + buildTs(cpt.templ.parents, tpe0.parents); + case _ : TypeTree => + case _ => + System.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 _ => { - System.err.println("UNKNOWN TPE4: " + tree + " " + (if (tree != null) tree.getClass() else null) + " vs. " + tpe + " " + (if (tpe != null) tpe.getClass().getSuperclass() else null) + " " + (if (tree != null) tree.pos else null)); - } - }; - def buildTs(trees : List[Tree], types : List[Type]): Unit = if (!trees.isEmpty || !types.isEmpty) { - buildT (trees.head, types.head); - buildTs(trees.tail, types.tail); - }; - case tree : AbsTypeDef => buildDef(tree.symbol, tree.namePos); - case tree : Bind => buildDef(tree.symbol, tree.pos); - build(tree.body); - case tree : Ident => buildUse(tree.symbol, tree.pos); - case tree : Select => - try { - build(tree.qualifier); - } catch { - case e : Error => System.err.println("SELECTQ: " + tree + " " + tree.qualifier + " " + unit.source.dbg(tree.qualifier.pos)); throw e; - } - try { - if (tree.pos >= unit.source.content.length) - System.err.println("BAD_SELECT_QUALIFIER " + tree + " @ " + tree.pos); - else buildUse(tree.symbol, selectPos(tree)); - } catch { - case e : Error => System.err.println("SELECTU: " + tree + " " + tree.symbol + " " + unit.source.dbg(tree.pos)); throw e; - } - case tree : GenericApply => - build(tree.fun0); - build(tree.args0); - case tree : Typed => build(tree.expr); build(tree.tpt); - case tree : Import => build(tree.expr); - - case tree : Block => build(tree.stats); build(tree.expr); - case tree : CaseDef => - build(tree.pat); build(tree.guard); build(tree.body); - case tree : Sequence => build(tree.trees); - case tree : Assign => build(tree.lhs); build(tree.rhs); - case tree : If => build(tree.cond); build(tree.thenp); build(tree.elsep); - case tree : New => 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 : DocDef => build(tree.definition); - case tree : Literal => ; - case tree : This => ; - case tree : Super => ; - case _ => ; - if (tree0 != EmptyTree) System.err.println("BAIL: " + tree0.pos + " " + tree0 + " " + tree0.getClass()); - } + } + case tpe0 : SingleType => { + // System.err.println("UNKNOWN TPE8: " + dbg(tree) + " TPE=" + tpe0 + " PRE=" + tpe0.pre + " SYM=" + tpe0.sym); + + } + case ErrorType => + + case _ => { + System.err.println("UNKNOWN TPE4: " + dbg(tree) + " vs. " + tpe + " " + (if (tpe != null) "" + tpe.getClass() + " " + tpe.getClass().getSuperclass() else null)); + } + }; + def buildTs(trees : List[Tree], types : List[Type]): Unit = if (!trees.isEmpty || !types.isEmpty) { + buildT (trees.head, types.head); + buildTs(trees.tail, types.tail); + }; + case tree : AbsTypeDef => buildDef(tree.symbol, tree.namePos); + case tree : Bind => buildDef(tree.symbol, tree.pos); + build(tree.body); + case tree : Ident => buildUse(tree.symbol, tree.pos, tree.tpe); + case tree : Select => + try { + build(tree.qualifier); + } catch { + case e : Error => System.err.println("SELECTQ: " + tree + " " + tree.qualifier + " " + unit.source.dbg(tree.qualifier.pos)); throw e; + } + try { + if (tree.pos >= unit.source.content.length) + System.err.println("BAD_SELECT_QUALIFIER " + tree + " @ " + tree.pos); + else { + buildUse(tree.symbol, selectPos(tree), tree.tpe); + } + } catch { + case e : Error => System.err.println("SELECTU: " + tree + " " + tree.symbol + " " + unit.source.dbg(tree.pos)); throw e; + } + case tree : GenericApply => + build(tree.fun0); + build(tree.args0); + case tree : Typed => build(tree.expr); build(tree.tpt); + case tree : Import => build(tree.expr); + + case tree : Block => build(tree.stats); build(tree.expr); + case tree : CaseDef => + build(tree.pat); build(tree.guard); build(tree.body); + case tree : Sequence => build(tree.trees); + case tree : Assign => build(tree.lhs); build(tree.rhs); + case tree : If => build(tree.cond); build(tree.thenp); build(tree.elsep); + case tree : New => 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 : DocDef => build(tree.definition); + case tree : Alternative => build(tree.trees); + case tree : Literal => ; + case tree : This => if (tree.symbol != null) buildUse(tree.symbol, tree.pos, tree.tpe); + case tree : Super => ; + case tree : AppliedTypeTree => ; + case tree : SingletonTypeTree => ; + case tree : Attributed => ; + case EmptyTree => ; + case _ => ; + System.err.println("BAIL: " + tree0.pos + " " + tree0 + " " + tree0.getClass()); } - def buildUse(term : Symbol, pos : Int) = buildSym(term, pos, false); - def buildDef(term : Symbol, pos : Int) = buildSym(term, pos, true); + } + + + 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) : Unit = - if (term.hasFlag(Flags.ACCESSOR)) buildSym(term.accessed, pos, isDef); - else if (pos == Position.NOPOS) { + def buildSym(term : Symbol, pos : Int, isDef : Boolean, tpe : Type) : Unit = + if (term.hasFlag(Flags.ACCESSOR)) buildSym(term.accessed, pos, isDef, tpe); + else if (pos == Position.NOPOS) { System.err.println("NOPOS: " + term); Thread.dumpStack(); - } else if (term != NoSymbol) { + } else if (term != NoSymbol) { val name = NameTransformer.decode(term.name.toString()).toString().trim(); val buf = unit.source.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)) { - return; - } else idx = idx + 1; - - list.put(pos, (if (isDef) new Def(term) else new Use(term))); - } - def selectPos(tree : Select): Int = if (tree.pos == Position.NOPOS) Position.NOPOS else { - val buf = unit.source.content; - if (tree.pos >= buf.length) { + if (cs.length + pos > buf.length) return; + else while (idx < cs.length) { + if (buf(pos + idx) != cs(idx)) return; + else idx = idx + 1; + } + if (cs.length + pos + 1 < buf.length) { + if (Character.isJavaIdentifierPart(buf(pos + cs.length))) 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 == Position.NOPOS) Position.NOPOS else { + val buf = unit.source.content; + if (tree.pos >= buf.length) { System.err.println(""+tree + "@" + tree.pos + " not in " + unit.source.file.getName() + "[" + buf.length + "]"); Thread.dumpStack(); throw new Error(); - } + } - val pos = + val pos = if (buf(tree.pos) != '.') tree.pos; else { def f(x : Int) : Int = { @@ -354,111 +383,104 @@ class SemanticTokens(val compiler: Compiler) { } f(tree.pos + 1); } - pos; - }; - class TokenList { - object begin extends HasNext { + pos; + }; + class TokenList { + object begin extends HasNext { def prev = this; def length = 0; - } - object end extends HasPrev { + } + object end extends HasPrev { def next = this; def length = 0; - } - // initialize - begin.next0 = end; - end.prev0 = begin; - - - def tokenAt(offset : Int) = { - //System.err.println("CURSOR-0: " + cursor.offset); - cursor.seek(offset); - //System.err.println("CURSOR-1: " + cursor.offset + " " + cursor.token + " " + 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) :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; - if (sem.symbol != tok.symbol && - sem.symbol.getClass() == tok.symbol.getClass() && - sem.symbol.pos == tok.symbol.pos) return; - - System.err.println("NOT_GAP: " + sem.symbol + " " + sem.symbol.getClass() + " " + unit.source.dbg(sem.symbol.pos) + " " + sem.symbol.flags); - System.err.println("NOT_GAP: " + tok.symbol + " " + tok.symbol.getClass() + " " + unit.source.dbg(tok.symbol.pos) + " " + tok.symbol.flags); - System.err.println("LIST: " + this); - System.err.println("POS: " + unit.source.dbg(offset)); - - - Thread.dumpStack(); - throw new Error(); - } else { - val gap = cursor.token.asInstanceOf[Gap]; - if (!(offset - cursor.offset + tok.length <= gap.length)) { - System.err.println("LIST =" + this); - System.err.println("OFFSET=" + offset + " " + tok + " " + tok.length); - System.err.println(" " + cursor.offset + " " + gap.length); - throw new Error(); + // 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 => ; } - 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); - } + 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; + if (sem.symbol != tok.symbol && + sem.symbol.getClass() == tok.symbol.getClass() && + sem.symbol.pos == tok.symbol.pos) return; + + System.err.println("NOT_GAP: " + sem.symbol + " " + sem.symbol.getClass() + " " + unit.source.dbg(sem.symbol.pos) + " " + sem.symbol.flags); + System.err.println("NOT_GAP: " + tok.symbol + " " + tok.symbol.getClass() + " " + unit.source.dbg(tok.symbol.pos) + " " + tok.symbol.flags); + System.err.println("LIST: " + this); + System.err.println("POS: " + unit.source.dbg(offset)); + + + Thread.dumpStack(); + throw new Error(); + } else { + val gap = cursor.token.asInstanceOf[Gap]; + if (!(offset - cursor.offset + tok.length <= gap.length)) { + System.err.println("LIST =" + this); + System.err.println("OFFSET=" + offset + " " + tok + " " + tok.length); + System.err.println(" " + cursor.offset + " " + gap.length); + throw new Error(); + } + 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); + } + } + } } - } - // System.err.println("PUT: " + this); - } - override def toString() = { - var node = begin.next; - var str = ""; - while (node != end) { - str = str + " " + node; - node = node.next; - } - str; - }; + override def toString() = { + 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; diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 64684c80ad..0becbda8bd 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -113,45 +113,51 @@ abstract class SymbolLoaders { module.moduleClass.setInfo(moduleClassLoader); owner.info.decls.enter(clazz); owner.info.decls.enter(module); - assert(clazz.linkedModule == module, module); - assert(module.linkedClass == clazz, clazz); + assert(clazz.linkedModule == module, module); + assert(module.linkedClass == clazz, clazz); } val classes = new HashMap[String, ClassPath.Context]; val packages = new HashMap[String, ClassPath.Context]; - for (val dir <- directory.classes) if (dir != null) { - val it = dir.list(); - while (it.hasNext()) { - val file = it.next().asInstanceOf[AbstractFile]; - if (file.isDirectory() && directory.validPackage(file.getName()) && !packages.isDefinedAt(file.getName())) - packages(file.getName()) = directory.find(file.getName(), true); - else if (!file.isDirectory() && file.getName().endsWith(".class")) { - val name = file.getName().substring(0, file.getName().length() - (".class").length()); - if (isValid(name) && !classes.isDefinedAt(name)) - classes(name) = directory.find(name, false); - } - } + for (val dir <- directory.entries) if (dir.location != null) { + val it = dir.location.list(); + while (it.hasNext()) { + val file = it.next().asInstanceOf[AbstractFile]; + if (file.isDirectory() && directory.validPackage(file.getName()) && !packages.isDefinedAt(file.getName())) + packages(file.getName()) = directory.find(file.getName(), true); + else if (!file.isDirectory() && file.getName().endsWith(".class")) { + val name = file.getName().substring(0, file.getName().length() - (".class").length()); + if (isValid(name) && !classes.isDefinedAt(name)) + classes(name) = directory.find(name, false); + } + } } - for (val dir <- directory.sources) if (dir != null) { - val it = dir.location.list(); - while (it.hasNext()) { - val file = it.next().asInstanceOf[AbstractFile]; - if (file.isDirectory() && directory.validPackage(file.getName()) && !packages.isDefinedAt(file.getName())) - packages(file.getName()) = directory.find(file.getName(), true); - else if (dir.compile && !file.isDirectory() && file.getName().endsWith(".scala")) { - val name = file.getName().substring(0, file.getName().length() - (".scala").length()); - if (isValid(name) && !classes.isDefinedAt(name)) - classes(name) = directory.find(name, false); - } - } + for (val dir <- directory.entries) if (dir.source != null) { + val jt = dir.source.location.list(); + while (jt.hasNext()) { + val file = jt.next().asInstanceOf[AbstractFile]; + if (file.isDirectory() && directory.validPackage(file.getName()) && !packages.isDefinedAt(file.getName())) + packages(file.getName()) = directory.find(file.getName(), true); + else if (dir.source.compile && !file.isDirectory() && file.getName().endsWith(".scala")) { + val name = file.getName().substring(0, file.getName().length() - (".scala").length()); + if (isValid(name) && !classes.isDefinedAt(name)) + classes(name) = directory.find(name, false); + } + } } //if (!packages.isEmpty) System.err.println("COMPLETE: " + packages); //if (! classes.isEmpty) System.err.println("COMPLETE: " + classes); // do classes first for (val Pair(name, file) <- classes.elements) { - val loader = if (!file.isSourceFile) new ClassfileLoader(file.file, file.sourceFile, file.sourcePath); - else new SourcefileLoader(file.file); - enterClassAndModule(name, loader); + val loader = if (!file.isSourceFile) { + // System.err.println("CLASSFILE: " + file.file + " in " + file); + new ClassfileLoader(file.file, file.sourceFile, file.sourcePath); + } else { + assert(file.sourceFile != null); + //System.err.println("SOURCEFILE: " + file.sourceFile + " in " + file); + new SourcefileLoader(file.sourceFile); + } + enterClassAndModule(name, loader); } for (val Pair(name, file) <- packages.elements) enterPackage(name, new PackageLoader(file)); } diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index afb12542a2..4658fac231 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -43,141 +43,101 @@ object ClassPath { } - class Context(val classes : List[AbstractFile], val sources : List[Source]) { - def find(name : String, isDir : boolean) = if (isPackage) { - def find0(classes : List[AbstractFile], sources : List[Source]) : Context = { - //assert(classes.length == sources.length); - if (classes.isEmpty || sources.isEmpty) new Context(Nil, Nil); + class Context(val entries : List[Entry]) { + def find(name : String, isDir : boolean) : Context = if (isPackage) { + def find0(entries : List[Entry]) : Context = { + if (entries.isEmpty) new Context(Nil); else { - val ret = find0(classes.tail, sources.tail); - - val clazz = if (classes.head == null) null; else - classes.head.lookupPath(name + (if (!isDir) ".class" else ""), isDir); - - val source = { - if (sources.head == null) null; - else { - val source0 = sources.head.location.lookupPath(name + (if (!isDir) ".scala" else ""), isDir); - if (source0 != null && isDir) source0; - else if (clazz != null && !isDir) sources.head.location; // directory where we can find source. - else null; - } + val ret = find0(entries.tail); + val head = entries.head; + + + val clazz = if (head.location == null) null; else + head.location.lookupPath(name + (if (!isDir) ".class" else ""), isDir); + + val source0 = if (head.source == null) null; else { + val source1 = head.source.location.lookupPath(name + (if (isDir) "" else ".scala"), isDir); + if (source1 == null && !isDir && clazz != null) head.source.location; + else source1; + } + if (clazz == null && source0 == null) ret; + else { + object entry extends Entry { + override def location = clazz; + override def source = + if (source0 == null) null; + else new Source(source0, head.source.compile); + }; + new Context(entry :: ret.entries); } - if (clazz == null && source == null) ret; - else new Context(clazz :: ret.classes, - (if (source != null) new Source(source, sources.head.compile) else null) - :: ret.sources); } } - val ret = find0(classes, sources); + val ret = find0(entries); + if (false && this.toString().indexOf("scala") != -1) + System.err.println("FIND " + name + " in " + this + " => " + ret); ret; } else null; def isPackage = { - //assert(classes.length == sources.length); - if (classes.isEmpty) true; - else if (classes.head != null) classes.head.isDirectory(); - else if (!sources.isEmpty && sources.head != null && sources.head.location != null) sources.head.location.isDirectory(); - else true; + if (entries.isEmpty) false; + else if (entries.head.location != null) entries.head.location.isDirectory(); + else entries.head.source.location.isDirectory(); } def name = { - if (classes.isEmpty) ""; + if (entries.isEmpty) ""; else { - val name = if (classes.head != null) classes.head.getName() else sources.head.location.getName(); + val head = entries.head; + + val name = if (head.location != null) head.location.getName() else head.source.location.getName(); if (isPackage) name; else name.substring(0, name.length() - (".class").length()); } } - override def toString(): String = toString(classes, sources); + override def toString(): String = toString(entries); - def toString(classes0: List[AbstractFile], sources0: List[Source]): String = - if (classes0.isEmpty) ""; - else - ((if (classes0.head == null) "" else classes0.head.toString()) + (if (sources0.head != null) { - "::" + sources0.head.location.toString(); - } else "")) + ":" + toString(classes0.tail, sources0.tail); + def toString(entry : Entry): String = + ((if (entry.location == null) ""; + else entry.location.toString()) + + (if (entry.source == null) ""; else " with_source=" + entry.source.location.toString())); - def file = { - assert(!isPackage); - if (classes.isEmpty) null; - else if (sources.head == null || sources.head.location.isDirectory() || !sources.head.compile) { - assert(classes.head != null); - classes.head; - } else if (classes.head == null) { - sources.head.location; - } else if (sources.head.location.lastModified() >= classes.head.lastModified()) sources.head.location; - else classes.head; - } - def isSourceFile = file.getName().endsWith(".scala"); + def toString(entries0: List[Entry]): String = + if (entries0.isEmpty) ""; + else toString(entries0.head) + ":::" + toString(entries0.tail); - def sourceFile = - if (sources.isEmpty || sources.head == null) null; - else if (sources.head.location.isDirectory()) null; - else sources.head.location; + def isSourceFile = + (!isPackage && !entries.isEmpty && entries.head.source != null && + entries.head.source.location.getFile().isFile()); - def sourcePath = - if (sources.isEmpty || sources.head == null) null; - else if (!sources.head.location.isDirectory()) null; - else sources.head.location; + def sourceFile = if (isSourceFile) entries.head.source.location else null; - def validPackage(name: String): Boolean = - if (name.equals("META-INF")) false; - else if (name.startsWith(".")) false; - else true; + def sourcePath = if (!isSourceFile && entries.head.source != null) entries.head.source.location else null; - def complete: List[Context] = { - assert(isPackage); - def complete0(classes: List[AbstractFile], sources: List[Source]): List[Context] = - if (classes.isEmpty) Nil; - else if (classes.head == null && sources.head == null) complete0(classes.tail, sources.tail); + def file = { + if (entries.isEmpty) null; /* file not found */ + else if (isPackage) null; else { - var ret : List[Context] = Nil; - if (classes.head != null) { - val i = classes.head.list(); - while (i.hasNext()) { - val file = i.next().asInstanceOf[AbstractFile]; - if (!file.isDirectory() && file.getName().endsWith(".class")) { - val name = file.getName().substring(0, file.getName().length() - (".class").length()); - ret = find(name, false) :: ret; - } else if (file.isDirectory() && validPackage(file.getName())) { - ret = (find(file.getName(), true) :: ret); - // System.err.println("FILE: " + file.getName() + " RET=" + ret.head); - } - } - } - if (sources.head != null && sources.head.compile) { - val j = sources.head.location.list(); - while (j.hasNext()) { - val file = j.next().asInstanceOf[AbstractFile]; - if (!file.isDirectory() && file.getName().endsWith(".scala")) { - val name = file.getName().substring(0, file.getName().length() - (".scala").length()); - if (classes.head == null || - classes.head.lookupPath(name + ".class", false) == null) ret = find(name, false) :: ret; - } else if (file.isDirectory() && validPackage(file.getName())) { - if (classes.head == null || classes.head.lookupPath(file.getName(), true) == null) - ret = find(file.getName(), true) :: ret; - } - } - } - ret ::: complete0(classes.tail, sources.tail); + def clazz = entries.head.location; + def source = if (entries.head.source == null) null else entries.head.source.location; + assert(!(clazz == null && source == null)); + if (clazz == null) source; + else if (source == null) clazz; + else if (source.getFile().isFile() && source.lastModified() > clazz.lastModified()) source; + else clazz; } - complete0(classes, sources); } - - } // class Context - + def validPackage(name: String): Boolean = + if (name.equals("META-INF")) false; + else if (name.startsWith(".")) false; + else true; + } class Build { val entries = new ArrayBuffer[Entry]; - def root = { - val classes = for (val entry <- entries.toList) yield entry.location - val sources = for (val entry <- entries.toList) yield entry.source - new Context(classes, sources) - } + def root = new Context(entries.toList); def this(classpath : String, source : String, output : String, boot : String, extdirs : String) = { @@ -189,9 +149,11 @@ object ClassPath { while (strtok.hasMoreTokens()) { val output0 = (new Output(AbstractFile.getDirectory(output), AbstractFile.getDirectory(strtok.nextToken()))); if (output0.location == null) throw new FileNotFoundException("output location \"" + output + "\" not found"); + //System.err.println("OUTPUT: " + output); entries += output0; } addFilesInPath(classpath); + //System.err.println("CLASSPATH: " + root); } def library(classes : String, sources : String) = { assert(classes != null); -- cgit v1.2.3