* 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 git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@15422 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
b4972fd59c
commit
31b57529a2
|
@ -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 {
|
||||
|
|
|
@ -16,8 +16,8 @@ import scala.xml.{NodeSeq, Text, Unparsed, Utility}
|
|||
*
|
||||
* @author Sean McDirmid, Stephane Micheloud
|
||||
*/
|
||||
trait ModelFrames extends ModelExtractor {
|
||||
import DocUtil._
|
||||
trait ModelFrames extends ModelExtractor {
|
||||
import DocUtil._
|
||||
def settings: doc.Settings
|
||||
import global.definitions.{AnyClass, AnyRefClass}
|
||||
|
||||
|
@ -53,9 +53,9 @@ trait ModelFrames extends ModelExtractor {
|
|||
protected val NAME_SUFFIX_OBJECT = "$object"
|
||||
protected val NAME_SUFFIX_PACKAGE = "$package"
|
||||
|
||||
def rootTitle = <div class="page-title">{docTitle}</div>;
|
||||
def rootTitle = (<div class="page-title">{docTitle}</div>);
|
||||
def rootDesc =
|
||||
<p>{load("This document is the API specification for " + windowTitle)}</p>;
|
||||
(<p>{load("This document is the API specification for " + windowTitle)}</p>);
|
||||
|
||||
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 =
|
||||
<div>
|
||||
(<div>
|
||||
<div class="doctitle-larger">{windowTitle}</div>
|
||||
<a href="all-classes.html" target={classesFrame} onclick="resetKind();">{"All objects and classes"}</a>
|
||||
</div>
|
||||
<div class="kinds">Packages</div>
|
||||
<ul class="list">{sort(packages).mkXML("","\n","")(pkg => {
|
||||
<li><a href={urlFor(pkg)} target={classesFrame} onclick="resetKind();">
|
||||
{pkg.fullName('.')}</a></li>
|
||||
(<li><a href={urlFor(pkg)} target={classesFrame} onclick="resetKind();">
|
||||
{pkg.fullName('.')}</a></li>)
|
||||
})}
|
||||
</ul>;
|
||||
</ul>);
|
||||
}
|
||||
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} ++ <hr/> ++
|
||||
<table cellpadding="3" class="member" summary="">
|
||||
{rootTitle} ++ {rootDesc} ++ (<hr/>) ++
|
||||
(<table cellpadding="3" class="member" summary="">
|
||||
<tr><td colspan="2" class="title">Package Summary</td></tr>
|
||||
{sort(packages).mkXML("","\n","")(pkg => <tr><td class="signature">
|
||||
{sort(packages).mkXML("","\n","")(pkg => (<tr><td class="signature">
|
||||
<code>package
|
||||
{aref(pkgPath(pkg.sym) + "$content.html", "_self", pkg.fullName('.'))}
|
||||
</code>
|
||||
</td></tr>)}
|
||||
</table>;
|
||||
</td></tr>))}
|
||||
</table>);
|
||||
}
|
||||
|
||||
val classFrameKinds = Classes :: Objects :: Nil;
|
||||
|
@ -222,33 +223,33 @@ trait ModelFrames extends ModelExtractor {
|
|||
|
||||
def body: NodeSeq = {
|
||||
val nav = if (navLabel == null) NodeSeq.Empty else
|
||||
<table class="navigation" summary="">
|
||||
(<table class="navigation" summary="">
|
||||
<tr><td valign="top" class="navigation-links">
|
||||
{aref(navPath, contentFrame, navLabel)}
|
||||
</td></tr>
|
||||
</table>;
|
||||
</table>);
|
||||
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) <li>{seq}</li>;
|
||||
if (ids contains id) (<li>{seq}</li>);
|
||||
else {
|
||||
ids += id;
|
||||
<li id={id}>{seq}</li>
|
||||
(<li id={id}>{seq}</li>)
|
||||
};
|
||||
}
|
||||
val body = <div>{classFrameKinds.mkXML("","\n","")(kind => {
|
||||
val body = (<div>{classFrameKinds.mkXML("","\n","")(kind => {
|
||||
val classes = sort(this.classes.filter(e => kind.f(e.sym)));
|
||||
if (classes.isEmpty) NodeSeq.Empty; else
|
||||
<div id={kind.plural} class="kinds">{Text(kind.plural)}</div>
|
||||
(<div id={kind.plural} class="kinds">{Text(kind.plural)}</div>
|
||||
<ul class="list">
|
||||
{classes.mkXML("","\n","")(cls => {
|
||||
idFor(kind, cls)(
|
||||
aref(urlFor(cls), contentFrame, cls.listName) ++ optional(cls)
|
||||
);
|
||||
})}
|
||||
</ul>;
|
||||
})}</div>;
|
||||
</ul>);
|
||||
})}</div>);
|
||||
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
|
||||
<table cellpadding="3" class="member" summary="">
|
||||
(<table cellpadding="3" class="member" summary="">
|
||||
<tr><td colspan="2" class="title">{kind.label} Summary</td></tr>
|
||||
{classes.mkXML("","\n","")(shortHeader)}
|
||||
</table>
|
||||
</table>)
|
||||
})};
|
||||
}
|
||||
|
||||
abstract class ClassContentFrame extends Frame {
|
||||
def clazz: ClassOrObject
|
||||
def body: NodeSeq =
|
||||
<xml:group>
|
||||
(<xml:group>
|
||||
{pageHeader}{navigation}{pageTop}
|
||||
{header0}{longHeader(clazz)}
|
||||
{pageBottom}{navigation}{pageFooter}
|
||||
</xml:group>;
|
||||
</xml:group>);
|
||||
final def path = urlFor0(clazz.sym, clazz.sym)
|
||||
private def navigation: NodeSeq =
|
||||
<table class="navigation" summary="">
|
||||
(<table class="navigation" summary="">
|
||||
<tr>
|
||||
<td valign="top" class="navigation-links">
|
||||
<!-- <table><tr></tr></table> -->
|
||||
|
@ -290,10 +291,10 @@ trait ModelFrames extends ModelExtractor {
|
|||
</td>
|
||||
</tr>
|
||||
<tr><td></td></tr>
|
||||
</table>;
|
||||
</table>);
|
||||
private def header0: NodeSeq = {
|
||||
val owner = decode(clazz.sym.owner)
|
||||
<xml:group>
|
||||
(<xml:group>
|
||||
<div class="entity">
|
||||
{aref(urlFor(owner), "_self", owner.fullNameString('.'))}
|
||||
<br/>
|
||||
|
@ -306,26 +307,26 @@ trait ModelFrames extends ModelExtractor {
|
|||
else {
|
||||
val name = owner.fullNameString('/') + (if (owner.isPackage) "/" + clazz.name else "")
|
||||
Text("[source: ") ++
|
||||
<a class={name} href=""><code>{name + ".scala"}</code></a> ++
|
||||
(<a class={name} href=""><code>{name + ".scala"}</code></a>) ++
|
||||
Text("]")
|
||||
}
|
||||
}
|
||||
</div><hr/>
|
||||
</xml:group>
|
||||
</xml:group>)
|
||||
}
|
||||
}
|
||||
|
||||
val index =
|
||||
<frameset cols="25%, 75%">
|
||||
(<frameset cols="25%, 75%">
|
||||
<frameset rows="50%, 28, 50%">
|
||||
<frame src="modules.html" name={modulesFrame}></frame>
|
||||
<frame src="nav-classes.html" name="navigationFrame"></frame>
|
||||
<frame src="all-classes.html" name={classesFrame}></frame>
|
||||
</frameset>
|
||||
<frame src="root-content.html" name={contentFrame}></frame>
|
||||
</frameset>;
|
||||
</frameset>);
|
||||
|
||||
val root = <b></b>;
|
||||
val root = (<b></b>);
|
||||
|
||||
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 <body style="margin:1px 0 0 1px; padding:1px 0 0 1px;">{nodes}</body>;
|
||||
else (<body style="margin:1px 0 0 1px; padding:1px 0 0 1px;">{nodes}</body>);
|
||||
def body =
|
||||
<form>
|
||||
(<form>
|
||||
<select id="kinds" onchange="gotoKind()">
|
||||
<option value="#Classes" selected="selected">Classes</option>
|
||||
<option value="#Objects">Objects</option>
|
||||
</select>
|
||||
<span id="alphabet" style="font-family:Courier;word-spacing:-8px;">{
|
||||
indexChars.mkXML("","\n","")(c => {
|
||||
<a href={Unparsed("javascript:gotoName(\'" + c + "\')")}>{c}</a>
|
||||
(<a href={Unparsed("javascript:gotoName(\'" + c + "\')")}>{c}</a>)
|
||||
});
|
||||
}
|
||||
</span>
|
||||
</form>
|
||||
</form>)
|
||||
}
|
||||
|
||||
def copyResources = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 _ =>
|
||||
|
|
|
@ -12,7 +12,7 @@ import scala.compat.Platform.currentTime
|
|||
import scala.tools.nsc.ast.TreeGen
|
||||
import scala.tools.nsc.util.{HashSet, Position, NoPosition}
|
||||
import Flags._
|
||||
|
||||
|
||||
/* A standard type pattern match:
|
||||
case ErrorType =>
|
||||
// internal: error
|
||||
|
@ -26,7 +26,7 @@ import Flags._
|
|||
// pre.sym.type
|
||||
case ConstantType(value) =>
|
||||
// int(2)
|
||||
case TypeRef(pre, sym, args) =>
|
||||
case TypeRef(pre, sym, args) =>
|
||||
// pre.sym[targs]
|
||||
case RefinedType(parents, defs) =>
|
||||
// parent1 with ... with parentn { defs }
|
||||
|
@ -58,9 +58,10 @@ import Flags._
|
|||
case DeBruijnIndex(level, index)
|
||||
*/
|
||||
|
||||
trait Types {
|
||||
trait Types {
|
||||
self: SymbolTable =>
|
||||
import definitions._
|
||||
|
||||
|
||||
//statistics
|
||||
var singletonClosureCount = 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
|
||||
else {
|
||||
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)
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -15,7 +15,7 @@ import scala.compat.Platform.currentTime
|
|||
import scala.tools.nsc.util.{HashSet, Position, Set, NoPosition, SourceFile}
|
||||
import symtab.Flags._
|
||||
import util.HashSet
|
||||
|
||||
|
||||
// Suggestion check whether we can do without priminng scopes with symbols of outer scopes,
|
||||
// like the IDE does.
|
||||
/** This trait provides methods to assign types to trees.
|
||||
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue