diff options
author | Martin Odersky <odersky@gmail.com> | 2005-03-09 18:11:33 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-03-09 18:11:33 +0000 |
commit | 89de2927954407224dbe51c03bb8cbbd0229519b (patch) | |
tree | f4bec09cf80890cf81949803c64a628f865e9b07 /sources | |
parent | 718ff58ca11cc1462e82f19ab7b37a250b6bbc0a (diff) | |
download | scala-89de2927954407224dbe51c03bb8cbbd0229519b.tar.gz scala-89de2927954407224dbe51c03bb8cbbd0229519b.tar.bz2 scala-89de2927954407224dbe51c03bb8cbbd0229519b.zip |
*** empty log message ***
Diffstat (limited to 'sources')
-rwxr-xr-x | sources/scala/tools/nsc/Global.scala | 18 | ||||
-rw-r--r-- | sources/scala/tools/nsc/Phase.scala | 4 | ||||
-rw-r--r-- | sources/scala/tools/nsc/Settings.scala | 2 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/TreePrinters.scala | 7 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/Trees.scala | 83 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/ast/parser/Syntactic.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Definitions.scala | 1 | ||||
-rw-r--r-- | sources/scala/tools/nsc/symtab/Flags.scala | 69 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/SymbolLoaders.scala | 7 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Symbols.scala | 22 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Types.scala | 55 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Namers.scala | 8 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/TypeCheckers.scala | 158 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 4 |
14 files changed, 266 insertions, 174 deletions
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index 7ec16edf65..36b250fbc3 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -134,7 +134,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable val typeCheckPhase = new analyzer.TypeCheckPhase(namerPhase); val picklePhase = new pickles.PicklePhase(typeCheckPhase); - val terminalPhase = new StdPhase(typeCheckPhase) { + val terminalPhase = new StdPhase(picklePhase) { def name = "terminal"; val global: Global.this.type = Global.this; def apply(unit: CompilationUnit): unit = {} @@ -183,8 +183,12 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable if (settings.Xshowobj.value != "") showDef(newTermName(settings.Xshowobj.value), true); if (reporter.errors() == 0) { - for (val Pair(sym, pickled) <- symData.elements) - writeSymblFile(sym, pickled) + for (val Pair(sym, pickled) <- symData.elements.toList) + if (symData contains sym) { + symData -= sym; + symData -= sym.linkedSym; + writeSymblFile(sym, pickled) + } } else { for (val Pair(sym, file) <- symSource.elements) sym.reset(loaders.sourcefileLoader(file)); @@ -237,10 +241,12 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable } /** Returns the file with the given suffix for the given class. */ - private def getFile(clazz: Symbol, suffix: String) = + private def getFile(clazz: Symbol, suffix: String) = { + val outdir = settings.outdir.value; new File( - settings.outdir.value + File.separatorChar + - clazz.fullNameString(File.separatorChar) + suffix); + if (outdir == "") clazz.simpleName.toString() + suffix + else outdir + File.separatorChar + clazz.fullNameString(File.separatorChar) + suffix); + } private def writeSymblFile(clazz: Symbol, pickled: PickleBuffer) = { val file = getFile(clazz, ".symbl"); diff --git a/sources/scala/tools/nsc/Phase.scala b/sources/scala/tools/nsc/Phase.scala index c110b54134..e4c8bf3f0e 100644 --- a/sources/scala/tools/nsc/Phase.scala +++ b/sources/scala/tools/nsc/Phase.scala @@ -5,6 +5,8 @@ // $Id$ package scala.tools.nsc; +import symtab.Flags.INITIALFLAGS; + abstract class Phase(val prev: Phase) { val id: int = if (prev == null) 0 else prev.id + 1; @@ -16,7 +18,7 @@ abstract class Phase(val prev: Phase) { def name: String; def description: String = name; - val flagMask: long = if (prev == null) 0L else prev.flagMask; + val flagMask: long = if (prev == null) INITIALFLAGS else prev.flagMask; def exactMatch: boolean = false; def run: unit; diff --git a/sources/scala/tools/nsc/Settings.scala b/sources/scala/tools/nsc/Settings.scala index 409655560f..2b57cc3ebd 100644 --- a/sources/scala/tools/nsc/Settings.scala +++ b/sources/scala/tools/nsc/Settings.scala @@ -22,7 +22,7 @@ class Settings(error: String => unit) { System.getProperty("sun.boot.class.path", "")); val extdirs = StringSetting ("-extdirs", "dirs", "Override location of installed extensions", System.getProperty("java.ext.dirs", "")); - val outdir = StringSetting ("-d", "directory", "Specify where to place generated class files", "."); + val outdir = StringSetting ("-d", "directory", "Specify where to place generated class files", ""); val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", "ISO-8859-1"); val separate = ChoiceSetting ("-separate", "Read symbol files for separate compilation", List("yes","no"), "default"); val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm", "msil"), "jvm"); diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala index 4f82d4a742..acc96bedfc 100644 --- a/sources/scala/tools/nsc/ast/TreePrinters.scala +++ b/sources/scala/tools/nsc/ast/TreePrinters.scala @@ -67,7 +67,7 @@ abstract class TreePrinters { } case AbsTypeDef(mods, name, lo, hi) => print(symName(tree, name)); - printOpt(">: ", lo); printOpt("<: ", hi); + printOpt(" >: ", lo); printOpt(" <: ", hi); } def printBlock(tree: Tree): unit = tree match { @@ -148,7 +148,7 @@ abstract class TreePrinters { case Template(parents, body) => printRow(parents, " with "); - if (!body.isEmpty) printColumn(body, "{", ";", "}") + if (!body.isEmpty) printColumn(body, " {", ";", "}") case Block(stats, expr) => printColumn(stats ::: List(expr), "{", ";", "}") @@ -215,7 +215,8 @@ abstract class TreePrinters { print("this"); case Select(qualifier, name) => - if (global.settings.debug.value || qualifier.symbol == null || !qualifier.symbol.isRoot) { + if (global.settings.debug.value || qualifier.symbol == null || + (!qualifier.symbol.isRoot && !qualifier.symbol.isEmptyPackageClass)) { print(qualifier); print("."); } print(symName(tree, name)) diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala index b9a86b9bc8..7e314683be 100644 --- a/sources/scala/tools/nsc/ast/Trees.scala +++ b/sources/scala/tools/nsc/ast/Trees.scala @@ -44,6 +44,13 @@ class Trees: Global { def duplicate: Tree = new Transformer(new StrictTreeCopier) transform this; + + def copyAttrs(tree: Tree): this.type = { + pos = tree.pos; + tpe = tree.tpe; + if (hasSymbol) symbol = tree.symbol; + this + } } abstract class SymTree extends Tree { @@ -317,81 +324,81 @@ class Trees: Global { class StrictTreeCopier extends TreeCopier { def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template) = - new ClassDef(mods, name, tparams, tpt, impl).setPos(tree.pos); + new ClassDef(mods, name, tparams, tpt, impl).copyAttrs(tree); def PackageDef(tree: Tree, name: Name, stats: List[Tree]) = - new PackageDef(name, stats).setPos(tree.pos); + new PackageDef(name, stats).copyAttrs(tree); def ModuleDef(tree: Tree, mods: int, name: Name, impl: Template) = - new ModuleDef(mods, name, impl).setPos(tree.pos); + new ModuleDef(mods, name, impl).copyAttrs(tree); def ValDef(tree: Tree, mods: int, name: Name, tpt: Tree, rhs: Tree) = - new ValDef(mods, name, tpt, rhs).setPos(tree.pos); + new ValDef(mods, name, tpt, rhs).copyAttrs(tree); def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = - new DefDef(mods, name, tparams, vparamss, tpt, rhs).setPos(tree.pos); + new DefDef(mods, name, tparams, vparamss, tpt, rhs).copyAttrs(tree); def AbsTypeDef(tree: Tree, mods: int, name: Name, lo: Tree, hi: Tree) = - new AbsTypeDef(mods, name, lo, hi).setPos(tree.pos); + new AbsTypeDef(mods, name, lo, hi).copyAttrs(tree); def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree) = - new AliasTypeDef(mods, name, tparams, rhs).setPos(tree.pos); + new AliasTypeDef(mods, name, tparams, rhs).copyAttrs(tree); def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = - new LabelDef(name, params, rhs).setPos(tree.pos); + new LabelDef(name, params, rhs).copyAttrs(tree); def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]) = - new Import(expr, selectors).setPos(tree.pos); + new Import(expr, selectors).copyAttrs(tree); def Attributed(tree: Tree, attribute: Tree, definition: Tree) = - new Attributed(attribute, definition).setPos(tree.pos); + new Attributed(attribute, definition).copyAttrs(tree); def DocDef(tree: Tree, comment: String, definition: Tree) = - new DocDef(comment, definition).setPos(tree.pos); + new DocDef(comment, definition).copyAttrs(tree); def Template(tree: Tree, parents: List[Tree], body: List[Tree]) = - new Template(parents, body).setPos(tree.pos); + new Template(parents, body).copyAttrs(tree); def Block(tree: Tree, stats: List[Tree], expr: Tree) = - new Block(stats, expr).setPos(tree.pos); + new Block(stats, expr).copyAttrs(tree); def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = - new CaseDef(pat, guard, body).setPos(tree.pos); + new CaseDef(pat, guard, body).copyAttrs(tree); def Sequence(tree: Tree, trees: List[Tree]) = - new Sequence(trees).setPos(tree.pos); + new Sequence(trees).copyAttrs(tree); def Alternative(tree: Tree, trees: List[Tree]) = - new Alternative(trees).setPos(tree.pos); + new Alternative(trees).copyAttrs(tree); def Bind(tree: Tree, name: Name, body: Tree) = - new Bind(name, body).setPos(tree.pos); + new Bind(name, body).copyAttrs(tree); def Function(tree: Tree, vparams: List[ValDef], body: Tree) = - new Function(vparams, body).setPos(tree.pos); + new Function(vparams, body).copyAttrs(tree); def Assign(tree: Tree, lhs: Tree, rhs: Tree) = - new Assign(lhs, rhs).setPos(tree.pos); + new Assign(lhs, rhs).copyAttrs(tree); def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = - new If(cond, thenp, elsep).setPos(tree.pos); + new If(cond, thenp, elsep).copyAttrs(tree); def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = - new Match(selector, cases).setPos(tree.pos); + new Match(selector, cases).copyAttrs(tree); def Return(tree: Tree, expr: Tree) = - new Return(expr).setPos(tree.pos); + new Return(expr).copyAttrs(tree); def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = - new Try(block, catches, finalizer).setPos(tree.pos); + new Try(block, catches, finalizer).copyAttrs(tree); def Throw(tree: Tree, expr: Tree) = - new Throw(expr).setPos(tree.pos); + new Throw(expr).copyAttrs(tree); def New(tree: Tree, tpt: Tree) = - new New(tpt).setPos(tree.pos); + new New(tpt).copyAttrs(tree); def Typed(tree: Tree, expr: Tree, tpt: Tree) = - new Typed(expr, tpt).setPos(tree.pos); + new Typed(expr, tpt).copyAttrs(tree); def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = - new TypeApply(fun, args).setPos(tree.pos); + new TypeApply(fun, args).copyAttrs(tree); def Apply(tree: Tree, fun: Tree, args: List[Tree]) = - new Apply(fun, args).setPos(tree.pos); + new Apply(fun, args).copyAttrs(tree); def Super(tree: Tree, qual: Name, mixin: Name) = - new Super(qual, mixin).setPos(tree.pos); + new Super(qual, mixin).copyAttrs(tree); def This(tree: Tree, qual: Name) = - new This(qual).setPos(tree.pos); + new This(qual).copyAttrs(tree); def Select(tree: Tree, qualifier: Tree, selector: Name) = - new Select(qualifier, selector).setPos(tree.pos); + new Select(qualifier, selector).copyAttrs(tree); def Ident(tree: Tree, name: Name) = - new Ident(name).setPos(tree.pos); + new Ident(name).copyAttrs(tree); def Literal(tree: Tree, value: Any) = - new Literal(value).setPos(tree.pos); + new Literal(value).copyAttrs(tree); def TypeTree(tree: Tree) = - new TypeTree().setPos(tree.pos); + new TypeTree().copyAttrs(tree); def SingletonTypeTree(tree: Tree, ref: Tree) = - new SingletonTypeTree(ref).setPos(tree.pos); + new SingletonTypeTree(ref).copyAttrs(tree); def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = - new SelectFromTypeTree(qualifier, selector).setPos(tree.pos); + new SelectFromTypeTree(qualifier, selector).copyAttrs(tree); def CompoundTypeTree(tree: Tree, templ: Template) = - new CompoundTypeTree(templ).setPos(tree.pos); + new CompoundTypeTree(templ).copyAttrs(tree); def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = - new AppliedTypeTree(tpt, args).setPos(tree.pos) + new AppliedTypeTree(tpt, args).copyAttrs(tree) } class LazyTreeCopier(copy: TreeCopier) extends TreeCopier { diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Syntactic.scala index 1384ae1ed7..ac369fa790 100755 --- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala +++ b/sources/scala/tools/nsc/ast/parser/Syntactic.scala @@ -1514,6 +1514,8 @@ abstract class Syntactic: ParserPhase { in.nextToken(); parents += simpleType(); if (in.token == LPAREN) args = argumentExprs(); + } else { + parents += scalaAnyRefConstr } parents += scalaScalaObjectConstr; if ((mods & Flags.CASE)!= 0) parents += caseClassConstr; diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala index 33f4075b48..c3a3254cc9 100755 --- a/sources/scala/tools/nsc/symtab/Definitions.scala +++ b/sources/scala/tools/nsc/symtab/Definitions.scala @@ -15,6 +15,7 @@ abstract class Definitions: SymbolTable { var RootClass: Symbol = _; var EmptyPackage: Symbol = _; var EmptyPackageClass: Symbol = _; + var emptypackagescope: Scope = null; //debug var JavaPackage: Symbol = _; var JavaLangPackage: Symbol = _; diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala index de46342a5d..fcaae4e8cf 100644 --- a/sources/scala/tools/nsc/symtab/Flags.scala +++ b/sources/scala/tools/nsc/symtab/Flags.scala @@ -60,12 +60,16 @@ object Flags { val IS_ERROR = 0x200000000l; // symbol is an error symbol val OVERLOADED = 0x400000000l; // symbol is overloaded - val TRANS_FLAG = 0x1000000000l; // transient flag guaranteed to be reset after each phase. + val TRANS_FLAG = 0x800000000l; // transient flag guaranteed to be reset after each phase. val LIFTED = TRANS_FLAG; // transient flag for lambdalift val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer + val INITIALFLAGS = 0x777777777l; // masks val SOURCEFLAGS = 0x00077777; // these modifiers can be set in source programs. + val EXPLICITFLAGS = // these modifiers can be explcitly in source programs. + PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE; + val ACCESSFLAGS = PRIVATE | PROTECTED; val VARIANCES = COVARIANT | CONTRAVARIANT; val CONSTRFLAGS = JAVA; @@ -74,7 +78,7 @@ object Flags { /** Flags already set by object creation and never set afterwards */ val CREATIONFLAGS = ACCESSFLAGS | METHOD | MODULE | MUTABLE | PARAM | PACKAGE | COVARIANT | CONTRAVARIANT | SYNTHETIC | STABLE | ACCESSOR | PARAMACCESSOR | LOCAL | - IS_ERROR | OVERLOADED; + IS_ERROR | OVERLOADED | INCONSTRUCTOR; /** Module flags inherited by their module-class */ val MODULE2CLASSFLAGS = ACCESSFLAGS | PACKAGE; @@ -84,17 +88,54 @@ object Flags { .map(i => flagToString(flags & (1L << i))) .filter("" !=).mkString("", " ", ""); - private def flagToString(flag: long): String = flag.asInstanceOf[int] match { - case PRIVATE => "private" - case PROTECTED => "protected" - case ABSTRACT => "abstract" - case FINAL => "final" - case SEALED => "sealed" - case TRAIT => "trait" - case OVERRIDE => "override" - case CASE => "case" - case SYNTHETIC => "<synthetic>" - case LOCAL => "<local>" - case _ => "" + private def flagToString(flag: long): String = { + if (flag == INTERFACE) "<interface>" + else if (flag == IS_ERROR) "<is_error>" + else if (flag == OVERLOADED) "<overloaded>" + else if (flag == TRANS_FLAG) "<transient>" + else flag.asInstanceOf[int] match { + case DEFERRED => "<deferred>" + case FINAL => "final" + case PRIVATE => "private" + case PROTECTED => "protected" + + case SEALED => "sealed" + case OVERRIDE => "override" + case CASE => "case" + case ABSTRACT => "abstract" + + case METHOD => "<method>" + case TRAIT => "<trait>" + case JAVA => "<java>" + case MODULE => "<module>" + + case MUTABLE => "<mutable>" + case PARAM => "<param>" + case PACKAGE => "<package>" + case DEPRECATED => "<deprecated>" + + case COVARIANT => "<covariant>" + case CONTRAVARIANT => "<contravariant>" + case ABSOVERRIDE => "<absoverride>" + case LOCAL => "<local>" + + case SYNTHETIC => "<synthetic>" + case STABLE => "<stable>" + case INITIALIZED => "<initialized>" + case LOCKED => "<locked>" + + case ACCESSED => "<accessed>" + case SELECTOR => "<selector>" + + case CAPTURED => "<captured>" + case ACCESSOR => "<accessor>" + + case ACCESS_METHOD => "<access>" + case PARAMACCESSOR => "<paramaccessor>" + case LABEL => "<label>" + case BRIDGE => "<bridge>" + + case _ => "" + } } } diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala index c8952f641b..b441231bd4 100755 --- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -45,8 +45,7 @@ abstract class SymbolLoaders { else "error while loading " + root.name + ", " + msg); } initRoot(root); - if (!root.isPackageClass) - initRoot(if (root.isModule) root.linkedClass else root.linkedModule); + if (!root.isPackageClass) initRoot(root.linkedSym); } private def initRoot(root: Symbol): unit = { @@ -60,7 +59,7 @@ abstract class SymbolLoaders { */ def packageLoader(directory: AbstractFile): SymbolLoader = new SymbolLoader(root => { - System.out.println("loading " + root);//debug + if (settings.debug.value) System.out.println("loading " + root); assert(root.isPackageClass, root); root.setInfo(new PackageClassInfoType(new Scope(), root)); @@ -109,7 +108,7 @@ abstract class SymbolLoaders { } for (val Pair(name, sfile) <- sources.elements) { classes.get(name) match { - case Some(cfile) if (cfile.lastModified() > sfile.lastModified()) => {} + case Some(cfile) if (cfile.lastModified() >= sfile.lastModified()) => {} case _ => enterClassAndModule(name, sourcefileLoader(sfile)); } } diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index 1fa0ac8865..e7eeaa92c2 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -109,7 +109,7 @@ abstract class Symbols: SymbolTable { final def isModuleClass = isClass && (rawflags & MODULE) != 0; final def isPackageClass = isClass && (rawflags & PACKAGE) != 0; final def isRoot = isPackageClass && name == nme.ROOT.toTypeName; - final def isEmptyPackage = isPackageClass && name == nme.EMPTY_PACKAGE_NAME.toTypeName; + final def isEmptyPackageClass = isPackageClass && name == nme.EMPTY_PACKAGE_NAME.toTypeName; /** Does this symbol denote a stable value? */ final def isStable = @@ -250,7 +250,7 @@ abstract class Symbols: SymbolTable { phase = current; limit = current; } - assert(infos != null, "info = null at " + this.name + " " + limit + " " + phase);//debug + assert(infos != null, name.toString() + " " + limit + " " + phase);//debug infos.info } else { var infos = this.infos; @@ -414,6 +414,12 @@ abstract class Symbols: SymbolTable { sym => (sym hasFlag MODULE) && (sym.rawInfo != NoType)); else NoSymbol; + /** For a module its linked class, for a class its linked module, NoSymbol otherwise */ + final def linkedSym: Symbol = + if (isModule) linkedClass + else if (isClass) linkedModule + else NoSymbol; + /** The module corresponding to this module class (note that this * is not updated when a module is cloned). */ @@ -445,8 +451,8 @@ abstract class Symbols: SymbolTable { /** String representation of symbol's definition key word */ final def keyString: String = if (isClass) - if (hasFlag(TRAIT)) - if (hasFlag(JAVA)) "interface" else "trait" + if ((rawflags & TRAIT) != 0) + if ((rawflags & JAVA) != 0) "interface" else "trait" else "class" else if (isType && !hasFlag(PARAM)) "type" else if (isVariable) "var" @@ -488,7 +494,7 @@ abstract class Symbols: SymbolTable { * Never adds id. */ final def fullNameString(separator: char): String = - if (owner.isRoot) simpleName.toString() + if (owner.isRoot || owner.isEmptyPackageClass) simpleName.toString() else owner.fullNameString(separator) + separator + simpleName; final def fullNameString: String = fullNameString('.'); @@ -551,7 +557,7 @@ abstract class Symbols: SymbolTable { /** String representation of symbol's definition */ final def defString: String = - compose(List(flagsToString(rawflags & SOURCEFLAGS), + compose(List(flagsToString(rawflags & EXPLICITFLAGS), keyString, varianceString + nameString, infoString(rawInfo))); @@ -589,9 +595,7 @@ abstract class Symbols: SymbolTable { override def tpe: Type = { if (valid != phase) { valid = phase; - val tparams = typeParams; - tpeCache = typeRef(owner.thisType, this, tparams map (.tpe)); - if (!tparams.isEmpty) tpeCache = PolyType(tparams, tpeCache); + tpeCache = typeRef(owner.thisType, this, typeParams map (.tpe)); } tpeCache } diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala index 2f677c99d7..3dfc7651cd 100755 --- a/sources/scala/tools/nsc/symtab/Types.scala +++ b/sources/scala/tools/nsc/symtab/Types.scala @@ -321,15 +321,14 @@ abstract class Types: SymbolTable { val sym = entry.sym; val excl = sym.rawflags & excluded; if (excl == 0) { - if (name.isTypeName) + if (name.isTypeName) { return sym - else if (member == NoSymbol) + } else if (member == NoSymbol) { member = sym - else if (members == null && - !(member.name == sym.name && - (memberType(member) matches memberType(sym)))) - members = new Scope(List(member, sym)) - else { + } else if (members == null) { + if (member.name != sym.name || !memberType(member).matches(memberType(sym))) + members = new Scope(List(member, sym)) + } else { var prevEntry = members lookupEntry sym.name; while (prevEntry != null && !(memberType(prevEntry.sym) matches memberType(sym))) @@ -412,7 +411,7 @@ abstract class Types: SymbolTable { override def singleDeref: Type = sym.typeOfThis; override def prefixString = if (settings.debug.value) sym.nameString + ".this."; - else if (sym.isRoot) "" + else if (sym.isRoot || sym.isEmptyPackageClass) "" else if (sym.isAnonymousClass || sym.isRefinementClass) "this." else if (sym.isPackageClass) sym.fullNameString('.') + "." else sym.nameString + ".this."; @@ -544,8 +543,6 @@ abstract class Types: SymbolTable { override def toString(): String = base.toString() + "(" + value + ")"; } - class ExtTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends TypeRef(pre, sym, args); - /** A class for named types of the form <prefix>.<sym.name>[args] * Cannot be created directly; one should always use `typeRef' for creation. */ @@ -633,14 +630,21 @@ abstract class Types: SymbolTable { extends Type { override def paramSectionCount: int = resultType.paramSectionCount; - override def paramTypes: List[Type] = resultType.paramTypes; + override def parents: List[Type] = resultType.parents; + override def decls: Scope = resultType.decls; + override def symbol: Symbol = resultType.symbol; + override def closure: Array[Type] = resultType.closure; + override def baseClasses: List[Symbol] = resultType.baseClasses; + override def baseType(clazz: Symbol): Type = resultType.baseType(clazz); + override def narrow: Type = resultType.narrow; override def erasure = resultType.erasure; override def toString(): String = (if (typeParams.isEmpty) "=> " else typeParams.mkString("[", ",", "]")) + resultType; + override def cloneInfo(owner: Symbol) = { val tparams = typeParams map (.cloneSymbol(owner)); for (val tparam <- tparams) @@ -712,7 +716,7 @@ abstract class Types: SymbolTable { sym1.resetFlag(LOCKED); result } else { - new ExtTypeRef(pre, sym1, args) {} + new TypeRef(pre, sym1, args) {} } } @@ -740,8 +744,11 @@ abstract class Types: SymbolTable { /** A creator for type applications */ def appliedType(tycon: Type, args: List[Type]): Type = tycon match { case TypeRef(pre, sym, _) => typeRef(pre, sym, args) - case PolyType(tparams, restpe) => restpe.subst(tparams, args) - case ErrorType => tycon + case _ => + tycon match { + case PolyType(tparams, restpe) => restpe.subst(tparams, args) + case ErrorType => tycon + } } // Helper Classes --------------------------------------------------------- @@ -1098,7 +1105,9 @@ abstract class Types: SymbolTable { sym2.isAbstractType && (tp1 <:< tp2.bounds.lo) || sym2.isClass && - ({ val base = tp1 baseType sym2; !(base eq tp1) && (base <:< tp2) })//debug + ({ val base = tp1 baseType sym2; + System.out.println("" + tp1 + " baseType " + sym2 + " = " + base); + !(base eq tp1) && (base <:< tp2) })//debug || sym1 == AllClass || @@ -1294,13 +1303,21 @@ abstract class Types: SymbolTable { /** Eliminate from list of types all elements which are a supertype * of some other element of the list. */ - private def elimSuper(ts: List[Type]): List[Type] = - ts filter (t => !(ts exists (t1 => t1 <:< t))); + private def elimSuper(ts: List[Type]): List[Type] = ts match { + case List() => List() + case t :: ts1 => + val rest = ts1 filter (t1 => !(t <:< t1)); + if (rest exists (t1 => t1 <:< t)) rest else t :: rest + } /** Eliminate from list of types all elements which are a subtype * of some other element of the list. */ - private def elimSub(ts: List[Type]): List[Type] = - ts filter (t => !(ts exists (t1 => t <:< t1))); + private def elimSub(ts: List[Type]): List[Type] = ts match { + case List() => List() + case t :: ts1 => + val rest = ts1 filter (t1 => !(t1 <:< t)); + if (rest exists (t1 => t <:< t1)) rest else t :: rest + } /** The least upper bound wrt <:< of a list of types */ def lub(ts: List[Type]): Type = { diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala index 3096d85017..693d1db576 100755 --- a/sources/scala/tools/nsc/typechecker/Namers.scala +++ b/sources/scala/tools/nsc/typechecker/Namers.scala @@ -29,6 +29,7 @@ trait Namers: Analyzer { (if ((sym.rawflags & CASE) != 0) "case class " + sym.name else sym.toString())); private def updatePosFlags(sym: Symbol, pos: int, mods: int): Symbol = { + if (settings.debug.value) System.out.println("overwriting " + sym); sym.pos = pos; val oldflags = sym.rawflags & (INITIALIZED | LOCKED); val newflags = mods & ~(INITIALIZED | LOCKED); @@ -68,7 +69,7 @@ trait Namers: Analyzer { private def enterModuleSymbol(pos: int, mods: int, name: Name): Symbol = { val m: Symbol = context.scope.lookup(name); - if (m.isModule && !m.isPackage && m.isExternal && context.scope == m.owner.info.decls) { + if (m.isModule && !m.isPackage && m.isExternal && (context.scope == m.owner.info.decls)) { updatePosFlags(m, pos, mods) } else { val newm = context.owner.newModule(pos, name); @@ -96,7 +97,8 @@ trait Namers: Analyzer { if (settings.debug.value) log("entered " + tree.symbol); val ltype = typer.typeCompleter(tree); def makeParam(tparam: AbsTypeDef): Symbol = - tree.symbol.newTypeParameter(tparam.pos, tparam.name); + tree.symbol.newTypeParameter(tparam.pos, tparam.name) + .setInfo(typer.typeCompleter(tparam)); tree.symbol.setInfo( if (tparams.isEmpty) ltype else new LazyPolyType(tparams map makeParam, ltype)) @@ -122,7 +124,7 @@ trait Namers: Analyzer { tree.symbol = enterClassSymbol(tree.pos, mods, name); finishWith(tparams) case ModuleDef(mods, name, _) => - tree.symbol = enterModuleSymbol(tree.pos, mods, name); + tree.symbol = enterModuleSymbol(tree.pos, mods | MODULE | FINAL, name); tree.symbol.moduleClass.setInfo(typer.typeCompleter(tree)); finish case ValDef(mods, name, tp, rhs) => diff --git a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala index 48f265a4e9..a00b9829b1 100755 --- a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala +++ b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala @@ -19,7 +19,7 @@ trait TypeCheckers: Analyzer { def name = "typechecker"; val global: TypeCheckers.this.global.type = TypeCheckers.this.global; def apply(unit: CompilationUnit): unit = - new TypeChecker(startContext.make(unit)).transformExpr(unit.body) + unit.body = new TypeChecker(startContext.make(unit)).transformExpr(unit.body) } class TypeChecker(context: Context) { @@ -211,8 +211,9 @@ trait TypeCheckers: Analyzer { } } else errorTree(tree, clazz.toString() + " is neither a case class nor a sequence class") - } else if ((mode & FUNmode) == 0 && !context.undetparams.isEmpty) { // (7) - context.undetparams = List(); + } else if ((mode & FUNmode) != 0) { + tree + } else if (tree.symbol != null && !tree.symbol.typeParams.isEmpty) { // (7) errorTree(tree, "" + clazz + " takes type parameters"); } else tree match { // (6) case TypeTree() => tree @@ -461,82 +462,76 @@ trait TypeCheckers: Analyzer { private def transform1(tree: Tree, mode: int, pt: Type): Tree = { + def funmode = mode & stickyModes | FUNmode | POLYmode; + def transformCases(cases: List[CaseDef], pattp: Type): List[CaseDef] = { val tc1 = new TypeChecker(context.makeNewScope(tree, context.owner)); cases mapConserve (cdef => tc1.transformCase(cdef, pattp, pt)) } - def transformTypeApply(fun: Tree, args: List[Tree]): Tree = { - inferPolyAlternative(fun, args.length); - val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType)); - val targs = args1 map (.tpe); - if (fun.tpe.isError || (targs exists (.isError))) - setError(tree) - else fun.tpe match { - case PolyType(tparams, restpe) => - checkBounds(tree.pos, tparams, targs, ""); - copy.TypeApply(tree, fun, args1) setType restpe.subst(tparams, targs) + def transformTypeApply(fun: Tree, args: List[Tree]): Tree = + if (fun.hasSymbol && fun.symbol.hasFlag(OVERLOADED)) { + transformTypeApply( + adapt(inferPolyAlternative(fun, args.length), funmode, WildcardType)) + } else { + val tparams = context.undetparams; + context.undetparams = List(); + if (tparams.length == args.length) { + new TreeSubstituter(tparams, targs).traverse(fun); fun + } else if (tparams.length == 0) { + errorTree(tree, treeSymTypeMsg(tree, args) + " takes type parameters."); + } else { + errorTree(tree, "wrong number of type parameters for " + treeSymTypeMsg(fun)) + } } - } - def transformApply(fun: Tree, args: List[Tree]): Tree = { - // if function is overloaded, filter all alternatives that match - // number of arguments and expected result type. - if (fun.hasSymbol && fun.symbol.hasFlag(OVERLOADED)) { - val argtypes = args map (arg => AllClass.tpe); - val pre = fun.symbol.info.prefix; - fun.symbol = fun.symbol filter (alt => - isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt)); - fun.tpe = pre.memberType(fun.symbol) - } - fun.tpe match { - case OverloadedType(pre, alts) => - val args1 = args mapConserve (arg => - transform(arg, mode & stickyModes, WildcardType)); - inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt); - transformApply(fun, args1); - case MethodType(formals0, restpe) => - val formals = formalTypes(formals0, args.length); - if (formals.length != args.length) { - errorTree(tree, "wrong number of arguments for " + treeSymTypeMsg(fun)) - } else { - val tparams = context.undetparams; - context.undetparams = List(); - if (tparams.isEmpty) { - val args1 = List.map2(args, formals) ((arg, formal) => - transform(arg, mode & stickyModes, formal)); - val tree1 = copy.Apply(tree, fun, args1).setType(restpe); - val tree2 = constfold(tree1); - if (tree1 == tree2) tree2 else transform(tree2, mode, pt) - } else { - assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns - val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt); - val strictTargs = List.map2(lenientTargs, tparams)((targ, tparam) => - if (targ == WildcardType) tparam.tpe else targ); - def transformArg(tree: Tree, formal: Type): Tree = { - val lenientPt = formal.subst(tparams, lenientTargs); - val tree1 = transform(tree, mode & stickyModes | POLYmode, lenientPt); - val argtparams = context.undetparams; - context.undetparams = List(); - if (!argtparams.isEmpty) { - val strictPt = formal.subst(tparams, strictTargs); - inferArgumentInstance(tree1, argtparams, strictPt, lenientPt); - } - tree1 - } - val args1 = List.map2(args, formals)(transformArg); - if (args1 exists (.tpe.isError)) setError(tree) - else { - val undetparams = inferMethodInstance(fun, tparams, args1, pt); - val result = transformApply(fun, args1); - context.undetparams = undetparams; - result - } + def transformApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match { + case OverloadedType(pre, alts) => + val args1 = args mapConserve (arg => + transform(arg, mode & stickyModes, WildcardType)); + inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt); + transformApply(adapt(fun, funmode, WildcardType), args1); + case MethodType(formals0, restpe) => + val formals = formalTypes(formals0, args.length); + if (formals.length != args.length) { + errorTree(tree, "wrong number of arguments for " + treeSymTypeMsg(fun)) + } else { + val tparams = context.undetparams; + context.undetparams = List(); + if (tparams.isEmpty) { + val args1 = List.map2(args, formals) ((arg, formal) => + transform(arg, mode & stickyModes, formal)); + val tree1 = copy.Apply(tree, fun, args1).setType(restpe); + val tree2 = constfold(tree1); + if (tree1 == tree2) tree2 else transform(tree2, mode, pt) + } else { + assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns + val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt); + val strictTargs = List.map2(lenientTargs, tparams)((targ, tparam) => + if (targ == WildcardType) tparam.tpe else targ); + def transformArg(tree: Tree, formal: Type): Tree = { + val lenientPt = formal.subst(tparams, lenientTargs); + val tree1 = transform(tree, mode & stickyModes | POLYmode, lenientPt); + val argtparams = context.undetparams; + context.undetparams = List(); + if (!argtparams.isEmpty) { + val strictPt = formal.subst(tparams, strictTargs); + inferArgumentInstance(tree1, argtparams, strictPt, lenientPt); + } + tree1 + } + val args1 = List.map2(args, formals)(transformArg); + if (args1 exists (.tpe.isError)) setError(tree) + else { + val undetparams = inferMethodInstance(fun, tparams, args1, pt); + val result = transformApply(fun, args1); + context.undetparams = undetparams; + result } } - case ErrorType => - setError(tree) - } + } + case ErrorType => + setError(tree) } /** The qualifying class of a this or super with prefix `qual' */ @@ -683,7 +678,10 @@ trait TypeCheckers: Analyzer { copy.PackageDef(tree, name, stats1) setType NoType case cdef @ ClassDef(_, _, _, _, _) => - new TypeChecker(context.makeNewScope(tree, sym)).transformClassDef(cdef) + val result = new TypeChecker(context.makeNewScope(tree, sym)).transformClassDef(cdef); + System.out.println("entered: " + result.symbol);//debug + result + case mdef @ ModuleDef(_, _, _) => transformModuleDef(mdef) @@ -819,11 +817,22 @@ trait TypeCheckers: Analyzer { copy.Typed(tree, expr1, tpt1) case TypeApply(fun, args) => - transformTypeApply(transform(fun, mode & stickyModes | FUNmode, WildcardType), args); + transformTypeApply(transform(fun, funmode, WildcardType), args) case Apply(fun, args) => val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType; - transformApply(transform(fun, mode & stickyModes | FUNmode | POLYmode, funpt), args) + var fun1 = transform(fun, funmode, funpt); + // if function is overloaded, filter all alternatives that match + // number of arguments and expected result type. + if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) { + val argtypes = args map (arg => AllClass.tpe); + val pre = fun1.symbol.info.prefix; + val sym = fun1.symbol filter (alt => + isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt)); + if (sym != NoSymbol) + fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType) + } + transformApply(fun1, args) case Super(qual, mix) => val clazz = qualifyingClass(qual); @@ -883,8 +892,7 @@ trait TypeCheckers: Analyzer { case AppliedTypeTree(tpt, args) => val tpt1 = transform(tpt, mode | FUNmode, WildcardType); - val tparams = context.undetparams; - context.undetparams = List(); + val tparams = tpt.tpe.symbol.typeParams; val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType)); if (tpt1.tpe.isError) setError(tree) diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index 57162d4092..e600c86625 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -94,6 +94,7 @@ trait Typers: Analyzer { val clazz = context.owner; val tparamSyms = enterTypeParams(clazz, tparams); if (!tpt.isEmpty) clazz.typeOfThis = selfTypeCompleter(tpt); + else tpt.tpe = NoType; makePolyType(tparamSyms, templateSig(impl)) } @@ -201,7 +202,8 @@ trait Typers: Analyzer { sym.isValueParameter && sym.owner.isClass && sym.owner.hasFlag(CASE)) unit.error(sym.pos, "pass-by-name arguments not allowed for case class parameters"); if ((sym.flags & DEFERRED) != 0) { - if (!sym.owner.isClass || sym.owner.isModuleClass || sym.owner.isAnonymousClass) { + if (!sym.isValueParameter && !sym.isTypeParameter && + (!sym.owner.isClass || sym.owner.isModuleClass || sym.owner.isAnonymousClass)) { unit.error(sym.pos, "only classes can have declared but undefined members" + (if (!sym.isVariable) "" |