diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Main.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/doc/DocGenerator.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/doc/DocUtil.scala | 28 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/PlainFile.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/ZipArchive.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/SymbolTable.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 21 |
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 ( |