From e18907e87ff7000d3547699cc3b8b5beaee7f4fc Mon Sep 17 00:00:00 2001 From: Sean McDirmid Date: Tue, 24 Jun 2008 08:43:05 +0000 Subject: * scaladoc - changed two objects into vals to a... * scaladoc - changed two objects into vals to avoid NPE in current build. - made model frame XML IDE friendly * IDE - hardening of various crashes - better semantic highlighting --- .../scala/tools/nsc/doc/DefaultDocDriver.scala | 4 +- src/compiler/scala/tools/nsc/doc/ModelFrames.scala | 71 +++++++------- .../scala/tools/nsc/symtab/IdeSupport.scala | 102 +++++++++++---------- .../scala/tools/nsc/symtab/SymbolWalker.scala | 23 ++++- src/compiler/scala/tools/nsc/symtab/Types.scala | 20 ++-- .../scala/tools/nsc/typechecker/IdeSupport.scala | 8 +- .../scala/tools/nsc/typechecker/Namers.scala | 16 +++- .../scala/tools/nsc/typechecker/Typers.scala | 3 +- 8 files changed, 149 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/doc/DefaultDocDriver.scala b/src/compiler/scala/tools/nsc/doc/DefaultDocDriver.scala index 4e43852bf6..32ab8d64cd 100644 --- a/src/compiler/scala/tools/nsc/doc/DefaultDocDriver.scala +++ b/src/compiler/scala/tools/nsc/doc/DefaultDocDriver.scala @@ -19,8 +19,8 @@ abstract class DefaultDocDriver extends DocDriver with ModelFrames with ModelToX import global._ import definitions.{AnyClass, AnyRefClass} - object additions extends jcl.LinkedHashSet[Symbol] - object additions0 extends ModelAdditions(global) { + val additions = new jcl.LinkedHashSet[Symbol] + val additions0 = new ModelAdditions(global) { override def addition(sym: global.Symbol) = { super.addition(sym) sym match { diff --git a/src/compiler/scala/tools/nsc/doc/ModelFrames.scala b/src/compiler/scala/tools/nsc/doc/ModelFrames.scala index 660b90b460..ed933c5c17 100644 --- a/src/compiler/scala/tools/nsc/doc/ModelFrames.scala +++ b/src/compiler/scala/tools/nsc/doc/ModelFrames.scala @@ -53,9 +53,9 @@ trait ModelFrames extends ModelExtractor { protected val NAME_SUFFIX_OBJECT = "$object" protected val NAME_SUFFIX_PACKAGE = "$package" - def rootTitle =
{docTitle}
; + def rootTitle = (
{docTitle}
); def rootDesc = -

{load("This document is the API specification for " + windowTitle)}

; + (

{load("This document is the API specification for " + windowTitle)}

); final def hasLink(sym: global.Symbol): Boolean = if (sym == global.NoSymbol) false @@ -70,6 +70,7 @@ trait ModelFrames extends ModelExtractor { } def path: String // relative to outdir def relative: String = { + if (path eq null) return "foo" assert(path ne null) var idx = 0 var ct = new StringBuilder @@ -180,16 +181,16 @@ trait ModelFrames extends ModelExtractor { override val title = "List of all packages" def packages: Iterable[Package] override def body: NodeSeq = -
+ (
{windowTitle}
{"All objects and classes"}
Packages
; + ); } abstract class PackagesContentFrame extends Frame { val path = "root-content" @@ -197,15 +198,15 @@ trait ModelFrames extends ModelExtractor { def packages : Iterable[Package] //def modules: TreeMap[String, ModuleClassSymbol] def body: NodeSeq = - {rootTitle} ++ {rootDesc} ++
++ - + {rootTitle} ++ {rootDesc} ++ (
) ++ + (
- {sort(packages).mkXML("","\n","")(pkg => )} -
Package Summary
+ {sort(packages).mkXML("","\n","")(pkg => (
package {aref(pkgPath(pkg.sym) + "$content.html", "_self", pkg.fullName('.'))} -
; + ))} + ); } val classFrameKinds = Classes :: Objects :: Nil; @@ -222,33 +223,33 @@ trait ModelFrames extends ModelExtractor { def body: NodeSeq = { val nav = if (navLabel == null) NodeSeq.Empty else - + ( - ; + ); val ids = new jcl.LinkedHashSet[String] def idFor(kind: Category, t: Entity)(seq : NodeSeq): NodeSeq = { val ch = t.listName.charAt(0); val id = kind.plural + "_" + ch; - if (ids contains id)
  • {seq}
  • ; + if (ids contains id) (
  • {seq}
  • ); else { ids += id; -
  • {seq}
  • + (
  • {seq}
  • ) }; } - val body =
    {classFrameKinds.mkXML("","\n","")(kind => { + val body = (
    {classFrameKinds.mkXML("","\n","")(kind => { val classes = sort(this.classes.filter(e => kind.f(e.sym))); if (classes.isEmpty) NodeSeq.Empty; else -
    {Text(kind.plural)}
    + (
    {Text(kind.plural)}
      {classes.mkXML("","\n","")(cls => { idFor(kind, cls)( aref(urlFor(cls), contentFrame, cls.listName) ++ optional(cls) ); })} -
    ; - })}
    ; + ); + })}
    ); nav ++ body } def optional(cls: ClassOrObject): NodeSeq = NodeSeq.Empty @@ -263,24 +264,24 @@ trait ModelFrames extends ModelExtractor { {rootTitle} ++ {rootDesc} ++ {classFrameKinds.mkXML("","\n","")(kind => { val classes = sort(this.classes.filter(e => kind.f(e.sym) && e.isInstanceOf[TopLevel])); if (classes.isEmpty) NodeSeq.Empty else - + (
    {classes.mkXML("","\n","")(shortHeader)} -
    {kind.label} Summary
    + ) })}; } abstract class ClassContentFrame extends Frame { def clazz: ClassOrObject def body: NodeSeq = - + ( {pageHeader}{navigation}{pageTop} {header0}{longHeader(clazz)} {pageBottom}{navigation}{pageFooter} - ; + ); final def path = urlFor0(clazz.sym, clazz.sym) private def navigation: NodeSeq = - + ( - ; + ); private def header0: NodeSeq = { val owner = decode(clazz.sym.owner) - + (
    {aref(urlFor(owner), "_self", owner.fullNameString('.'))}
    @@ -306,26 +307,26 @@ trait ModelFrames extends ModelExtractor { else { val name = owner.fullNameString('/') + (if (owner.isPackage) "/" + clazz.name else "") Text("[source: ") ++ - {name + ".scala"} ++ + ({name + ".scala"}) ++ Text("]") } }

    -
    +
    ) } } val index = - + ( - ; + ); - val root = ; + val root = (); abstract class RootFrame extends Frame { def title = windowTitle @@ -341,20 +342,20 @@ trait ModelFrames extends ModelExtractor { def path="nav-classes" override def body0(hasBody: Boolean, nodes: NodeSeq): NodeSeq = if (!hasBody) nodes - else {nodes}; + else ({nodes}); def body = -
    + ( { indexChars.mkXML("","\n","")(c => { - {c} + ({c}) }); } -
    + ) } def copyResources = { diff --git a/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala b/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala index 0805d4f820..44a6c1d95b 100644 --- a/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala +++ b/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala @@ -13,6 +13,10 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. def verifyAndPrioritize[T](verify : Symbol => Symbol)(pt : Type)(f : => T) : T = f def makeNoChanges : Boolean = false } + def check(condition : Boolean, msg : => String) = { + assert(condition) + condition + } override def inIDE = true import CompatibleResult._ @@ -72,21 +76,21 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. var delete = List[Symbol]() while (e != null && e.sym != sym) { if (false && !e.sym.rawInfo.isComplete) { - assert(true) + delete = e.sym :: delete } e = scope.lookupNextEntry(e) } delete.foreach(scope.unlink) if (e != null && e.sym == sym) { - assert(true) + val list = reuseMap.get(scope) match { case Some(list) => list case None => val list = new jcl.LinkedList[Symbol] reuseMap(scope) = list; list } - assert(!sym.isPackage) + check(!sym.isPackage, "" +sym) import symtab.Flags._ // if def is abstract, will only unlink its name if (sym.isGetter) { @@ -101,16 +105,16 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. while (e != null && !e.sym.isGetter && e.sym.accessed != sym) { e = scope lookupNextEntry e } - if (e != null) { + if (e != null && check(e.sym.accessed == sym, "accessed" + e.sym.accessed +" vs. " + sym) && check(!e.sym.isSetter, "setter: " + e.sym)) { val getter = e.sym - assert(e.sym.accessed == sym && !e.sym.isSetter) + check(e.sym.accessed == sym && !e.sym.isSetter, e.sym.toString) list += getter scope unlink getter //Console.println("RS-UNLINK: " + getter) e = scope lookupEntry nme.getterToSetter(getter.name) while (e != null && !e.sym.isSetter) e = scope lookupNextEntry e if (e != null) { - assert(getter.accessed == sym) + check(getter.accessed == sym, "" + getter + " vs. " + sym) val setter = e.sym list += setter scope unlink setter @@ -134,14 +138,14 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. val buf = new jcl.LinkedList[Symbol] scope.toList.foreach{sym => if (false && sym.hasFlag(Flags.CASE) && sym.hasFlag(Flags.SYNTHETIC)) { - assert(sym != null) + check(sym != null, "") } else { buf add sym scope unlink sym } } if (!buf.isEmpty) { - assert(true) + reuseMap.get(scope) match { case Some(buf0) => buf.foreach(buf0.+=) case None => reuseMap(scope) = buf @@ -151,7 +155,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. } def reloadSource(file : AbstractFile) = { - assert(true) + if (!currentClient.makeNoChanges) topDefs.removeKey(file) match { case None => case Some(symbols) => symbols.foreach{sym => @@ -159,12 +163,11 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. case scope : PersistentScope => reuse(scope, (sym)) } if (sym.isModuleClass) { - assert(sym.name.isTypeName) - if (sym.hasRawInfo) + if (check(sym.name.isTypeName,"") && sym.hasRawInfo) if (sym.linkedModuleOfClass != NoSymbol) f(sym.linkedModuleOfClass) } else { - assert(sym.name.isTypeName) - f(sym) + if (check(sym.name.isTypeName, "")) + f(sym) } } } @@ -199,7 +202,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. case None => }) if (resetType) { - assert(true) + sym.setInfo(oldType) // restore old good type. } } @@ -312,12 +315,10 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. } def finish(symbol : Symbol) = { if (symbol.isTypeSkolem) { - assert(true) - assert(true) + } if (symbol.owner.isPackageClass && !symbol.isPackageClass && symbol.sourceFile != null) { - assert(true) - assert(true) + topDefs(symbol.sourceFile) += (symbol match { case symbol : ClassSymbol => symbol case symbol : ModuleSymbol => symbol.moduleClass.asInstanceOf[ClassSymbol] @@ -325,13 +326,20 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. } super.enter(symbol) } - def nuke(existing: Symbol, other : Symbol) : Unit = { + def nuke(existing: Symbol) : Unit = { if (existing.isMonomorphicType) existing.resetFlag(Flags.MONOMORPHIC) assert(!existing.isPackage) existing.attributes = Nil // reset attributes, we don't look at these. - existing.setInfo(if (other.hasRawInfo) other.rawInfo else NoType) - if (existing.isModule && existing.moduleClass != NoSymbol) - nuke(existing.moduleClass,symbol.moduleClass) + if (existing.isModuleClass) { + //Console.println("NUKE_N: " + existing + " " + existing.id) + } else { + existing.setInfo(if (symbol.hasRawInfo) symbol.rawInfo else NoType) + } + if (existing.isModule && existing.moduleClass != NoSymbol){ + //Console.println("NUKE_0: " + existing + " " + existing.id) + //Console.println("NUKE_1: " + existing.moduleClass + " " + existing.moduleClass.id) + existing.moduleClass.setInfo(if (symbol.moduleClass.hasRawInfo) symbol.moduleClass.rawInfo else NoType) + } } def reuse(existing : Symbol) : Symbol = { @@ -340,10 +348,9 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. tracedTypes(existing) = existing.info } record(existing) - nuke(existing,symbol) + nuke(existing) if (existing.pos == NoPosition) { - assert(true) - assert(true) + } finish(existing) @@ -360,7 +367,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. if (code.isInstanceOf[Updated]) { invalidate(existing.name) } - nuke(existing,symbol) + nuke(existing) return (existing) } } @@ -371,7 +378,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. while (i.hasNext) { var existing = i.next if (existing == symbol) return { - assert(true) + i.remove finish(existing) } @@ -383,25 +390,25 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. case _ => existing.name == symbol.name } }) { - assert(existing != NoSymbol) - val oldName = existing.name - compatible(existing, symbol) match { - case NotCompatible => - assert(true) - assert(true) - case code@GoResult(existing0) => - i.remove - existing = existing0 - if (code.isInstanceOf[Updated]) { - invalidate(oldName) - invalidate(existing.name) + if (check(existing != NoSymbol,"")) { + val oldName = existing.name + compatible(existing, symbol) match { + case NotCompatible => + + case code@GoResult(existing0) => + i.remove + existing = existing0 + if (code.isInstanceOf[Updated]) { + invalidate(oldName) + invalidate(existing.name) + } + return (reuse(existing)) } - return (reuse(existing)) } } } if (true) { - assert(true) + //Console.println("NEW SYMBOL: " + symbol + ":" + symbol.id + " @ " + symbol.owner + " " + key); } invalidate(symbol.name) @@ -447,8 +454,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. } if (((existing.flags&(MONOMORPHIC|INTERFACE)) != 0) || ((symbol .flags&(MONOMORPHIC|INTERFACE)) != 0)) { - assert(true) - assert(true) + } val ret = (existing.owner == symbol.owner || { existing.owner.name == symbol.owner.name && // why???? @@ -489,7 +495,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. case Some(scope) => scope case None => val scope = new PersistentScope(kind,this) - assert(scope.key == kind) + check(scope.key == kind, ""+scope.key + " " + scope.toString) scopes = (scope) :: scopes scope } @@ -507,10 +513,10 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. override def newClassScope(clazz : Symbol) = { newDefScope0({ if (clazz.isModuleClass && !clazz.isPackageClass) { - assert(true) + clazz } else if (clazz.isModule && !clazz.isPackage) { - assert(true) + clazz.moduleClass } else clazz }, ClassKind) @@ -600,7 +606,11 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. } // mostly intellisense hacks. override def verifyAndPrioritize[T](verify : Symbol => Symbol)(pt : Type)(f : => T) : T = { + try { currentClient.verifyAndPrioritize(verify)(pt)(f) + } catch {case e : Error=> + throw e + } } override def compare(sym : Symbol, name : Name) = { val client = currentClient diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala b/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala index 0c084a1e3c..dc39860bc2 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala @@ -173,6 +173,14 @@ trait SymbolWalker { } } 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 @@ -224,7 +232,20 @@ trait SymbolWalker { 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 => f(tree.rhs); fs(tree.tparams) + case tree : TypeDef => + assert(true) + (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 _ => diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 768b072447..fbfae15b15 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -62,6 +62,7 @@ trait Types { self: SymbolTable => import definitions._ + //statistics var singletonClosureCount = 0 var compoundClosureCount = 0 @@ -250,7 +251,7 @@ trait Types { */ def narrow: Type = if (phase.erasedTypes) this - else refinedType(List(this), commonOwner(this), EmptyScope).narrow + else refinedType(List(this), commonOwner(this), EmptyScope, commonOwner(this).pos).narrow /** For a TypeBounds type, itself; * for a reference denoting an abstract type, its bounds, @@ -1920,14 +1921,17 @@ A type's typeSymbol should never be inspected directly. } /** the canonical creator for a refined type with a given scope */ - def refinedType(parents: List[Type], owner: Symbol, decls: Scope): Type = { + def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos : Position): Type = { if (phase.erasedTypes) if (parents.isEmpty) ObjectClass.tpe else parents.head else { - val clazz = recycle(owner.newRefinementClass(if (inIDE) owner.pos else NoPosition)) - val result = refinementOfClass(clazz, parents, decls) - clazz.setInfo(result) - result + val clazz = recycle(owner.newRefinementClass(if (inIDE) pos else NoPosition)) + if (!inIDE || !parents.isEmpty) { + val result = refinementOfClass(clazz, parents, decls) + clazz.setInfo(result) + result + } else clazz.info + //result } } @@ -1938,7 +1942,7 @@ A type's typeSymbol should never be inspected directly. * @return ... */ def refinedType(parents: List[Type], owner: Symbol): Type = - refinedType(parents, owner, newTempScope) + refinedType(parents, owner, newTempScope, owner.pos) def copyRefinedType(original: RefinedType, parents: List[Type], decls: Scope) = if ((parents eq original.parents) && (decls eq original.decls)) original @@ -3135,7 +3139,7 @@ A type's typeSymbol should never be inspected directly. case RefinedType(parents, decls) => val parents1 = List.mapConserve(parents)(this) if (parents1 eq parents) tp - else refinedType(parents1, tp.typeSymbol.owner, decls) + else refinedType(parents1, tp.typeSymbol.owner, decls, tp.typeSymbol.owner.pos) case SuperType(_, _) => mapOver(tp) case TypeBounds(_, _) => mapOver(tp) case MethodType(_, _) => mapOver(tp) diff --git a/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala b/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala index 6cce427a14..4781288caf 100644 --- a/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala +++ b/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala @@ -120,7 +120,13 @@ trait IdeSupport extends Analyzer { if (tree.tpe == null) tree.tpe = tree.underlying.updateTyper(this, mode, pt) tree - case tree => super.typed1(tree, mode, pt) + case tree => + try { + super.typed1(tree, mode, pt) + } catch { + case e : TypeError => throw e + case e : Error => global.check(false, "tree: " + tree + " " + e); throw e + } } } private val toComplete = new scala.collection.jcl.LinkedHashSet[Symbol] diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index f9a6b96a67..caaecc1b90 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -429,8 +429,16 @@ trait Namers { self: Analyzer => validate(sym) } - def moduleClassTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym => - tree.symbol.info // sets moduleClass info as a side effect. + def moduleClassTypeCompleter(tree: Tree) = { + mkTypeCompleter(tree) { sym => + val moduleSymbol = tree.symbol + assert(moduleSymbol.moduleClass == sym) + if (inIDE && moduleSymbol.rawInfo.isComplete) { + // reset! + } + moduleSymbol.info // sets moduleClass info as a side effect. + //assert(sym.rawInfo.isComplete) + } } def getterTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym => @@ -598,7 +606,7 @@ trait Namers { self: Analyzer => var vparamSymss = if (inIDE && meth.isPrimaryConstructor) { // @S: because they have already been entered this way.... - assert(true) + enterValueParams(meth.owner.owner, vparamss) } else { enterValueParams(meth, vparamss) @@ -608,7 +616,7 @@ trait Namers { self: Analyzer => tpt setPos meth.pos } - if (onlyPresentation) + if (onlyPresentation && methodArgumentNames != null) methodArgumentNames(meth) = vparamss.map(_.map(_.symbol)); def convertToDeBruijn(vparams: List[Symbol], level: Int): TypeMap = new TypeMap { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index aec92302f4..2740d8944d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2942,7 +2942,8 @@ trait Typers { self: Analyzer => if (parents1 exists (_.tpe.isError)) tree setType ErrorType else { val decls = scopeFor(tree, CompoundTreeScopeKind) - val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls) + //Console.println("Owner: " + context.enclClass.owner + " " + context.enclClass.owner.id) + val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls, templ.pos) newTyper(context.make(templ, self.typeSymbol, decls)).typedRefinement(templ.body) tree setType self } -- cgit v1.2.3