summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala6
-rw-r--r--src/compiler/scala/tools/nsc/Main.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocGenerator.scala5
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocUtil.scala28
-rw-r--r--src/compiler/scala/tools/nsc/io/PlainFile.scala20
-rw-r--r--src/compiler/scala/tools/nsc/io/ZipArchive.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTable.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala21
12 files changed, 90 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index e9c23b27e5..8743a4d73e 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -105,6 +105,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val comments =
if (onlyPresentation) new HashMap[Symbol,String]
else null
+ val methodArgumentNames =
+ if (onlyPresentation) new HashMap[Symbol,List[List[Symbol]]];
+ else null;
// reporting -------------------------------------------------------
@@ -642,6 +645,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
def forCLDC: Boolean = settings.target.value == "cldc"
def forMSIL: Boolean = settings.target.value == "msil"
def onlyPresentation = settings.doc.value
+ // used to disable caching in lampion IDE.
+ def inIDE = false
+
// position stuff
final val positionConfiguration: PositionConfiguration = initConfig;
protected def initConfig : PositionConfiguration = posConfig;
diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala
index 82a0026c24..089a0f7d23 100644
--- a/src/compiler/scala/tools/nsc/Main.scala
+++ b/src/compiler/scala/tools/nsc/Main.scala
@@ -6,7 +6,7 @@
package scala.tools.nsc
-import scala.tools.nsc.doc.DocGenerator
+import scala.tools.nsc.doc.{DocDriver => DocGenerator}
import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
import scala.tools.nsc.util.FakePos //{Position}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 3d9ed750e4..a2da40d399 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -441,7 +441,7 @@ trait Trees requires Global {
vparamss map (.map (vd => {
val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations,
vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos)
- if (false/*inIDE*/ && vd.symbol != NoSymbol)
+ if (inIDE && vd.symbol != NoSymbol)
ret.symbol = vd.symbol
ret
}));
diff --git a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
index 41e83f8383..5ca3b6a323 100644
--- a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
@@ -214,8 +214,8 @@ abstract class DocGenerator extends Models {
</div>;
abstract class ListModuleFrame extends Frame {
- val path = "modules"
- val title = "List of all packages"
+ override val path = "modules"
+ override val title = "List of all packages"
def modules: TreeMap[String, ModuleClassSymbol]
def body: NodeSeq =
<div>
@@ -303,7 +303,6 @@ abstract class DocGenerator extends Models {
}
abstract class ContentFrame0 extends Frame {
-
private def extendsFor(mmbr: HasTree): NodeSeq = mmbr match {
case mmbr: ImplMod =>
val parents = mmbr.treey.impl.parents
diff --git a/src/compiler/scala/tools/nsc/doc/DocUtil.scala b/src/compiler/scala/tools/nsc/doc/DocUtil.scala
index 95f05605eb..34844c1367 100644
--- a/src/compiler/scala/tools/nsc/doc/DocUtil.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocUtil.scala
@@ -38,7 +38,12 @@ object DocUtil {
def relative: String
def aref(href0: String, target: String, text: String): NodeSeq = {
- val href = relative + Utility.escape(href0)
+ if (href0 == null) return Text(text);
+
+ val href = {
+ if (href0.startsWith("http:") || href0.startsWith("file:")) "";
+ else relative
+ } + Utility.escape(href0)
if ((target ne null) && target.indexOf('<') != -1) throw new Error(target)
val t0 = Text(text)
@@ -90,5 +95,26 @@ object DocUtil {
}
ts
}
+ implicit def coerceIterable[T](list : Iterable[T]) = NodeWrapper(list.elements);
+ implicit def coerceIterator[T](list : Iterator[T]) = NodeWrapper(list);
+ case class NodeWrapper[T](list : Iterator[T]) {
+ def mkXML(begin : NodeSeq, separator : NodeSeq, end : NodeSeq)(f : T => NodeSeq) : NodeSeq = {
+ var seq : NodeSeq = begin;
+ val i = list;
+ while (i.hasNext) {
+ seq = seq ++ f(i.next);
+ if (i.hasNext) seq = seq ++ separator;
+ }
+ seq ++ end;
+ }
+
+ def mkXML(begin : String, separator : String, end : String)(f : T => NodeSeq) : NodeSeq = {
+ this.mkXML(Text(begin),Text(separator),Text(end))(f);
+ }
+ def surround(open : String, close : String)(f : T => NodeSeq) = {
+ if (list.hasNext) mkXML(open, ", ", close)(f);
+ else NodeSeq.Empty;
+ }
+ }
}
diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala
index c863a30e68..cff9fac410 100644
--- a/src/compiler/scala/tools/nsc/io/PlainFile.scala
+++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala
@@ -10,10 +10,6 @@ package scala.tools.nsc.io
import java.io.{File, FileInputStream, IOException}
object PlainFile {
-
- /** Returns "fromFile(new File(path))". */
- //def fromPath(path: String): AbstractFile = fromFile(new File(path));
-
/**
* If the specified File exists, returns an abstract file backed
* by it. Otherwise, returns null.
@@ -26,6 +22,8 @@ object PlainFile {
/** This class implements an abstract file backed by a File.
*/
class PlainFile(val file: File) extends AbstractFile {
+ private val fpath = try { file.getCanonicalPath }
+ catch { case _: IOException => file.getAbsolutePath }
assert(file ne null)
assert(file.exists(), "non-existent file: " + file)
@@ -43,19 +41,11 @@ class PlainFile(val file: File) extends AbstractFile {
override def size = Some(file.length.toInt)
- override def hashCode(): Int =
- try { file.getCanonicalPath().hashCode() }
- catch { case _: IOException => 0 }
+ override def hashCode(): Int = fpath.hashCode
override def equals(that: Any): Boolean =
- try {
- that.isInstanceOf[PlainFile] &&
- file.getCanonicalPath().equals(that.asInstanceOf[PlainFile].file.getCanonicalPath());
- } catch {
- case _: IOException =>
- that.isInstanceOf[PlainFile] &&
- file.getAbsolutePath().equals(that.asInstanceOf[PlainFile].file.getAbsolutePath());
- }
+ that.isInstanceOf[PlainFile] &&
+ fpath.equals(that.asInstanceOf[PlainFile].fpath)
/** Is this abstract file a directory? */
def isDirectory: Boolean = file.isDirectory()
diff --git a/src/compiler/scala/tools/nsc/io/ZipArchive.scala b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
index 4f2482c112..e5c144db08 100644
--- a/src/compiler/scala/tools/nsc/io/ZipArchive.scala
+++ b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
@@ -181,13 +181,10 @@ final class ZipArchive(file: File, val archive: ZipFile) extends PlainFile(file)
/** A regular file archive entry */
final class FileEntry(name: String, path: String, val entry: ZipEntry)
- extends Entry(name, path)
- {
-
+ extends Entry(name, path) {
+ def archive = ZipArchive.this.archive;
override def lastModified: Long = entry.getTime()
-
override def read = archive.getInputStream(entry);
-
override def size = Some(entry.getSize().toInt)
}
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
index 60c795920e..c68d2dfee3 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
@@ -25,6 +25,8 @@ abstract class SymbolTable extends Names
/** Are we compiling for .NET*/
def forMSIL: Boolean
+ /** are we in a lampion presentation compiler? then disable caching. */
+ def inIDE : Boolean;
/** A period is an ordinal number for a phase in a run.
* Phases in later runs have higher periods than phases in earlier runs.
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 7011f7d809..31d28b79db 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -791,7 +791,7 @@ trait Symbols requires SymbolTable {
matchingSymbol(ofclazz, ofclazz.thisType)
final def allOverriddenSymbols: List[Symbol] =
- if (owner.isClass)
+ if (owner.isClass && !owner.info.baseClasses.isEmpty)
for { val bc <- owner.info.baseClasses.tail
val s = overriddenSymbol(bc)
s != NoSymbol } yield s
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 9e30b254aa..024d71b7e8 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -421,6 +421,7 @@ trait Types requires SymbolTable {
*/
//TODO: use narrow only for modules? (correct? efficiency gain?)
def findMember(name: Name, excludedFlags: int, requiredFlags: long, stableOnly: boolean): Symbol = {
+ if (inIDE) trackTypeIDE(symbol)
if (util.Statistics.enabled) findMemberCount = findMemberCount + 1
val startTime = if (util.Statistics.enabled) currentTime else 0l
@@ -628,6 +629,7 @@ trait Types requires SymbolTable {
private var singleDerefCache: Type = _
private var singleDerefPeriod = NoPeriod
override def singleDeref: Type = {
+ if (inIDE) return pre.memberType(sym).resultType
val period = singleDerefPeriod
if (period != currentPeriod) {
singleDerefPeriod = currentPeriod
@@ -783,6 +785,7 @@ trait Types requires SymbolTable {
override def closureDepth: int = { closure; closureDepthCache }
override def baseClasses: List[Symbol] = {
+ if (inIDE) trackTypeIDE(symbol)
def computeBaseClasses: List[Symbol] =
if (parents.isEmpty) List(symbol)
else {
@@ -831,11 +834,15 @@ trait Types requires SymbolTable {
}
override def baseType(sym: Symbol): Type = {
+ if (inIDE) { trackTypeIDE(sym); trackTypeIDE(symbol); }
val index = closurePos(sym)
if (index >= 0) closure(index) else NoType
}
- override def narrow: Type = symbol.thisType
+ override def narrow: Type = {
+ if (inIDE) trackTypeIDE(symbol)
+ symbol.thisType
+ }
// override def isNonNull: boolean = parents forall (.isNonNull);
@@ -1798,6 +1805,7 @@ trait Types requires SymbolTable {
def apply(tp: Type): Type = {
def subst(sym: Symbol, from: List[Symbol], to: List[T]): Type =
if (from.isEmpty) tp
+ else if (to.isEmpty && inIDE) throw new TypeError(NoPos, "type parameter list problem");
else if (matches(from.head, sym)) toType(tp, to.head)
else subst(sym, from.tail, to.tail)
tp match {
@@ -2187,6 +2195,8 @@ trait Types requires SymbolTable {
} finally {
stc = stc - 1
}
+ /** hook for IDE */
+ protected def trackTypeIDE(sym : Symbol) : Boolean = true;
/** Does type <code>tp1</code> conform to <code>tp2</code>?
*
@@ -2214,6 +2224,8 @@ trait Types requires SymbolTable {
case (TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) =>
//Console.println("isSubType " + tp1 + " " + tp2);//DEBUG
+ if (inIDE) { trackTypeIDE(sym1); trackTypeIDE(sym2); }
+
def isSubArgs(tps1: List[Type], tps2: List[Type],
tparams: List[Symbol]): boolean = (
tps1.isEmpty && tps2.isEmpty
@@ -2267,8 +2279,9 @@ trait Types requires SymbolTable {
case (_, AnnotatedType(_,atp2)) =>
tp1 <:< atp2
case (_, TypeRef(pre2, sym2, args2))
- if sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo) =>
- true
+ if sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo) && {
+ if (!inIDE) true else trackTypeIDE(sym2)
+ } => true
case (_, RefinedType(parents2, ref2)) =>
(parents2 forall tp1.<:<) && (ref2.toList forall tp1.specializes) &&
(!parents2.exists(.symbol.isAbstractType) || tp1.symbol != AllRefClass)
@@ -2284,6 +2297,7 @@ trait Types requires SymbolTable {
case (ConstantType(_), _) => tp1.singleDeref <:< tp2
case (TypeRef(pre1, sym1, args1), _) =>
+ if (inIDE) trackTypeIDE(sym1)
(sym1 == AllClass && tp2 <:< AnyClass.tpe
||
sym1 == AllRefClass && tp2.isInstanceOf[SingletonType] && (tp1 <:< tp2.widen))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index f4e99e0007..8ab4b50aa2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -476,12 +476,16 @@ trait Namers requires Analyzer {
var resultPt = if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe
+ if (onlyPresentation)
+ methodArgumentNames(meth) = vparamss.map(.map(.symbol));
if (meth.owner.isClass && (tpt.isEmpty || vparamss.exists(.exists(.tpt.isEmpty)))) {
// try to complete from matching definition in base type
for (val vparams <- vparamss; val vparam <- vparams)
if (vparam.tpt.isEmpty) vparam.symbol setInfo WildcardType
val schema = thisMethodType(resultPt)
val site = meth.owner.thisType
+
+
val overridden = intersectionType(meth.owner.info.parents).member(meth.name).filter(sym =>
sym != NoSymbol && (site.memberType(sym) matches schema))
if (overridden != NoSymbol && !(overridden hasFlag OVERLOADED)) {
@@ -489,6 +493,7 @@ trait Namers requires Analyzer {
case PolyType(tparams, rt) => rt.substSym(tparams, tparamSyms)
case mt => mt
}
+
for (val vparams <- vparamss) {
var pfs = resultPt.paramTypes
for (val vparam <- vparams) {
@@ -772,10 +777,11 @@ trait Namers requires Analyzer {
* This is used for error messages, where we want to speak in terms
* of the actual declaration or definition, not in terms of the generated setters
* and getters */
- def underlying(member: Symbol) =
+ def underlying(member: Symbol) : Symbol =
if (member hasFlag ACCESSOR) {
if (member hasFlag DEFERRED) {
val getter = if (member.isSetter) member.getter(member.owner) else member
+ if (inIDE && getter == NoSymbol) return NoSymbol;
val result = getter.owner.newValue(getter.pos, getter.name)
.setInfo(getter.tpe.resultType)
.setFlag(DEFERRED)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index df3ede8eca..aff947c210 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -900,7 +900,7 @@ trait Typers requires Analyzer {
if (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL) && !stat.symbol.isModuleVar =>
val vdef = copy.ValDef(stat, mods | PRIVATE | LOCAL, nme.getterToLocal(name), tpt, rhs)
val value = vdef.symbol
- val getter = if (mods hasFlag DEFERRED) value else value.getter(value.owner)
+ val getter = if ((mods hasFlag DEFERRED) || inIDE) value else value.getter(value.owner)
assert(getter != NoSymbol, stat)
if (getter hasFlag OVERLOADED)
error(getter.pos, getter+" is defined twice")
@@ -1179,6 +1179,8 @@ trait Typers requires Analyzer {
tp
}
+ protected def typedFunctionIDE(fun : Function, txt : Context) = {}
+
/**
* @param block ...
* @param mode ...
@@ -1282,6 +1284,8 @@ trait Typers requires Analyzer {
vparam.symbol
}
// XXX: here to for IDE hooks.
+ if (inIDE) // HACK to process arguments types in IDE.
+ typedFunctionIDE(fun, context);
val vparams = List.mapConserve(fun.vparams)(typedValDef)
for (val vparam <- vparams) {
checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()
@@ -1787,7 +1791,7 @@ trait Typers requires Analyzer {
qual.tpe.widen+" does not have a constructor"
else
decode(name)+" is not a member of "+qual.tpe.widen +
- (if ((context.unit ne null) && Position.line(context.unit.source, qual.pos) <
+ (if (!inIDE && (context.unit ne null) && Position.line(context.unit.source, qual.pos) <
Position.line(context.unit.source, tree.pos))
"\npossible cause: maybe a semicolon is missing before `"+decode(name)+"'?"
else ""))
@@ -1857,8 +1861,21 @@ trait Typers requires Analyzer {
while (defSym == NoSymbol && cx != NoContext) {
pre = cx.enclClass.prefix
defEntry = cx.scope.lookupEntry(name)
+ if (inIDE && (defEntry ne null) && defEntry.sym.exists) {
+ val sym = defEntry.sym
+ val namePos : Int = tree.pos
+ val symPos : Int = sym.pos
+ if (namePos < symPos) defEntry = null
+ }
if ((defEntry ne null) && qualifies(defEntry.sym)) {
defSym = defEntry.sym
+ } else if (inIDE) {
+ if (cx.outer == cx.enclClass) {
+ cx = cx.enclClass
+ defSym = pre.member(name) filter (
+ sym => sym.exists && context.isAccessible(sym, pre, false))
+ }
+ if (defSym == NoSymbol) cx = cx.outer
} else {
cx = cx.enclClass
defSym = pre.member(name) filter (