summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean McDirmid <sean.mcdirmid@gmail.com>2006-10-16 09:39:52 +0000
committerSean McDirmid <sean.mcdirmid@gmail.com>2006-10-16 09:39:52 +0000
commit4490aaef070b037d59029d56c6ea472772fa00a2 (patch)
treef20973b2b519831202c8fa657a0537086642567a /src
parentc95aa7344c5a2dfb5e488e556d656905b8d79477 (diff)
downloadscala-4490aaef070b037d59029d56c6ea472772fa00a2.tar.gz
scala-4490aaef070b037d59029d56c6ea472772fa00a2.tar.bz2
scala-4490aaef070b037d59029d56c6ea472772fa00a2.zip
* Added support for accessing files directly
* Added hook in settings to hide options in IDE * Updated Contexts, Namers, and Typers with hooks to prepare them for IDE integration.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala26
-rw-r--r--src/compiler/scala/tools/nsc/io/AbstractFile.scala18
-rw-r--r--src/compiler/scala/tools/nsc/io/PlainFile.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/VirtualFile.scala3
-rw-r--r--src/compiler/scala/tools/nsc/io/ZipArchive.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala106
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala133
-rw-r--r--src/compiler/scala/tools/nsc/util/SourceFile.scala5
9 files changed, 187 insertions, 122 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index acf0d59b85..6a3747710d 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -74,7 +74,7 @@ class Settings(error: String => unit) {
private val windowtitleDefault = "Scala Library Documentation"
private val documenttitleDefault = "Scala 2"
- val doc = BooleanSetting("-doc", "Generate documentation");
+ val doc = new BooleanSetting("-doc", "Generate documentation") { override def hiddenToIDE = true }
val debuginfo = new DebugSetting("-g", "Generate debugging info", List("none", "source", "line", "vars", "notc"), "vars", "vars")
val nowarnings = BooleanSetting("-nowarn", "Generate no warnings")
val noassertions = BooleanSetting("-noassert", "Generate no assertions and assumptions")
@@ -85,18 +85,18 @@ class Settings(error: String => unit) {
val bootclasspath = StringSetting ("-bootclasspath", "path", "Override location of bootstrap class files", bootclasspathDefault)
val extdirs = StringSetting ("-extdirs", "dirs", "Override location of installed extensions", extdirsDefault)
val outdir = StringSetting ("-d", "directory", "Specify where to place generated class files", ".")
- val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", encodingDefault)
+ val encoding = new StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", encodingDefault) { override def hiddenToIDE = false }
val windowtitle = StringSetting ("-windowtitle", "windowtitle", "Specify window title of generated HTML documentation", windowtitleDefault)
val documenttitle = StringSetting ("-documenttitle", "documenttitle", "Specify document title of generated HTML documentation", documenttitleDefault)
val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm-1.5", "jvm-1.4", "msil", "cldc"), "jvm-1.4")
val migrate = BooleanSetting("-migrate", "Assist in migrating from Scala version 1.0")
- val debug = BooleanSetting("-debug", "Output debugging messages")
- val statistics = BooleanSetting("-statistics", "Print compiler statistics")
+ val debug = new BooleanSetting("-debug", "Output debugging messages") { override def hiddenToIDE = true }
+ val statistics = new BooleanSetting("-statistics", "Print compiler statistics") { override def hiddenToIDE = true }
val explaintypes = BooleanSetting("-explaintypes", "Explain type errors in more detail")
- val resident = BooleanSetting("-resident", "Compiler stays resident, files to compile are read from standard input")
+ val resident = new BooleanSetting("-resident", "Compiler stays resident, files to compile are read from standard input") { override def hiddenToIDE = true }
val uniqid = BooleanSetting("-uniqid", "Print identifiers with unique names (debugging option)")
- val printtypes = BooleanSetting("-printtypes", "Print tree types (debugging option)")
- val prompt = BooleanSetting("-prompt", "Display a prompt after each error (debugging option)")
+ val printtypes = new BooleanSetting("-printtypes", "Print tree types (debugging option)") { override def hiddenToIDE = true }
+ val prompt = new BooleanSetting("-prompt", "Display a prompt after each error (debugging option)") { override def hiddenToIDE = true }
val noimports = BooleanSetting("-noimports", "Compile without any implicit imports")
val nopredefs = BooleanSetting("-nopredefs", "Compile without any implicit predefined values")
val skip = PhasesSetting ("-skip", "Skip")
@@ -108,8 +108,8 @@ class Settings(error: String => unit) {
val browse = PhasesSetting ("-browse", "Browse the abstract syntax tree after")
val stop = PhasesSetting ("-stop", "Stop after phase")
val log = PhasesSetting ("-log", "Log operations in")
- val version = BooleanSetting("-version", "Print product version and exit")
- val help = BooleanSetting("-help", "Print a synopsis of standard options")
+ val version = new BooleanSetting("-version", "Print product version and exit") { override def hiddenToIDE = true }
+ val help = new BooleanSetting("-help", "Print a synopsis of standard options") { override def hiddenToIDE = true }
val nouescape = new BooleanSetting("-nouescape", "disables handling of \\u unicode escapes")
// val showPhases = BooleanSetting("-showphases", "Print a synopsis of compiler phases")
@@ -122,7 +122,7 @@ class Settings(error: String => unit) {
val Xlinearizer = ChoiceSetting ("-Xlinearizer", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo")
val Xgenerics = BooleanSetting("-Xgenerics", "Use generic Java types")
val Xprintpos = BooleanSetting("-Xprintpos", "Print tree positions (as offsets)")
- val Xscript = BooleanSetting("-Xscript", "compile script file")
+ val Xscript = new BooleanSetting("-Xscript", "compile script file") { override def hiddenToIDE = true }
val Xexperimental = BooleanSetting("-Xexperimental", "enable experimental extensions")
/** A list of all settings */
@@ -157,6 +157,10 @@ class Settings(error: String => unit) {
*/
def unparse: List[String]
+ /** override if option should be hidden from IDE.
+ */
+ def hiddenToIDE : Boolean = false
+
// initialization
allsettings = this :: allsettings
}
@@ -181,6 +185,7 @@ class Settings(error: String => unit) {
/** A setting represented by a string, (`default' unless set) */
case class StringSetting(nme: String, arg: String, descr: String, default: String)
extends Setting(nme, descr) {
+ override def hiddenToIDE = true;
var abbreviation: String = null
var value: String = default
@@ -290,6 +295,7 @@ class Settings(error: String => unit) {
*/
case class PhasesSetting(nme: String, descr: String)
extends Setting(nme, descr + " <phase>") { // (see -showphases)") {
+ override def hiddenToIDE = true
var value: List[String] = List()
def tryToSet(args: List[String]): List[String] = args match {
diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
index 2b75752543..475ea7fada 100644
--- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala
+++ b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
@@ -8,7 +8,7 @@
package scala.tools.nsc.io
-import java.io.File
+import java.io.{File,InputStream,DataInputStream}
object AbstractFile {
@@ -90,6 +90,22 @@ abstract class AbstractFile extends Object with Iterable[AbstractFile] {
/** Returns the time that this abstract file was last modified. */
def lastModified: Long
+ /** returns an input stream so the file can be read */
+ def read : InputStream;
+ final def toCharArray = {
+ val input = read;
+ var str : String = "";
+ val buf = new Array[Byte](100);
+ var eof = false;
+ while (!eof) {
+ val x = input.read(buf);
+ eof = x == -1;
+ if (!eof) str = str + new String(buf, 0, x);
+ }
+ input.close;
+ str.toCharArray;
+ }
+
/** Reads the content of this abstract file into a byte array. */
//def getBytes: Array[Byte] = error("getBytes not supported by "+this.getClass())
diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala
index fcc2689592..8d24387b4f 100644
--- a/src/compiler/scala/tools/nsc/io/PlainFile.scala
+++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala
@@ -39,6 +39,7 @@ class PlainFile(val file: File) extends AbstractFile {
/** Returns the path of this abstract file. */
def path = file.getPath()
+ override def read = new FileInputStream(file)
override def hashCode(): Int =
try { file.getCanonicalPath().hashCode() }
diff --git a/src/compiler/scala/tools/nsc/io/VirtualFile.scala b/src/compiler/scala/tools/nsc/io/VirtualFile.scala
index e53387ac4f..1f3d62c241 100644
--- a/src/compiler/scala/tools/nsc/io/VirtualFile.scala
+++ b/src/compiler/scala/tools/nsc/io/VirtualFile.scala
@@ -7,7 +7,7 @@
package scala.tools.nsc.io
-import java.io.File
+import java.io.{File,InputStream}
/** This class implements an empty abstract regular file.
*
@@ -37,6 +37,7 @@ class VirtualFile(val name: String, _path: String) extends AbstractFile {
/** Returns null. */
final def file: File = null
+ def read : InputStream = throw new Error("not suported");
/** Is this abstract file a directory? */
def isDirectory: Boolean = false
diff --git a/src/compiler/scala/tools/nsc/io/ZipArchive.scala b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
index b0bbd91c1e..5bb9d1d40e 100644
--- a/src/compiler/scala/tools/nsc/io/ZipArchive.scala
+++ b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
@@ -162,6 +162,7 @@ final class ZipArchive(file: File, val archive: ZipFile) extends PlainFile(file)
var entry: ZipEntry = _
override def isDirectory = true
+ override def read = throw new Error("cannot read directories");
override def lastModified: Long =
if (entry != null) entry.getTime() else super.lastModified
@@ -185,6 +186,8 @@ final class ZipArchive(file: File, val archive: ZipFile) extends PlainFile(file)
override def lastModified: Long = entry.getTime()
+ override def read = archive.getInputStream(entry);
+
/** in zip archives, we assume class files conform to Java spec by using UTF-8 * /
def getBytes: Array[Byte] = {
val in: InputStream = archive.getInputStream(entry);
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 95a56585a5..86d572815a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -95,6 +95,20 @@ trait Contexts requires Analyzer {
var savedTypeBounds: List[Pair[Symbol, Type]] = List()
+ override def equals(that : Any) = that match {
+ case that if (super.equals(that)) => true
+ case txt : Context =>
+ tree == txt.tree && owner == txt.owner && scope == txt.scope &&
+ outer == txt.outer && enclClass == txt.enclClass && enclMethod == txt.enclMethod &&
+ variance == txt.variance && _undetparams == txt._undetparams &&
+ depth == txt.depth && imports == txt.imports && prefix == txt.prefix &&
+ inConstructorSuffix == txt.inConstructorSuffix && implicitsEnabled == txt.implicitsEnabled &&
+ checking == txt.checking && retyping == txt.retyping &&
+ savedTypeBounds == txt.savedTypeBounds
+ case _ => false;
+ }
+
+
def undetparams = _undetparams
def undetparams_=(ps: List[Symbol]) = {
//System.out.println("undetparams = " + ps);//debug
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 72aebe7d32..5493bb7e71 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -42,6 +42,7 @@ trait Namers requires Analyzer {
mapOver(tp)
}
}
+ protected def doEnterValueParams = true;
class Namer(val context: Context) {
@@ -49,23 +50,23 @@ trait Namers requires Analyzer {
def setPrivateWithin(tree: Tree, sym: Symbol, mods: Modifiers): Symbol = {
if (!mods.privateWithin.isEmpty)
- sym.privateWithin = typer.qualifyingClassContext(tree, mods.privateWithin).owner;
+ sym.privateWithin = typer.qualifyingClassContext(tree, mods.privateWithin).owner
sym
}
def updatePosFlags(sym: Symbol, pos: PositionType, flags: int): Symbol = {
- if (settings.debug.value) log("overwriting " + sym);
- val lockedFlag = sym.flags & LOCKED;
- sym.reset(NoType);
- sym setPos pos;
- sym.flags = flags | lockedFlag;
+ if (settings.debug.value) log("overwriting " + sym)
+ val lockedFlag = sym.flags & LOCKED
+ sym.reset(NoType)
+ sym setPos pos
+ sym.flags = flags | lockedFlag
if (sym.isModule && sym.moduleClass != NoSymbol)
- updatePosFlags(sym.moduleClass, pos, (flags & ModuleToClassFlags) | MODULE | FINAL);
+ updatePosFlags(sym.moduleClass, pos, (flags & ModuleToClassFlags) | MODULE | FINAL)
if (sym.owner.isPackageClass &&
(sym.linkedSym.rawInfo.isInstanceOf[loaders.SymbolLoader] ||
sym.linkedSym.rawInfo.isComplete && runId(sym.validTo) != currentRunId))
// pre-set linked symbol to NoType, in case it is not loaded together with this symbol.
- sym.linkedSym.setInfo(NoType);
+ sym.linkedSym.setInfo(NoType)
sym
}
@@ -104,9 +105,9 @@ trait Namers requires Analyzer {
sym
}
- private def enterPackageSymbol(pos: PositionType, name: Name): Symbol = {
+ def enterPackageSymbol(pos: PositionType, name: Name): Symbol = {
val cscope = if (context.owner == EmptyPackageClass) RootClass.info.decls
- else context.scope;
+ else context.scope
val p: Symbol = cscope.lookup(name)
if (p.isPackage && cscope == p.owner.info.decls) {
p
@@ -119,16 +120,16 @@ trait Namers requires Analyzer {
}
}
- private def inConstructorFlag: long =
+ def inConstructorFlag: long =
if (context.owner.isConstructor && !context.inConstructorSuffix) INCONSTRUCTOR
- else 0l;
+ else 0l
private def enterClassSymbol(pos: PositionType, flags: int, name: Name): Symbol = {
var c: Symbol = context.scope.lookup(name)
if (c.isType && !currentRun.compiles(c) && context.scope == c.owner.info.decls) {
- updatePosFlags(c, pos, flags);
+ updatePosFlags(c, pos, flags)
} else {
- c = enterInScope(context.owner.newClass(pos, name)).setFlag(flags | inConstructorFlag);
+ c = enterInScope(context.owner.newClass(pos, name)).setFlag(flags | inConstructorFlag)
}
if (c.owner.isPackageClass) {
val file = context.unit.source.getFile()
@@ -152,7 +153,7 @@ trait Namers requires Analyzer {
updatePosFlags(m, pos, flags)
} else {
if (m.isTerm && !m.isPackage && !currentRun.compiles(m) && (context.scope == m.owner.info.decls))
- context.scope.unlink(m);
+ context.scope.unlink(m)
m = context.owner.newModule(pos, name)
m.setFlag(flags)
m.moduleClass.setFlag(flags | inConstructorFlag)
@@ -178,15 +179,15 @@ trait Namers requires Analyzer {
}
def enterSyms(trees: List[Tree]): Namer =
- (this /: trees) ((namer, tree) => namer.enterSym(tree));
+ (this /: trees) ((namer, tree) => namer.enterSym(tree))
def newTypeSkolems(tparams: List[Symbol]): List[Symbol] = {
val tskolems = tparams map (.newTypeSkolem)
val ltp = new LazyType {
override def complete(sym: Symbol): unit =
- sym setInfo sym.deSkolemize.info.substSym(tparams, tskolems);
+ sym setInfo sym.deSkolemize.info.substSym(tparams, tskolems)
}
- tskolems foreach (.setInfo(ltp));
+ tskolems foreach (.setInfo(ltp))
tskolems
}
@@ -197,7 +198,7 @@ trait Namers requires Analyzer {
def applicableTypeParams(owner: Symbol): List[Symbol] =
if (owner.isTerm || owner.isPackageClass) List()
- else applicableTypeParams(owner.owner) ::: owner.typeParams;
+ else applicableTypeParams(owner.owner) ::: owner.typeParams
def deSkolemize: TypeMap = new DeSkolemizeMap(applicableTypeParams(context.owner))
@@ -207,9 +208,9 @@ trait Namers requires Analyzer {
if (settings.debug.value) log("entered " + tree.symbol + " in " + context.owner + ", scope-id = " + context.scope.hashCode());
var ltype: LazyType = innerNamer.typeCompleter(tree)
if (!tparams.isEmpty) {
- new Namer(context.makeNewScope(tree, tree.symbol)).enterSyms(tparams);
+ new Namer(context.makeNewScope(tree, tree.symbol)).enterSyms(tparams)
ltype = new LazyPolyType(tparams map (.symbol), ltype)
- if (tree.symbol.isTerm) skolemize(tparams);
+ if (tree.symbol.isTerm) skolemize(tparams)
}
tree.symbol.setInfo(ltype)
}
@@ -220,22 +221,22 @@ trait Namers requires Analyzer {
val owner = context.owner
tree match {
case PackageDef(name, stats) =>
- tree.symbol = enterPackageSymbol(tree.pos, name);
+ tree.symbol = enterPackageSymbol(tree.pos, name)
val namer = new Namer(
- context.make(tree, tree.symbol.moduleClass, tree.symbol.info.decls));
- namer.enterSyms(stats);
+ context.make(tree, tree.symbol.moduleClass, tree.symbol.info.decls))
+ namer.enterSyms(stats)
case ClassDef(mods, name, tparams, _, impl) =>
if ((mods.flags & (CASE | ABSTRACT)) == CASE) { // enter case factory method.
tree.symbol = enterCaseFactorySymbol(
tree.pos, mods.flags & AccessFlags | METHOD | CASE, name.toTermName)
- .setInfo(innerNamer.caseFactoryCompleter(tree));
- setPrivateWithin(tree, tree.symbol, mods);
+ .setInfo(innerNamer.caseFactoryCompleter(tree))
+ setPrivateWithin(tree, tree.symbol, mods)
}
tree.symbol = enterClassSymbol(tree.pos, mods.flags, name)
setPrivateWithin(tree, tree.symbol, mods)
finishWith(tparams)
case ModuleDef(mods, name, _) =>
- tree.symbol = enterModuleSymbol(tree.pos, mods.flags | MODULE | FINAL, name);
+ tree.symbol = enterModuleSymbol(tree.pos, mods.flags | MODULE | FINAL, name)
setPrivateWithin(tree, tree.symbol, mods)
setPrivateWithin(tree, tree.symbol.moduleClass, mods)
tree.symbol.moduleClass.setInfo(innerNamer.moduleClassTypeCompleter(tree))
@@ -246,14 +247,14 @@ trait Namers requires Analyzer {
(if ((mods.flags & MUTABLE) != 0) mods.flags & ~MUTABLE else mods.flags | STABLE)
val getter = owner.newMethod(tree.pos, name)
.setFlag(accflags)
- .setInfo(innerNamer.getterTypeCompleter(tree));
- setPrivateWithin(tree, getter, mods);
- enterInScope(getter);
+ .setInfo(innerNamer.getterTypeCompleter(tree))
+ setPrivateWithin(tree, getter, mods)
+ enterInScope(getter)
if ((mods.flags & MUTABLE) != 0) {
val setter = owner.newMethod(tree.pos, nme.getterToSetter(name))
.setFlag(accflags & ~STABLE & ~CASEACCESSOR)
- .setInfo(innerNamer.setterTypeCompleter(tree));
- setPrivateWithin(tree, setter, mods);
+ .setInfo(innerNamer.setterTypeCompleter(tree))
+ setPrivateWithin(tree, setter, mods)
enterInScope(setter)
}
tree.symbol =
@@ -264,7 +265,7 @@ trait Namers requires Analyzer {
else getter;
} else {
tree.symbol = enterInScope(owner.newValue(tree.pos, name))
- .setFlag(mods.flags);
+ .setFlag(mods.flags)
finish
}
case DefDef(mods, nme.CONSTRUCTOR, tparams, _, _, _) =>
@@ -291,7 +292,7 @@ trait Namers requires Analyzer {
enterSym(defn)
case imp @ Import(_, _) =>
tree.symbol = NoSymbol.newImport(tree.pos).setInfo(innerNamer.typeCompleter(tree));
- return new Namer(context.makeNewImport(imp));
+ return new Namer(context.makeNewImport(imp))
case _ =>
}
}
@@ -356,15 +357,16 @@ trait Namers requires Analyzer {
sym.isMethod && !(sym hasFlag ACCESSOR)) tpe.deconst
else tpe;
+
def enterValueParams(owner: Symbol, vparamss: List[List[ValDef]]): List[List[Symbol]] = {
- def enterValueParam(param: ValDef): Symbol = {
+ def enterValueParam(param: ValDef): Symbol = if (doEnterValueParams) {
param.symbol = owner.newValueParameter(param.pos, param.name)
.setInfo(typeCompleter(param))
- .setFlag(param.mods.flags & (BYNAMEPARAM | IMPLICIT));
- setPrivateWithin(param, param.symbol, param.mods);
- context.scope enter param.symbol;
+ .setFlag(param.mods.flags & (BYNAMEPARAM | IMPLICIT))
+ setPrivateWithin(param, param.symbol, param.mods)
+ context.scope enter param.symbol
param.symbol
- }
+ } else param.symbol
vparamss.map(.map(enterValueParam))
}
@@ -382,7 +384,7 @@ trait Namers requires Analyzer {
def checkParent(tpt: Tree): Type = {
val tp = tpt.tpe
if (tp.symbol == context.owner) {
- context.error(tpt.pos, ""+tp.symbol+" inherits itself");
+ context.error(tpt.pos, ""+tp.symbol+" inherits itself")
AnyRefClass.tpe
} else if (tp.isError) {
AnyRefClass.tpe
@@ -391,16 +393,16 @@ trait Namers requires Analyzer {
}
}
val parents = typer.parentTypes(templ) map checkParent
- val decls = newScope;
- new Namer(context.make(templ, clazz, decls)).enterSyms(templ.body);
+ val decls = newDecls(templ, clazz)
+ new Namer(context.make(templ, clazz, decls)).enterSyms(templ.body)
ClassInfoType(parents, decls, clazz)
}
private def classSig(tparams: List[AbsTypeDef], tpt: Tree, impl: Template): Type = {
- val tparamSyms = typer.reenterTypeParams(tparams);
+ val tparamSyms = typer.reenterTypeParams(tparams)
if (!tpt.isEmpty)
- context.owner.typeOfThis = selfTypeCompleter(tpt);
- else tpt.tpe = NoType;
+ context.owner.typeOfThis = selfTypeCompleter(tpt)
+ else tpt.tpe = NoType
makePolyType(tparamSyms, templateSig(impl))
}
@@ -413,9 +415,9 @@ trait Namers requires Analyzer {
if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) tpt.tpe = context.enclClass.owner.tpe
def makeMethodType(vparams: List[Symbol], restpe: Type) = {
- val formals = vparams map (.tpe);
+ val formals = vparams map (.tpe)
if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) ImplicitMethodType(formals, restpe)
- else MethodType(formals, restpe);
+ else MethodType(formals, restpe)
}
def thisMethodType(restype: Type) =
@@ -512,13 +514,13 @@ trait Namers requires Analyzer {
private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
- private def typeSig(tree: Tree): Type = {
+ def typeSig(tree: Tree): Type = {
val result =
try {
val sym: Symbol = tree.symbol
tree match {
case ClassDef(_, _, tparams, tpt, impl) =>
- new Namer(context.makeNewScope(tree, sym)).classSig(tparams, tpt, impl)
+ new Namer(makeNewScope(context, tree, sym)).classSig(tparams, tpt, impl)
case ModuleDef(_, _, impl) =>
val clazz = sym.moduleClass
@@ -528,7 +530,7 @@ trait Namers requires Analyzer {
case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
val result =
- new Namer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs);
+ new Namer(makeNewScope(context, tree, sym)).methodSig(tparams, vparamss, tpt, rhs);
checkContractive(sym, result)
case ValDef(_, _, tpt, rhs) =>
@@ -548,8 +550,8 @@ trait Namers requires Analyzer {
typer1.typedType(tpt).tpe
}
- case AliasTypeDef(_, _, tparams, rhs) =>
- new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
+ case tree @ AliasTypeDef(_, _, tparams, rhs) =>
+ new Namer(makeNewScope(context, tree, sym)).aliasTypeSig(sym, tparams, rhs)
case AbsTypeDef(_, _, lo, hi) =>
var lt = typer.typedType(lo).tpe
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index a12b814cd6..9beb1db673 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -49,6 +49,47 @@ trait Typers requires Analyzer {
super.traverse(tree)
}
}
+ def makeNewScope(txt : Context, tree : Tree, sym : Symbol) =
+ txt.makeNewScope(tree, sym)
+ def newDecls(tree : CompoundTypeTree) = newScope
+ def newDecls(tree : Template, clazz : Symbol) = newScope
+ def newTemplateScope(impl : Template, clazz : Symbol) = newScope
+
+ /** Mode constants
+ */
+ val NOmode = 0x000
+ val EXPRmode = 0x001 // these 3 modes are mutually exclusive.
+ val PATTERNmode = 0x002
+ val TYPEmode = 0x004
+
+ val SCCmode = 0x008 // orthogonal to above. When set we are
+ // in the this or super constructor call of a constructor.
+
+ val FUNmode = 0x10 // orthogonal to above. When set
+ // we are looking for a method or constructor
+
+ val POLYmode = 0x020 // orthogonal to above. When set
+ // expression types can be polymorphic.
+
+ val QUALmode = 0x040 // orthogonal to above. When set
+ // expressions may be packages and
+ // Java statics modules.
+
+ val TAPPmode = 0x080 // Set for the function/type constructor part
+ // of a type application. When set we do not
+ // decompose PolyTypes.
+
+ val SUPERCONSTRmode = 0x100 // Set for the `super' in a superclass constructor call
+ // super.<init>
+
+ val SNDTRYmode = 0x200 // indicates that an application is typed for the 2nd
+ // time. In that case functions may no longer be
+ // be coerced with implicit views.
+
+ val LHSmode = 0x400 // Set for the left-hand side of an assignment
+
+ val CONSTmode = 0x800 // expressions should evaluate to constants
+ // used for attribute arguments
class Typer(context0: Context) {
import context0.unit
@@ -96,42 +137,8 @@ trait Typers requires Analyzer {
}
private var context = context0
+ def context1 = context
- /** Mode constants
- */
- val NOmode = 0x000
- val EXPRmode = 0x001 // these 3 modes are mutually exclusive.
- val PATTERNmode = 0x002
- val TYPEmode = 0x004
-
- val SCCmode = 0x008 // orthogonal to above. When set we are
- // in the this or super constructor call of a constructor.
-
- val FUNmode = 0x10 // orthogonal to above. When set
- // we are looking for a method or constructor
-
- val POLYmode = 0x020 // orthogonal to above. When set
- // expression types can be polymorphic.
-
- val QUALmode = 0x040 // orthogonal to above. When set
- // expressions may be packages and
- // Java statics modules.
-
- val TAPPmode = 0x080 // Set for the function/type constructor part
- // of a type application. When set we do not
- // decompose PolyTypes.
-
- val SUPERCONSTRmode = 0x100 // Set for the `super' in a superclass constructor call
- // super.<init>
-
- val SNDTRYmode = 0x200 // indicates that an application is typed for the 2nd
- // time. In that case functions may no longer be
- // be coerced with implicit views.
-
- val LHSmode = 0x400 // Set for the left-hand side of an assignment
-
- val CONSTmode = 0x800 // expressions should evaluate to constants
- // used for attribute arguments
private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode | CONSTmode
@@ -614,7 +621,7 @@ trait Typers requires Analyzer {
case DefDef(_, _, _, vparamss, _, Apply(_, superargs)) =>
val outercontext = context.outer
supertpt = TypeTree(
- newTyper(outercontext.makeNewScope(constr, outercontext.owner))
+ newTyper(makeNewScope(outercontext, constr, outercontext.owner))
.completeParentType(
supertpt,
tparams,
@@ -696,7 +703,7 @@ trait Typers requires Analyzer {
reenterTypeParams(cdef.tparams)
val tparams1 = List.mapConserve(cdef.tparams)(typedAbsTypeDef)
val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(cdef.tpt))
- val impl1 = newTyper(context.make(cdef.impl, clazz, newScope))
+ val impl1 = newTyper(context.make(cdef.impl, clazz, newTemplateScope(cdef.impl, clazz)))
.typedTemplate(cdef.impl, parentTypes(cdef.impl))
val impl2 = addSyntheticMethods(impl1, clazz, context.unit)
val ret = copy.ClassDef(cdef, cdef.mods, cdef.name, tparams1, tpt1, impl2)
@@ -712,7 +719,7 @@ trait Typers requires Analyzer {
//System.out.println("sourcefile of " + mdef.symbol + "=" + mdef.symbol.sourceFile)
attributes(mdef)
val clazz = mdef.symbol.moduleClass
- val impl1 = newTyper(context.make(mdef.impl, clazz, newScope))
+ val impl1 = newTyper(context.make(mdef.impl, clazz, newTemplateScope(mdef.impl, clazz)))
.typedTemplate(mdef.impl, parentTypes(mdef.impl))
val impl2 = addSyntheticMethods(impl1, clazz, context.unit)
@@ -1006,7 +1013,7 @@ trait Typers requires Analyzer {
def typedCases(tree: Tree, cases: List[CaseDef], pattp0: Type, pt: Type): List[CaseDef] = {
var pattp = pattp0
List.mapConserve(cases) ( cdef =>
- newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt))
+ newTyper(makeNewScope(context, cdef, context.owner)).typedCase(cdef, pattp, pt))
/* not yet!
cdef.pat match {
case Literal(Constant(null)) =>
@@ -1259,9 +1266,13 @@ trait Typers requires Analyzer {
defn.mods setAttr List();
}
+ protected def typedHookForTree(tree : Tree, mode : Int, pt : Type): Tree = null;
protected def typed1(tree: Tree, mode: int, pt: Type): Tree = {
-
+ { // IDE hook
+ val ret = typedHookForTree(tree, mode, pt)
+ if (ret != null) return ret
+ }
def ptOrLub(tps: List[Type]) = if (isFullyDefined(pt)) pt else lub(tps)
def typedTypeApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
@@ -1543,35 +1554,36 @@ trait Typers requires Analyzer {
val sym: Symbol = tree.symbol
if (sym != null) sym.initialize
//if (settings.debug.value && tree.isDef) log("typing definition of "+sym);//DEBUG
+
tree match {
case PackageDef(name, stats) =>
val stats1 = newTyper(context.make(tree, sym.moduleClass, sym.info.decls))
.typedStats(stats, NoSymbol)
copy.PackageDef(tree, name, stats1) setType NoType
- case cdef @ ClassDef(_, _, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).typedClassDef(cdef)
+ case tree @ ClassDef(_, _, _, _, _) =>
+ newTyper(makeNewScope(context, tree, sym)).typedClassDef(tree)
- case mdef @ ModuleDef(_, _, _) =>
- newTyper(context.make(tree, sym.moduleClass)).typedModuleDef(mdef)
+ case tree @ ModuleDef(_, _, _) =>
+ newTyper(context.make(tree, sym.moduleClass)).typedModuleDef(tree)
case vdef @ ValDef(_, _, _, _) =>
typedValDef(vdef)
case ddef @ DefDef(_, _, _, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).typedDefDef(ddef)
+ newTyper(makeNewScope(context, tree, sym)).typedDefDef(ddef)
case tdef @ AbsTypeDef(_, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).typedAbsTypeDef(tdef)
+ newTyper(makeNewScope(context, tree, sym)).typedAbsTypeDef(tdef)
case tdef @ AliasTypeDef(_, _, _, _) =>
- newTyper(context.makeNewScope(tree, sym)).typedAliasTypeDef(tdef)
+ newTyper(makeNewScope(context, tree, sym)).typedAliasTypeDef(tdef)
case ldef @ LabelDef(_, _, _) =>
var lsym = ldef.symbol
var typer1 = this
if (lsym == NoSymbol) { // labeldef is part of template
- typer1 = newTyper(context.makeNewScope(tree, context.owner))
+ typer1 = newTyper(makeNewScope(context, tree, context.owner))
typer1.enterLabelDef(ldef)
}
typer1.typedLabelDef(ldef)
@@ -1581,9 +1593,9 @@ trait Typers requires Analyzer {
if (comments != null) comments(defn . symbol) = comment;
ret
}
- case block @ Block(_, _) =>
- newTyper(context.makeNewScope(tree, context.owner))
- .typedBlock(block, mode, pt)
+ case tree @ Block(_, _) =>
+ newTyper(makeNewScope(context, tree, context.owner))
+ .typedBlock(tree, mode, pt)
case Sequence(elems) =>
val elems1 = List.mapConserve(elems)(elem => typed(elem, mode, pt))
@@ -1623,11 +1635,11 @@ trait Typers requires Analyzer {
.setType(if (isFullyDefined(pt) && !phase.erasedTypes) pt
else appliedType(ArrayClass.typeConstructor, List(elemtpt1.tpe)))
- case fun @ Function(_, _) =>
+ case tree @ Function(_, _) =>
if (tree.symbol == NoSymbol)
tree.symbol = context.owner.newValue(tree.pos, nme.ANON_FUN_NAME)
.setFlag(SYNTHETIC).setInfo(NoType)
- newTyper(context.makeNewScope(tree, tree.symbol)).typedFunction(fun, mode, pt)
+ newTyper(makeNewScope(context, tree, tree.symbol)).typedFunction(tree, mode, pt)
case Assign(lhs, rhs) =>
def mayBeVarGetter(sym: Symbol) = sym.info match {
@@ -1842,12 +1854,13 @@ trait Typers requires Analyzer {
case SelectFromTypeTree(qual, selector) =>
tree setType typedSelect(typedType(qual), selector).tpe
- case CompoundTypeTree(templ: Template) =>
+
+ case tree @ CompoundTypeTree(templ: Template) =>
tree setType {
val parents1 = List.mapConserve(templ.parents)(typedType)
if (parents1 exists (.tpe.isError)) ErrorType
else {
- val decls = newScope
+ val decls = newDecls(tree)
val self = refinedType(parents1 map (.tpe), context.enclClass.owner, decls)
newTyper(context.make(templ, self.symbol, decls)).typedRefinement(templ.body)
self
@@ -1886,6 +1899,7 @@ trait Typers requires Analyzer {
throw new Error("unexpected tree: "+tree);//debug
}
}
+ protected def typedHookForType(tree : Tree, mode : Int, pt : Type): Tree = null;
def typed(tree: Tree, mode: int, pt: Type): Tree =
try {
@@ -1896,6 +1910,11 @@ trait Typers requires Analyzer {
tree.tpe = null
if (tree.hasSymbol) tree.symbol = NoSymbol
}
+ { // IDE hook, can reset type if things are different.
+ val ret = typedHookForType(tree, mode, pt);
+ if (ret != null) return ret;
+ }
+
//System.out.println("typing "+tree+", "+context.undetparams);//DEBUG
val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt)
//System.out.println("typed "+tree1+":"+tree1.tpe+", "+context.undetparams);//DEBUG
@@ -1918,10 +1937,10 @@ trait Typers requires Analyzer {
}
def atOwner(owner: Symbol): Typer =
- new Typer(context.make(context.tree, owner))
+ newTyper(context.make(context.tree, owner))
def atOwner(tree: Tree, owner: Symbol): Typer =
- new Typer(context.make(tree, owner))
+ newTyper(context.make(tree, owner))
/** Types expression or definition `tree' */
def typed(tree: Tree): Tree = {
diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala
index fd4dcc760b..19ae7bc849 100644
--- a/src/compiler/scala/tools/nsc/util/SourceFile.scala
+++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala
@@ -13,6 +13,9 @@ package scala.tools.nsc.util
import scala.tools.nsc.io.{AbstractFile, VirtualFile}
+/** Uses positions that are offsets rather than line/column pairs.
+ *
+ */
object SourceFile {
val LF: Char = 0x0A
val FF: Char = 0x0C
@@ -29,7 +32,7 @@ object SourceFile {
class SourceFile(val file: AbstractFile, _content: Array[Char]) {
import SourceFile._
- //def this(_file: AbstractFile) = this(_file, _file.getChars)
+ def this(_file: AbstractFile) = this(_file, _file.toCharArray);
def this(sourceName: String, content: Array[Char]) =
this(new VirtualFile(sourceName), content)