From 9e67e8eb2a4480d2761d2e08a87cea6b32a71fbb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 22 Mar 2005 15:26:54 +0000 Subject: *** empty log message *** --- sources/scala/List.scala | 2 +- sources/scala/tools/nsc/Global.scala | 6 +- sources/scala/tools/nsc/Phase.scala | 4 - sources/scala/tools/nsc/ast/TreeGen.scala | 101 +++++++- sources/scala/tools/nsc/ast/Trees.scala | 2 +- sources/scala/tools/nsc/ast/parser/Syntactic.scala | 154 +++++------- sources/scala/tools/nsc/symtab/Definitions.scala | 8 +- sources/scala/tools/nsc/symtab/Flags.scala | 12 +- sources/scala/tools/nsc/symtab/Names.scala | 4 +- sources/scala/tools/nsc/symtab/StdNames.scala | 2 + sources/scala/tools/nsc/symtab/SymbolLoaders.scala | 24 +- sources/scala/tools/nsc/symtab/Symbols.scala | 119 +++++---- sources/scala/tools/nsc/symtab/Types.scala | 89 ++++--- .../nsc/symtab/classfile/ClassfileParser.scala | 11 +- .../tools/nsc/symtab/classfile/MetaParser.scala | 3 +- sources/scala/tools/nsc/typechecker/Contexts.scala | 15 +- sources/scala/tools/nsc/typechecker/Namers.scala | 36 +-- .../scala/tools/nsc/typechecker/TypeCheckers.scala | 276 +++++++++++++-------- sources/scala/tools/nsc/typechecker/Typers.scala | 37 ++- .../scala/tools/scalac/typechecker/RefCheck.scala | 26 +- test/files/pos/List1.scala | 6 +- test/files/pos/abstract.scala | 4 +- test/files/pos/arrays2.scala | 4 +- test/files/pos/bug115.scala | 5 +- 24 files changed, 581 insertions(+), 369 deletions(-) diff --git a/sources/scala/List.scala b/sources/scala/List.scala index 0563f49998..e4a109852d 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -748,7 +748,7 @@ sealed trait List[+a] extends Seq[a] { def flatMap[b](f: a => List[b]): List[b] = match { case Nil => Nil case head :: tail => f(head) ::: (tail flatMap f) - }; + } /** Reverses the elements of this list. *

diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index 36b250fbc3..aba47f7d89 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -11,7 +11,7 @@ import scala.tools.util._; import scala.collection.mutable.{HashSet,HashMap,ListBuffer} import symtab._; -import symtab.pickles.{PickleBuffer, Pickles}; +import symtab.classfile.{PickleBuffer, Pickler}; import util._; import ast._; import ast.parser._; @@ -38,7 +38,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable val global: Global.this.type = Global.this } - object pickles extends Pickles { + object pickler extends Pickler { val global: Global.this.type = Global.this } @@ -132,7 +132,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable } val namerPhase = new analyzer.NamerPhase(parserPhase); val typeCheckPhase = new analyzer.TypeCheckPhase(namerPhase); - val picklePhase = new pickles.PicklePhase(typeCheckPhase); + val picklePhase = new pickler.PicklePhase(typeCheckPhase); val terminalPhase = new StdPhase(picklePhase) { def name = "terminal"; diff --git a/sources/scala/tools/nsc/Phase.scala b/sources/scala/tools/nsc/Phase.scala index e4c8bf3f0e..1bb14483ac 100644 --- a/sources/scala/tools/nsc/Phase.scala +++ b/sources/scala/tools/nsc/Phase.scala @@ -5,8 +5,6 @@ // $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; @@ -17,8 +15,6 @@ abstract class Phase(val prev: Phase) { def name: String; def description: String = name; - - val flagMask: long = if (prev == null) INITIALFLAGS else prev.flagMask; def exactMatch: boolean = false; def run: unit; diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala index 523bf74b78..f152bb2f2e 100755 --- a/sources/scala/tools/nsc/ast/TreeGen.scala +++ b/sources/scala/tools/nsc/ast/TreeGen.scala @@ -6,14 +6,111 @@ package scala.tools.nsc.ast; import scala.tools.util.Position; +import symtab.Flags._; abstract class TreeGen { val global: Global; import global._; + import definitions._; + import posAssigner.atPos; - def mkGlobalRef(sym: Symbol): Tree = Ident(sym.name) setSymbol sym setType sym.tpe; + /** Builds a reference to value whose type is given stable prefix. + */ + def mkQualifier(stable: Type): Tree = stable match { + case NoPrefix => + EmptyTree + case ThisType(clazz) => + if (clazz.isRoot || clazz.isEmptyPackageClass) EmptyTree else This(clazz) + case SingleType(pre, sym) => + val qual = mkStableRef(pre, sym); + qual.tpe match { + case MethodType(params, _) => + assert(params.isEmpty, qual.tpe); + Apply(qual, List()); + case _ => + qual + } + } - def This(sym: Symbol): Tree = global.This(sym.name) setSymbol sym setType sym.thisType; + /** Builds a reference to given symbol with given stable prefix. */ + def mkRef(pre: Type, sym: Symbol): Tree = { + val qual = mkQualifier(pre); + if (qual == EmptyTree) Ident(sym) else Select(qual, sym) + } + + /** Builds a reference to given symbol. */ + def mkRef(sym: Symbol): Tree = mkRef(sym.owner.thisType, sym); + + /** Replacecs tree type with a stable type if possible */ + def stabilize(tree: Tree): Tree = tree match { + case Ident(_) => + if (tree.symbol.isStable) tree.setType(singleType(NoPrefix, tree.symbol)) + else tree + case Select(qual, _) => + if (tree.symbol.isStable && qual.tpe.isStable) tree.setType(singleType(qual.tpe, tree.symbol)) + else tree + case _ => + tree + } + + /** Builds a reference with stable type to given symbol */ + def mkStableRef(pre: Type, sym: Symbol): Tree = stabilize(mkRef(pre, sym)); + def mkStableRef(sym: Symbol): Tree = stabilize(mkRef(sym)); + + def TypeTree(tp: Type) = global.TypeTree() setType tp; + + def This(sym: Symbol) = + global.This(sym.name) setSymbol sym setType sym.thisType; + + def Ident(sym: Symbol) = { + assert(sym.isTerm); + sym.setFlag(ACCESSED); + global.Ident(sym.name) setSymbol sym setType sym.tpe; + } + + def Select(qual: Tree, sym: Symbol) = { + assert(sym.isTerm); + sym.setFlag(ACCESSED); + global.Select(qual, sym.name) setSymbol sym setType qual.tpe.memberType(sym); + } + + def Apply(fun: Tree, args: List[Tree]) = fun.tpe match { + case MethodType(formals, restpe) => + global.Apply(fun, args) setType restpe + } + + def Assign(lhs: Tree, rhs: Tree) = + global.Assign(lhs, rhs) setType UnitClass.tpe; + + def ValDef(sym: Symbol, rhs: Tree): ValDef = atPos(sym.pos) { + global.ValDef(flags2mods(sym.flags), sym.name, TypeTree(sym.tpe), rhs) + } + def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree); + + def AbsTypeDef(sym: Symbol) = + global.AbsTypeDef(flags2mods(sym.flags), sym.name, + TypeTree(sym.info.bounds.lo), TypeTree(sym.info.bounds.hi)); + + def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree) = atPos(sym.pos) { + var cnt = 0; + def freshName = { cnt = cnt + 1; newTermName("x$" + cnt) } + def mk(tparams: List[Symbol], vparamss: List[List[Symbol]], tpe: Type): DefDef = tpe match { + case PolyType(tparams, restpe) => + mk(tparams, List(), restpe) + case MethodType(formals, restpe) => + val vparams: List[Symbol] = formals map sym.newValueParameter(sym.pos, freshName).setInfo; + mk(tparams, vparamss ::: List(vparams), restpe) + case _ => + global.DefDef( + flags2mods(sym.flags), + sym.name, + tparams.map(AbsTypeDef), + vparamss.map(.map(ValDef)), + TypeTree(tpe), + rhs(vparamss)) + } + mk(List(), List(), sym.tpe) + } } diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala index 7e314683be..1a1f64a872 100644 --- a/sources/scala/tools/nsc/ast/Trees.scala +++ b/sources/scala/tools/nsc/ast/Trees.scala @@ -220,7 +220,7 @@ class Trees: Global { /** General type term, introduced by RefCheck. */ case class TypeTree() extends TypTree { - override def isEmpty = tpe == null; + override def isEmpty = tpe == null || tpe == NoType; } /** Singleton type, eliminated by RefCheck */ diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Syntactic.scala index ac369fa790..479e0a65d6 100755 --- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala +++ b/sources/scala/tools/nsc/ast/parser/Syntactic.scala @@ -1283,15 +1283,15 @@ abstract class Syntactic: ParserPhase { false } - /** Def ::= val PatDef - * | var VarDef - * | def FunDef - * | type TypeDef + /** Def ::= val PatDef {`,' PatDef} + * | var VarDef {`,' VatDef} + * | def FunDef {`,' FunDef} + * | type TypeDef {`,' TypeDef} * | TmplDef - * Dcl ::= val ValDcl - * | var ValDcl - * | def FunDcl - * | type TypeDcl + * Dcl ::= val ValDcl {`,' ValDcl} + * | var ValDcl {`,' ValDcl} + * | def FunDcl {`,' FunDcl} + * | type TypeDcl {`,' TypeDcl} */ def defOrDcl(mods: int): List[Tree] = { in.token match { @@ -1300,12 +1300,12 @@ abstract class Syntactic: ParserPhase { case VAR => varDefOrDcl(mods); case DEF => - funDefOrDcl(mods); + List(funDefOrDcl(mods)); case TYPE => in.nextToken(); List(typeDefOrDcl(mods)) case _ => - tmplDef(mods) + List(tmplDef(mods)) } } @@ -1367,43 +1367,33 @@ abstract class Syntactic: ParserPhase { atPos(pos) { ValDef(newmods, name, tp.duplicate, rhs.duplicate) } } - /** FunDef ::= FunSig {`,' FunSig} `:' Type `=' Expr + /** FunDef ::= FunSig `:' Type `=' Expr * | this ParamClause `=' ConstrExpr - * FunDcl ::= FunSig {`,' FunSig} `:' Type + * FunDcl ::= FunSig `:' Type * FunSig ::= id [FunTypeParamClause] ParamClauses */ - def funDefOrDcl(mods: int): List[Tree] = { - in.nextToken(); - if (in.token == THIS) - List( - atPos(in.skipToken()) { - val vparams = List(paramClause(false)); - accept(EQUALS); - DefDef( - mods, nme.CONSTRUCTOR, List(), vparams, TypeTree(), constrExpr()) - }) - else { - var newmods = mods; - val lhs = new ListBuffer[Tuple4[Int, Name, List[AbsTypeDef], List[List[ValDef]]]] - + Tuple4( - in.pos, ident(), typeParamClauseOpt(false), paramClauses(false)); - while (in.token == COMMA) - lhs += Tuple4( - in.skipToken(), ident(), typeParamClauseOpt(false), paramClauses(false)); - val restype = typedOpt(); - val rhs = - if (restype == EmptyTree || in.token == EQUALS) equalsExpr(); - else { - newmods = newmods | Flags.DEFERRED; - EmptyTree - } - for (val Tuple4(pos, name, tparams, vparams) <- lhs.toList) yield - atPos(pos) { - DefDef(newmods, name, tparams, vparams, - restype.duplicate, rhs.duplicate) - } + def funDefOrDcl(mods: int): Tree = + atPos(in.skipToken()) { + if (in.token == THIS) { + in.nextToken(); + val vparams = List(paramClause(false)); + accept(EQUALS); + DefDef(mods, nme.CONSTRUCTOR, List(), vparams, TypeTree(), constrExpr()) + } else { + var newmods = mods; + val name = ident(); + val tparams = typeParamClauseOpt(false); + val vparamss = paramClauses(false); + val restype = typedOpt(); + val rhs = + if (restype == EmptyTree || in.token == EQUALS) equalsExpr(); + else { + newmods = newmods | Flags.DEFERRED; + EmptyTree + } + DefDef(newmods, name, tparams, vparamss, restype, rhs) + } } - } /** ConstrExpr ::= SelfInvocation * | `{' SelfInvocation {`;' BlockStat} `}' @@ -1452,9 +1442,9 @@ abstract class Syntactic: ParserPhase { /** TmplDef ::= ([case] class | trait) ClassDef * | [case] object ObjectDef */ - def tmplDef(mods: int): List[Tree] = in.token match { + def tmplDef(mods: int): Tree = in.token match { case TRAIT => - classDef(mods | Flags.TRAIT | Flags.ABSTRACT); + classDef(mods | Flags.ABSTRACT); case CLASS => classDef(mods); case CASECLASS => @@ -1465,48 +1455,36 @@ abstract class Syntactic: ParserPhase { objectDef(mods | Flags.CASE); case _ => syntaxError("illegal start of definition", true); - List() + EmptyTree } - /** ClassDef ::= ClassSig {`,' ClassSig} [`:' SimpleType] ClassTemplate + /** ClassDef ::= ClassSig [`:' SimpleType] ClassTemplate * ClassSig ::= Id [TypeParamClause] [ClassParamClause] */ - def classDef(mods: int): List[Tree] = { - val lhs = new ListBuffer[Tuple4[Int, Name, List[AbsTypeDef], List[List[ValDef]]]]; - do { - lhs += Tuple4(in.skipToken(), - ident().toTypeName, - typeParamClauseOpt(true), - if ((mods & Flags.TRAIT) != 0) List() else paramClauses(true)) - } while (in.token == COMMA); - val thistpe = simpleTypedOpt(); - val template = classTemplate(mods); - for (val Tuple4(pos, name, tparams, vparamss) <- lhs.toList) yield - atPos(pos) { - val template1 = if ((mods & Flags.TRAIT) != 0) template - else addConstructor(mods, vparamss, template); - ClassDef(mods, name, tparams, thistpe.duplicate, template1.duplicate.asInstanceOf[Template]) - } - } + def classDef(mods: int): Tree = + atPos(in.skipToken()) { + val name = ident().toTypeName; + val tparams = typeParamClauseOpt(true); + if ((mods & Flags.CASE) != 0 && in.token != LPAREN) accept(LPAREN); + val vparamss = paramClauses(true); + val thistpe = simpleTypedOpt(); + val mods1 = if (vparamss.isEmpty && (mods & ABSTRACT) != 0) mods | Flags.TRAIT else mods; + val template = classTemplate(mods1, vparamss); + ClassDef(mods1, name, tparams, thistpe, template) + } - /** ObjectDef ::= Id { , Id } ClassTemplate + /** ObjectDef ::= Id ClassTemplate */ - def objectDef(mods: int): List[Tree] = { - val lhs = new ListBuffer[Pair[Int, Name]]; - do { - lhs += Pair(in.skipToken(), ident()); - } while (in.token == COMMA); - val template = classTemplate(mods); - for (val Pair(pos, name) <- lhs.toList) yield - atPos(pos) { - val template1 = addConstructor(mods, List(), template); - ModuleDef(mods, name, template1.duplicate.asInstanceOf[Template]) - } - } + def objectDef(mods: int): Tree = + atPos(in.skipToken()) { + val name = ident(); + val template = classTemplate(mods, List()); + ModuleDef(mods, name, template) + } - /** ClassTemplate ::= [`extends' SimpleType [`(' [Exprs] `)']] {`with' SimpleType} [TemplateBody] + /** ClassTemplate ::= [`extends' TemplateParents] [TemplateBody] */ - def classTemplate(mods: int): Template = + def classTemplate(mods: int, vparamss: List[List[ValDef]]): Template = atPos(in.pos) { val parents = new ListBuffer[Tree]; var args: List[Tree] = List(); @@ -1514,14 +1492,13 @@ abstract class Syntactic: ParserPhase { in.nextToken(); parents += simpleType(); if (in.token == LPAREN) args = argumentExprs(); - } else { - parents += scalaAnyRefConstr + while (in.token == WITH) { + in.nextToken(); + parents += simpleType() + } } - parents += scalaScalaObjectConstr; + parents += scalaScalaObjectConstr; if ((mods & Flags.CASE)!= 0) parents += caseClassConstr; - while (in.token == WITH) { - in.nextToken(); parents += simpleType(); - } val ps = parents.toList; var body = if (in.token == LBRACE) { @@ -1531,7 +1508,8 @@ abstract class Syntactic: ParserPhase { syntaxError("`extends' or `{' expected", true); List() } - if ((mods & Flags.TRAIT) == 0) body = makeSuperCall(args) :: body; + if ((mods & Flags.TRAIT) == 0) + body = makeConstructorPart(mods, vparamss, args) ::: body; Template(ps, body) } @@ -1591,7 +1569,7 @@ abstract class Syntactic: ParserPhase { in.token == LBRACKET || isModifier) { stats ++ - joinAttributes(attributeClauses(), joinComment(tmplDef(modifiers()))) + joinAttributes(attributeClauses(), joinComment(List(tmplDef(modifiers())))) } else if (in.token != SEMI) { syntaxError("illegal start of class or object definition", true); } @@ -1696,7 +1674,7 @@ abstract class Syntactic: ParserPhase { stats += Literal(()).setPos(in.pos) } } else if (isLocalModifier) { - stats ++= tmplDef(localClassModifiers()); + stats += tmplDef(localClassModifiers()); accept(SEMI); if (in.token == RBRACE || in.token == CASE) { stats += Literal(()).setPos(in.pos) diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala index c3a3254cc9..c9561c5e30 100755 --- a/sources/scala/tools/nsc/symtab/Definitions.scala +++ b/sources/scala/tools/nsc/symtab/Definitions.scala @@ -133,7 +133,7 @@ abstract class Definitions: SymbolTable { } private def newMethod(owner: Symbol, name: Name): Symbol = { - val msym = owner.newMethod(Position.NOPOS, name); + val msym = owner.newMethod(Position.NOPOS, name.encode); owner.info.decls.enter(msym); msym } @@ -145,13 +145,15 @@ abstract class Definitions: SymbolTable { def init = { RootClass = NoSymbol.newClass(Position.NOPOS, nme.ROOT.toTypeName) - .setFlag(FINAL | PACKAGE | JAVA).setInfo(rootLoader); + .setFlag(FINAL | MODULE | PACKAGE | JAVA).setInfo(rootLoader); EmptyPackage = RootClass.newPackage(Position.NOPOS, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL); EmptyPackageClass = EmptyPackage.moduleClass; EmptyPackageClass.setInfo(ClassInfoType(List(), new Scope(), EmptyPackageClass)); - EmptyPackage.setInfo(EmptyPackageClass.typeConstructor); + + + EmptyPackage.setInfo(EmptyPackageClass.tpe); RootClass.info.decls.enter(EmptyPackage); JavaPackage = getModule("java"); diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala index fcaae4e8cf..776adab42e 100644 --- a/sources/scala/tools/nsc/symtab/Flags.scala +++ b/sources/scala/tools/nsc/symtab/Flags.scala @@ -63,11 +63,12 @@ object Flags { 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. + val GENFLAGS = // these modifiers can be in generated trees + SOURCEFLAGS | SYNTHETIC | STABLE | ACCESSOR | ACCESS_METHOD | PARAMACCESSOR | LABEL | BRIDGE; + val EXPLICITFLAGS = // these modifiers can be set explicitly in source programs. PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE; val ACCESSFLAGS = PRIVATE | PROTECTED; @@ -75,14 +76,11 @@ object Flags { val CONSTRFLAGS = JAVA; val PICKLEDFLAGS = 0x77777777 & ~LOCKED & ~INITIALIZED; - /** 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 | INCONSTRUCTOR; - /** Module flags inherited by their module-class */ val MODULE2CLASSFLAGS = ACCESSFLAGS | PACKAGE; + def flags2mods(flags: long): int = flags.asInstanceOf[int] & GENFLAGS; + def flagsToString(flags: long): String = List.range(0, 63) .map(i => flagToString(flags & (1L << i))) diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala index d5a51fc66d..ed9aad85fd 100755 --- a/sources/scala/tools/nsc/symtab/Names.scala +++ b/sources/scala/tools/nsc/symtab/Names.scala @@ -254,8 +254,8 @@ class Names { val str = toString(); val res = NameTransformer.encode(str); if (res == str) this - else if (isTypeName) newTypeName(str) - else newTermName(str) + else if (isTypeName) newTypeName(res) + else newTermName(res) } /** Replace $op_name by corresponding operator symbol */ diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala index 52f09275fc..2c3603dbaa 100755 --- a/sources/scala/tools/nsc/symtab/StdNames.scala +++ b/sources/scala/tools/nsc/symtab/StdNames.scala @@ -25,6 +25,8 @@ abstract class StdNames: SymbolTable { def TUPLE_FIELD(index: int) = newTermName(TUPLE_FIELD_PREFIX_STRING + index); + def SETTER_NAME(name: Name) = encode(name.toString() + "_="); + val ERROR = newTermName(""); val ERRORtype = newTypeName(""); diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala index b441231bd4..7e69107d45 100755 --- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -9,7 +9,7 @@ import java.io.IOException; import scala.tools.util.{AbstractFile, Position} import scala.tools.nsc.util.NameTransformer; import scala.collection.mutable.HashMap; -import classfile.ClassfileParser; +import classfile.{ClassfileParser, SymblfileParser}; import Flags._; @@ -80,12 +80,11 @@ abstract class SymbolLoaders { module.moduleClass.setInfo(errorLoader); owner.info.decls.enter(clazz); owner.info.decls.enter(module); - assert(clazz.linkedModule == module); + assert(clazz.linkedModule == module, "" + module + module.hasFlag(MODULE)); assert(module.linkedClass == clazz); } val sources = new HashMap[String, AbstractFile]; - val symbols = new HashMap[String, AbstractFile]; val classes = new HashMap[String, AbstractFile]; val packages = new HashMap[String, AbstractFile]; val it = directory.list(); @@ -96,8 +95,8 @@ abstract class SymbolLoaders { if (filename != "META_INF" && !packages.isDefinedAt(filename)) packages(filename) = file; } else if (filename.endsWith(".symbl")) { val name = filename.substring(0, filename.length() - 6); - if (!symbols.isDefinedAt(name) || - symbols(name).getName().endsWith(".class")) symbols(name) = file; + if (!classes.isDefinedAt(name) || + classes(name).getName().endsWith(".class")) classes(name) = file; } else if (filename.endsWith(".class")) { val name = filename.substring(0, filename.length() - 6); if (!classes.isDefinedAt(name)) classes(name) = file; @@ -115,7 +114,10 @@ abstract class SymbolLoaders { for (val Pair(name, cfile) <- classes.elements) { sources.get(name) match { case Some(sfile) if (sfile.lastModified() > cfile.lastModified()) => {} - case _ => enterClassAndModule(name, classfileLoader(cfile)); + case _ => + val loader = if (cfile.getName().endsWith(".symbl")) symblfileLoader(cfile) + else classfileLoader(cfile); + enterClassAndModule(name, loader) } } for (val Pair(name, file) <- packages.elements) { @@ -130,12 +132,22 @@ abstract class SymbolLoaders { val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global; } + private object symblfileParser extends SymblfileParser { + val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global; + } + def classfileLoader(file: AbstractFile) = new SymbolLoader(root => { classfileParser.parse(file, root); "class file '" + file + "'"; }); + def symblfileLoader(file: AbstractFile) = + new SymbolLoader(root => { + symblfileParser.parse(file, root); + "symbl file '" + file + "'"; + }); + def sourcefileLoader(file: AbstractFile) = new SymbolLoader(root => { global.compileLate(file); diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index e7eeaa92c2..7d87f7e552 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -22,7 +22,7 @@ abstract class Symbols: SymbolTable { var name = initName; var pos = initPos; val id = { ids = ids + 1; ids } - var rawflags: long = 0; + private var rawflags: long = 0; // Creators ------------------------------------------------------------------- @@ -51,8 +51,9 @@ abstract class Symbols: SymbolTable { m.moduleClass.setFlag(JAVA | PACKAGE); m } - final def newThisSym(pos: int) = + final def newThisSym(pos: int) = { newValue(pos, nme.this_).setFlag(SYNTHETIC); + } final def newImport(pos: int) = newValue(pos, nme.IMPORT).setFlag(SYNTHETIC); final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol = @@ -88,33 +89,33 @@ abstract class Symbols: SymbolTable { def isType = false; //to be overridden def isClass = false; //to be overridden - final def isValue = isTerm && !(isModule && ((rawflags & (PACKAGE | JAVA)) != 0)); - final def isVariable = isTerm && (rawflags & MUTABLE) != 0; - final def isGetter = isTerm && (rawflags & ACCESSOR) != 0 && !name.endsWith(nme._EQ); - final def isSetter = isTerm && (rawflags & ACCESSOR) != 0 && name.endsWith(nme._EQ); - final def isValueParameter = isTerm && (rawflags & PARAM) != 0; + final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)); + final def isVariable = isTerm && hasFlag(MUTABLE); + final def isGetter = isTerm && hasFlag(ACCESSOR) && !name.endsWith(nme._EQ); + final def isSetter = isTerm && hasFlag(ACCESSOR) && name.endsWith(nme._EQ); + final def isValueParameter = isTerm && hasFlag(PARAM); final def isLocalDummy = isTerm && (name startsWith nme.LOCAL_PREFIX); - final def isMethod = isTerm && (rawflags & (METHOD | STABLE)) == METHOD; - final def isLabel = isTerm && (rawflags & LABEL) != 0; + final def isMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD; + final def isLabel = isTerm && hasFlag(LABEL); final def isConstructor = isTerm && name == nme.CONSTRUCTOR; - final def isModule = isTerm && (rawflags & MODULE) != 0; - final def isPackage = isModule && (rawflags & PACKAGE) != 0; + final def isModule = isTerm && hasFlag(MODULE); + final def isPackage = isModule && hasFlag(PACKAGE); final def isThisSym = isTerm && name == nme.this_; - final def isError = (rawflags & IS_ERROR) != 0; - final def isAliasType = isType && !isClass && (rawflags & DEFERRED) == 0; - final def isAbstractType = isType && !isClass && (rawflags & DEFERRED) != 0; - final def isTypeParameter = isType && (rawflags & PARAM) != 0; + final def isError = hasFlag(IS_ERROR); + final def isTrait = isClass & hasFlag(TRAIT); + final def isAliasType = isType && !isClass && !hasFlag(DEFERRED); + final def isAbstractType = isType && !isClass && hasFlag(DEFERRED); + final def isTypeParameter = isType && hasFlag(PARAM); final def isAnonymousClass = isClass && (name startsWith nme.ANON_CLASS_NAME); // startsWith necessary because name may grow when lifted final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME; // no lifting for refinement classes - final def isModuleClass = isClass && (rawflags & MODULE) != 0; - final def isPackageClass = isClass && (rawflags & PACKAGE) != 0; + final def isModuleClass = isClass && hasFlag(MODULE); + final def isPackageClass = isClass && hasFlag(PACKAGE); final def isRoot = isPackageClass && name == nme.ROOT.toTypeName; final def isEmptyPackageClass = isPackageClass && name == nme.EMPTY_PACKAGE_NAME.toTypeName; /** Does this symbol denote a stable value? */ final def isStable = - isTerm && (rawflags & MUTABLE) == 0 && - ((rawflags & METHOD) == 0 || (rawflags & STABLE) != 0); + isTerm && !hasFlag(MUTABLE) && (!hasFlag(METHOD) || hasFlag(STABLE)); /** Does this symbol denote the primary constructor * of its enclosing class? */ @@ -155,21 +156,18 @@ abstract class Symbols: SymbolTable { /** The variance of this symbol as an integer */ final def variance: int = - if ((rawflags & COVARIANT) != 0) 1 - else if ((rawflags & CONTRAVARIANT) != 0) -1 + if (hasFlag(COVARIANT)) 1 + else if (hasFlag(CONTRAVARIANT)) -1 else 0; // Flags ---------------------------------------------------------------------------- - final def flags = { - initialize; rawflags & phase.flagMask - } + final def flags = rawflags; + final def flags_=(fs: long) = rawflags = fs; final def setFlag(mask: long): this.type = { rawflags = rawflags | mask; this } final def resetFlag(mask: long): this.type = { rawflags = rawflags & ~mask; this } - final def getFlag(mask: long): long = - (if ((mask & ~CREATIONFLAGS) == 0) rawflags else flags) & mask; - final def hasFlag(mask: long): boolean = - ((if ((mask & ~CREATIONFLAGS) == 0) rawflags else flags) & mask) != 0; + final def getFlag(mask: long): long = rawflags & mask; + final def hasFlag(mask: long): boolean = (rawflags & mask) != 0; final def resetFlags: unit = { rawflags = rawflags & SOURCEFLAGS } // Info and Type ------------------------------------------------------------------- @@ -200,8 +198,8 @@ abstract class Symbols: SymbolTable { phase = infos.start; //System.out.println("completing " + this);//DEBUG tp.complete(this); - phase = current; rawflags = rawflags & ~LOCKED; + phase = current; cnt = cnt + 1; // allow for two completions: // one: sourceCompleter to LazyType, two: LazyType to completed type @@ -215,10 +213,10 @@ abstract class Symbols: SymbolTable { infos = new TypeHistory(phase, info, null); limit = phase; assert(info != null, "setInfo(null) for " + name + " at phase " + phase);//debug - rawflags = if (info.isComplete) rawflags | INITIALIZED - else rawflags & ~INITIALIZED; + rawflags = if (info.isComplete) rawflags | INITIALIZED & ~LOCKED; + else rawflags & ~INITIALIZED & ~LOCKED; if (info.isInstanceOf[MethodType] || info.isInstanceOf[PolyType]) - assert(isClass || (rawflags & METHOD) != 0); + assert(isClass || hasFlag(METHOD)); this } @@ -351,7 +349,7 @@ abstract class Symbols: SymbolTable { /** A clone of this symbol, but with given owner */ final def cloneSymbol(owner: Symbol): Symbol = - cloneSymbolImpl(owner).setInfo(info.cloneInfo(owner)).setFlag(rawflags); + cloneSymbolImpl(owner).setInfo(info.cloneInfo(owner)).setFlag(flags); /** Internal method to clone a symbol's implementation without flags or type */ @@ -390,7 +388,7 @@ abstract class Symbols: SymbolTable { /** The symbol accessed by this accessor function. */ final def accessed: Symbol = { - assert((rawflags & ACCESSOR) != 0); + assert(hasFlag(ACCESSOR)); val name1 = if (name.endsWith(nme._EQ)) name.subName(0, name.length - nme._EQ.length) else name; owner.info.decl(name1.toString() + "$") @@ -423,7 +421,7 @@ abstract class Symbols: SymbolTable { /** The module corresponding to this module class (note that this * is not updated when a module is cloned). */ - //def sourceModule: Symbol = NoSymbol; + def sourceModule: Symbol = NoSymbol; /** The module class corresponding to this module. */ @@ -450,10 +448,9 @@ abstract class Symbols: SymbolTable { /** String representation of symbol's definition key word */ final def keyString: String = - if (isClass) - if ((rawflags & TRAIT) != 0) - if ((rawflags & JAVA) != 0) "interface" else "trait" - else "class" + if (isTrait) + if (hasFlag(JAVA)) "interface" else "trait" + else if (isClass) "class" else if (isType && !hasFlag(PARAM)) "type" else if (isVariable) "var" else if (isPackage) "package" @@ -469,8 +466,8 @@ abstract class Symbols: SymbolTable { else if (isAnonymousClass) "