diff options
author | Martin Odersky <odersky@gmail.com> | 2005-09-06 14:10:41 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-09-06 14:10:41 +0000 |
commit | 7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671 (patch) | |
tree | bf40f0447b7b2f165aea41c57ae70b06ded6ced1 | |
parent | 16632c98c6b3213bf6e8dd9e41f76a6b23f524fe (diff) | |
download | scala-7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671.tar.gz scala-7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671.tar.bz2 scala-7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671.zip |
*** empty log message ***
-rwxr-xr-x | sources/scala/tools/nsc/Global.scala | 6 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/TreePrinters.scala | 6 | ||||
-rw-r--r-- | sources/scala/tools/nsc/symtab/Flags.scala | 41 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Scopes.scala | 7 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/StdNames.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Symbols.scala | 23 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/classfile/Pickler.scala | 4 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/classfile/UnPickler.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/AddInterfaces.scala | 6 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/ExplicitOuter.scala | 26 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Infer.scala | 4 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/RefChecks.scala | 4 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 53 |
13 files changed, 118 insertions, 66 deletions
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index 55c265d29f..d163b9eae3 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -206,6 +206,10 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable val global: Global.this.type = Global.this; } + object mixin extends Mixin { + val global: Global.this.type = Global.this; + } + object sampleTransform extends SampleTransform { val global: Global.this.type = Global.this; } @@ -232,6 +236,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable lambdaLift, flatten, constructors, + //mixin, if (settings.Xshowicode.value) genicode else sampleTransform); @@ -265,6 +270,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable val typerPhase = phaseNamed("typer"); val refchecksPhase = phaseNamed("refchecks"); val erasurePhase = phaseNamed("erasure"); + val delegateMixins = phaseNamed("mixin") != NoPhase; val typer = new analyzer.Typer(analyzer.NoContext.make(EmptyTree, definitions.RootClass, new Scope())) { override def typed(tree: Tree, mode: int, pt: Type): Tree = { diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala index 49dd0a3b05..9678a70c9b 100644 --- a/sources/scala/tools/nsc/ast/TreePrinters.scala +++ b/sources/scala/tools/nsc/ast/TreePrinters.scala @@ -80,11 +80,7 @@ abstract class TreePrinters { if (!tree.isEmpty) { print(prefix); print(tree) } def printFlags(tree: Tree, flags: long): unit = - printModifiers( - if (tree.symbol == NoSymbol) flags - else if (settings.debug.value) tree.symbol.flags - else tree.symbol.flags & SourceFlags.asInstanceOf[long]); - //todo: check codegen so that we can remove this + printModifiers(if (tree.symbol == NoSymbol) flags else tree.symbol.flags); def printModifiers(flags: long): unit = { val mask = if (settings.debug.value) -1 else PrintableFlags; diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala index c7d187af97..8845ade238 100644 --- a/sources/scala/tools/nsc/symtab/Flags.scala +++ b/sources/scala/tools/nsc/symtab/Flags.scala @@ -21,8 +21,8 @@ object Flags { // Note difference to DEFERRED! final val DEFERRED = 0x00000100; // was `abstract' for members - final val METHOD = 0x00000200; // a def parameter - final val TRAIT = 0x00000400; // a trait + final val METHOD = 0x00000200; // a method + final val MODULE = 0x00000400; // symbol is module or class implementing a module final val INTERFACE = 0x00000800; // symbol is an interface final val MUTABLE = 0x00001000; // symbol is a mutable variable. @@ -43,12 +43,11 @@ object Flags { final val STATIC = 0x00800000; // static field, method or class final val CASEACCESSOR = 0x01000000; // symbol is a case parameter (or its accessor) - final val MODULE = 0x02000000; // symbol is module or class implementing a module + final val TRAIT = 0x02000000; // symbol is a trait final val BRIDGE = 0x04000000; // function is a bridge method. Set by Erasure final val ACCESSOR = 0x08000000; // a value or variable accessor - final val ACCESS_METHOD = 0x10000000; // function is an access function for a method in some - // outer class; set by ExplicitOuter + final val SUPERACCESSOR = 0x10000000; // a super accessor final val PARAMACCESSOR = 0x20000000; // for value definitions: is an access method for a final val parameter // for parameters: is a val parameter @@ -57,16 +56,17 @@ object Flags { final val IS_ERROR = 0x100000000l; // symbol is an error symbol final val OVERLOADED = 0x200000000l; // symbol is overloaded + final val FLATTENED = 0x400000000l; // class has been lifted out to package level + final val MIXEDIN = 0x800000000l; // member has been mixed in - final val TRANS_FLAG = 0x400000000l; // transient flag guaranteed to be reset after each phase. + final val TRANS_FLAG = 0x1000000000l; // transient flag guaranteed to be reset after each phase. final val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer - final val FLATTENED = 0x800000000l; // class has been lifted out to package level - final val INITIALIZED = 0x1000000000l; // symbol's definition is complete - final val LOCKED = 0x2000000000l; // temporary flag to catch cyclic dependencies + final val INITIALIZED = 0x2000000000l; // symbol's definition is complete + final val LOCKED = 0x4000000000l; // temporary flag to catch cyclic dependencies - final val InitialFlags = 0x000000FFFFFFFFFFl; // flags that are enabled from phase 1. - final val LateFlags = 0x000FFF0000000000l; // flags that override flags in 0xFFF. + final val InitialFlags = 0x000000FFFFFFFFFFl; // flags that are enabled from phase 1. + final val LateFlags = 0x000FFF0000000000l; // flags that override flags in 0xFFF. final val AntiFlags = 0x7FF0000000000000l; // flags that cancel flags in 0x7FF final val LateShift = 40l; final val AntiShift = 52l; @@ -74,18 +74,24 @@ object Flags { // late flags (set by a transformer phase) final val lateDEFERRED = (DEFERRED: long) << LateShift; final val lateINTERFACE = (INTERFACE: long) << LateShift; + final val lateMODULE = (MODULE: long) << LateShift; + final val lateFINAL = (FINAL: long) << LateShift; final val notPRIVATE = (PRIVATE: long) << AntiShift; final val notPROTECTED = (PROTECTED: long) << AntiShift; + final val notFINAL = (FINAL: long) << AntiShift; // masks - final val SourceFlags = 0x002FFFFF; // these modifiers can be set in source programs. + /** This flags can be set when class or module symbol is first created. */ + final val TopLevelCreationFlags = + MODULE | PACKAGE | FINAL | JAVA; + final val ExplicitFlags = // these modifiers can be set explicitly in source programs. PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE; + final val PrintableFlags = // these modifiers appear in TreePrinter output. ExplicitFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | ACCESSOR | - ACCESS_METHOD | PARAMACCESSOR | LABEL | BRIDGE | STATIC; - final val GenFlags = // these modifiers can be in generated trees - SourceFlags | PrintableFlags; + SUPERACCESSOR | PARAMACCESSOR | LABEL | BRIDGE | STATIC; + final val FieldFlags = MUTABLE | CASEACCESSOR | PARAMACCESSOR | STATIC | FINAL; final val AccessFlags = PRIVATE | PROTECTED; @@ -96,7 +102,7 @@ object Flags { /** Module flags inherited by their module-class */ final val ModuleToClassFlags = AccessFlags | PACKAGE; - def flags2mods(flags: long): int = flags.asInstanceOf[int] & GenFlags; + def flags2mods(flags: long): int = flags.asInstanceOf[int]; def flagsToString(flags: long): String = List.range(0, 63) @@ -109,6 +115,7 @@ object Flags { else if (flag == IS_ERROR) "<is-error>" else if (flag == OVERLOADED) "<overloaded>" else if (flag == TRANS_FLAG) "<trans-flag>" + else if (flag == MIXEDIN) "<mixedin>" else if (flag == INITIALIZED) "<initialized>" else if (flag == LOCKED) "<locked>" else flag.asInstanceOf[int] match { @@ -145,7 +152,7 @@ object Flags { case CASEACCESSOR => "<caseaccessor>" case ACCESSOR => "<accessor>" - case ACCESS_METHOD => "<access>" + case SUPERACCESSOR => "<superaccessor>" case PARAMACCESSOR => "<paramaccessor>" case LABEL => "<label>" case BRIDGE => "<bridge>" diff --git a/sources/scala/tools/nsc/symtab/Scopes.scala b/sources/scala/tools/nsc/symtab/Scopes.scala index 58f82382be..cc2da304c0 100755 --- a/sources/scala/tools/nsc/symtab/Scopes.scala +++ b/sources/scala/tools/nsc/symtab/Scopes.scala @@ -113,6 +113,13 @@ abstract class Scopes: SymbolTable { */ def enter(sym: Symbol): unit = enter(newScopeEntry(sym, this)); + /** enter a symbol + */ + def enterUnique(sym: Symbol): unit = { + assert(lookup(sym.name) == NoSymbol); + enter(sym); + } + private def createHash: unit = { hashtable = new Array[ScopeEntry](HASHSIZE); enterInHash(elems); diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala index 0c31434cb7..17997dd510 100755 --- a/sources/scala/tools/nsc/symtab/StdNames.scala +++ b/sources/scala/tools/nsc/symtab/StdNames.scala @@ -80,6 +80,7 @@ abstract class StdNames: SymbolTable { def isLocalName(name: Name) = name(name.length - 1) == ' '; def GETTER_NAME(name: Name) = newTermName(name.toString().substring(0, name.length - 1)); def SETTER_NAME(name: Name) = encode(name.toString() + "_="); + def SUPER_NAME(name: Name) = newTermName("super$" + name); val ERROR = newTermName("<error>"); val ERRORtype = newTypeName("<error>"); @@ -101,6 +102,7 @@ abstract class StdNames: SymbolTable { val ROOT = newTermName("<root>"); val REPEATED_PARAM_CLASS_NAME = newTermName("<repeated>"); val BYNAME_PARAM_CLASS_NAME = newTermName("<byname>"); + val SELF = newTermName("$self"); val CONSTRUCTOR = newTermName("<init>"); val MIXIN_CONSTRUCTOR = newTermName("$init$"); diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index c45646cb26..7e844b05b0 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -211,7 +211,7 @@ abstract class Symbols: SymbolTable { final def resetFlag(mask: long): this.type = { rawflags = rawflags & ~mask; this } final def getFlag(mask: long): long = flags & mask; final def hasFlag(mask: long): boolean = (flags & mask) != 0; - final def resetFlags: unit = { rawflags = rawflags & SourceFlags } + final def resetFlags: unit = { rawflags = rawflags & TopLevelCreationFlags } // Info and Type ------------------------------------------------------------------- @@ -481,7 +481,7 @@ abstract class Symbols: SymbolTable { /** For a paramaccessor: a superclass paramaccessor for which this symbol is * an alias, NoSymbol for all others */ - def aliasSym: Symbol = NoSymbol; + def alias: Symbol = NoSymbol; /** The class with the same name in the same package as this module or * case class factory @@ -531,19 +531,24 @@ abstract class Symbols: SymbolTable { base.info.nonPrivateDecl(name).suchThat(sym => !sym.isTerm || (base.thisType.memberType(sym) matches base.thisType.memberType(this))); - /** The symbol accessed by a super in the definition of `this' when seen from + /** The symbol accessed by a super in the definition of this symbol when seen from * class `base'. This symbol is always concrete. * pre: `this.owner' is in the base class sequence of `base'. */ final def superSymbol(base: Symbol): Symbol = { - var bcs = base.info.baseClasses.dropWhile(.!=(owner)).tail; + var bcs = base.info.baseClasses.dropWhile(owner !=).tail; var sym: Symbol = NoSymbol; while (!bcs.isEmpty && sym == NoSymbol) { - sym = overriddenSymbol(bcs.head).suchThat(sym => !(sym hasFlag DEFERRED));; + sym = overriddenSymbol(bcs.head).suchThat(sym => !sym.hasFlag(DEFERRED)); bcs = bcs.tail } sym } + + /** The superaccessor for this symbol in the definition of `base'. */ + final def superAccessor(base: Symbol): Symbol = + base.info.decl(nme.SUPER_NAME(name)) suchThat (.alias.==(this)); + /* def referenced: Symbol = throw new Error("referenced inapplicable for " + this); @@ -690,11 +695,11 @@ abstract class Symbols: SymbolTable { clone } - override def aliasSym: Symbol = - if (hasFlag(PARAMACCESSOR)) referenced else NoSymbol; + override def alias: Symbol = + if (hasFlag(SUPERACCESSOR | PARAMACCESSOR)) referenced else NoSymbol; def setAlias(alias: Symbol): TermSymbol = { - assert(hasFlag(PARAMACCESSOR)); + assert(hasFlag(SUPERACCESSOR | PARAMACCESSOR | MIXEDIN)); referenced = alias; this } @@ -809,7 +814,7 @@ abstract class Symbols: SymbolTable { clone } - override def sourceModule = if (isModuleClass) owner.linkedModule else NoSymbol; + override def sourceModule = if (isModuleClass) linkedModule else NoSymbol; } /** A class for module class symbols diff --git a/sources/scala/tools/nsc/symtab/classfile/Pickler.scala b/sources/scala/tools/nsc/symtab/classfile/Pickler.scala index 22b726453e..172bf358a7 100755 --- a/sources/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/sources/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -85,7 +85,7 @@ abstract class Pickler extends SubComponent { putType(sym.info); if (sym.thisSym != sym) putType(sym.typeOfThis); - putSymbol(sym.aliasSym); + putSymbol(sym.alias); } else if (sym != NoSymbol) { putEntry(if (sym.isModuleClass) sym.name.toTermName else sym.name); if (!sym.owner.isRoot) putSymbol(sym.owner); @@ -173,7 +173,7 @@ abstract class Pickler extends SubComponent { if (sym.isAbstractType) TYPEsym else ALIASsym case sym: TermSymbol => writeSymInfo(sym); - if (sym.aliasSym != NoSymbol) writeRef(sym.aliasSym); + if (sym.alias != NoSymbol) writeRef(sym.alias); if (sym.isModule) MODULEsym else VALsym case NoType => NOtpe diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala index 7969768c46..55991e660f 100755 --- a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -120,7 +120,7 @@ abstract class UnPickler { errorBadSignature("bad symbol tag: " + tag); } sym.setFlag(flags); - if (readIndex != end) assert(sym hasFlag (ACCESSOR | PARAMACCESSOR)); + if (readIndex != end) assert(sym hasFlag (SUPERACCESSOR | PARAMACCESSOR)); sym.setInfo( if (readIndex != end) new LazyTypeRefAndAlias(inforef, readNat()) else new LazyTypeRef(inforef)); diff --git a/sources/scala/tools/nsc/transform/AddInterfaces.scala b/sources/scala/tools/nsc/transform/AddInterfaces.scala index 1688585893..751c782ef3 100755 --- a/sources/scala/tools/nsc/transform/AddInterfaces.scala +++ b/sources/scala/tools/nsc/transform/AddInterfaces.scala @@ -15,7 +15,7 @@ abstract class AddInterfaces extends InfoTransform { import definitions._; // standard classes and methods import posAssigner.atPos; // for filling in tree positions - override def phaseNewFlags: long = lateDEFERRED | lateINTERFACE; + override def phaseNewFlags: long = lateDEFERRED | lateINTERFACE | notFINAL; // Type transformation @@ -25,7 +25,7 @@ abstract class AddInterfaces extends InfoTransform { private val implMethodMap = new HashMap[Symbol, Symbol]; private def implClassName(sym: Symbol): Name = - newTermName(sym.name.toString() + nme.IMPL_CLASS_SUFFIX); + newTypeName(sym.name.toString() + nme.IMPL_CLASS_SUFFIX); private def needsImplClass(sym: Symbol): boolean = sym.isTrait && (!(sym hasFlag INTERFACE) || (sym hasFlag lateINTERFACE)) && !sym.isImplClass; @@ -64,7 +64,7 @@ abstract class AddInterfaces extends InfoTransform { val impl = sym.cloneSymbol(implClass).setInfo(sym.info); if (!impl.isExternal) implMethodMap(sym) = impl; decls enter impl; - sym setFlag lateDEFERRED + sym setFlag (lateDEFERRED | notFINAL) } } else { sym.owner = implClass; diff --git a/sources/scala/tools/nsc/transform/ExplicitOuter.scala b/sources/scala/tools/nsc/transform/ExplicitOuter.scala index 673ba1fdb8..fb9bb2cc98 100755 --- a/sources/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/sources/scala/tools/nsc/transform/ExplicitOuter.scala @@ -313,8 +313,7 @@ abstract class ExplicitOuter extends InfoTransform { /** The second step performs the following transformations: * 1. Add definitions of superaccessors to the members of a class * (@see makeSuperAccessorDefs) - * 2. Remove private modifiers from members M of mixins T that are accessed with a qualifier - * different from T.this. (@see makeNotPrivate) + * 2. Remove private modifiers from members M of mixins T. (@see makeNotPrivate) * 3. Remove `private' modifier from class members M that are accessed from an inner class. * 4. Remove `protected' modifier from class members M that are accessed * without a super qualifier accessed from an inner class. (@see makeNotPrivate) @@ -340,11 +339,11 @@ abstract class ExplicitOuter extends InfoTransform { * to avoid name clashes. */ def makeNotPrivate(sym: Symbol): unit = - if (sym hasFlag PRIVATE) { - if (sym.isTerm) - sym.name = newTermName( - sym.name.toString() + "$$" + sym.owner.enclClass.fullNameString('$')); + if (sym.isTerm && (sym hasFlag PRIVATE)) { + sym.name = newTermName( + sym.name.toString() + "$$" + sym.owner.enclClass.fullNameString('$')); sym setFlag notPRIVATE; + if (!(sym hasFlag DEFERRED)) sym setFlag lateFINAL; } /** The second-step transformation method */ @@ -356,14 +355,15 @@ abstract class ExplicitOuter extends InfoTransform { val accessors = makeSuperAccessorDefs(sym.owner, typer.atOwner(tree1, currentOwner)); if (accessors.isEmpty) tree1 else copy.Template(tree1, parents, stats ::: accessors) + case DefDef(_, _, _, _, _, _) => + if (sym.owner.isTrait && (sym hasFlag (ACCESSOR | SUPERACCESSOR))) makeNotPrivate(sym); + tree1 case Select(qual, name) => - if ((sym hasFlag PRIVATE) && - ((sym.owner.isTrait && qual.tpe != sym.owner.thisType) || // (2) - currentOwner.enclClass != sym.owner)) // (3) - makeNotPrivate(sym) - else if ((sym hasFlag PROTECTED) && - !(qual.isInstanceOf[Super] || - (qual.tpe.widen.symbol isSubClass currentOwner.enclClass))) + if (currentOwner.enclClass != sym.owner) // (3) + makeNotPrivate(sym); + if ((sym hasFlag PROTECTED) && + !(qual.isInstanceOf[Super] || + (qual.tpe.widen.symbol isSubClass currentOwner.enclClass))) sym setFlag notPROTECTED; tree1 case _ => diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala index 5b1473918d..fe7a9995f5 100755 --- a/sources/scala/tools/nsc/typechecker/Infer.scala +++ b/sources/scala/tools/nsc/typechecker/Infer.scala @@ -207,14 +207,14 @@ abstract class Infer: Analyzer { tree setSymbol sym setType ErrorType } else if (sym.owner.hasFlag(INCONSTRUCTOR) && !sym.isTypeParameter && !sym.isConstructor && - site.isInstanceOf[This] && !phase.erasedTypes) { + (site.isInstanceOf[This] || site.isInstanceOf[Super]) && !phase.erasedTypes) { errorTree(tree, "" + sym + " cannot be accessed from constructor"); } else { val sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super])); if (sym1 == NoSymbol) { if (settings.debug.value) System.out.println(context);//debug System.out.println(tree);//debug - System.out.println("" + pre + " " + sym.owner.thisType + (pre =:= sym.owner.thisType));//debug + System.out.println("" + pre + " " + sym.owner + " " + context.owner + " " + context.outer.enclClass.owner + " " + sym.owner.thisType + (pre =:= sym.owner.thisType));//debug errorTree(tree, sym.toString() + " cannot be accessed in " + pre.widen) } else { var owntype = pre.memberType(sym1); diff --git a/sources/scala/tools/nsc/typechecker/RefChecks.scala b/sources/scala/tools/nsc/typechecker/RefChecks.scala index a9ac4d1f24..71ac61b4f6 100755 --- a/sources/scala/tools/nsc/typechecker/RefChecks.scala +++ b/sources/scala/tools/nsc/typechecker/RefChecks.scala @@ -514,13 +514,13 @@ abstract class RefChecks extends InfoTransform { unit.error(tree.pos, "symbol accessed from super may not be abstract"); case _ => } - } else if (sym.aliasSym != NoSymbol) { + } else if (sym.alias != NoSymbol) { qual match { case This(_) => result = typed { Select( Super(qual.symbol, qual.symbol.info.parents.head.symbol.name) setPos qual.pos, - sym.aliasSym) setPos tree.pos + sym.alias) setPos tree.pos } if (settings.debug.value) System.out.println("alias replacement: " + tree + " ==> " + result);//debug diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index 2d8cbd18c8..ce729dce52 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -22,7 +22,14 @@ abstract class Typers: Analyzer { var selcnt = 0; var implcnt = 0; - private var transformed = new HashMap[Tree, Tree]; + private val transformed = new HashMap[Tree, Tree]; + + private val superDefs = new HashMap[Symbol, ListBuffer[Tree]]; + + def init = { + transformed.clear; + superDefs.clear; + } def newTyper(context: Context): Typer = new Typer(context); @@ -216,6 +223,26 @@ abstract class Typers: Analyzer { } else tree } + class AddSuperAccessors(clazz: Symbol) extends Traverser { + override def traverse(tree: Tree) = tree match { + case Select(Super(_, mix), _) => + if (tree.isTerm && mix == nme.EMPTY.toTypeName) { + if (tree.symbol.superAccessor(clazz) == NoSymbol) { + System.out.println("add super acc " + tree.symbol + tree.symbol.locationString + " to " + clazz);//debug + clazz.info.decls enter + clazz.newMethod(tree.pos, nme.SUPER_NAME(tree.symbol.name)) + .setFlag(SUPERACCESSOR | PRIVATE) + .setAlias(tree.symbol) + .setInfo(clazz.thisType.memberType(tree.symbol)) + } + } + case Template(_, _) => + ; + case _ => + super.traverse(tree) + } + } + /** Perform the following adaptations of expression, pattern or type `tree' wrt to * given mode `mode' and given prototype `pt': * (0) Convert expressions with constant types to literals @@ -474,7 +501,8 @@ abstract class Typers: Analyzer { else typed(Assign(Select(This(value.owner), getterDef.symbol), Ident(vparamss.head.head))))) } - val gs = if ((mods & MUTABLE) != 0) List(getterDef, setterDef) else List(getterDef); + val gs = if ((mods & MUTABLE) != 0) List(getterDef, setterDef) + else List(getterDef); if ((mods & DEFERRED) != 0) gs else vdef :: gs case DocDef(comment, defn) => addGetterSetter(defn) map (stat => DocDef(comment, stat)) @@ -485,20 +513,21 @@ abstract class Typers: Analyzer { } def typedTemplate(templ: Template): Template = { - if (templ.symbol == NoSymbol) - templ setSymbol context.owner.newLocalDummy(templ.pos); + val clazz = context.owner; + if (templ.symbol == NoSymbol) templ setSymbol clazz.newLocalDummy(templ.pos); val parents1 = parentTypes(templ); val selfType = - if (context.owner.isAnonymousClass && !phase.erasedTypes) - intersectionType(context.owner.info.parents, context.owner.owner) - else context.owner.typeOfThis; + if (clazz.isAnonymousClass && !phase.erasedTypes) + intersectionType(clazz.info.parents, clazz.owner) + else clazz.typeOfThis; // the following is necessary for templates generated later - new Namer(context.outer.make(templ, context.owner, context.owner.info.decls)) - .enterSyms(templ.body); + new Namer(context.outer.make(templ, clazz, clazz.info.decls)).enterSyms(templ.body); validateParentClasses(parents1, selfType); val body1 = templ.body flatMap addGetterSetter; val body2 = typedStats(body1, templ.symbol); - copy.Template(templ, parents1, body2) setType context.owner.tpe + if (clazz.isTrait && phase.id <= typerPhase.id) + new AddSuperAccessors(clazz).traverseTrees(body2); + copy.Template(templ, parents1, body2) setType clazz.tpe } def typedValDef(vdef: ValDef): ValDef = { @@ -544,7 +573,7 @@ abstract class Typers: Analyzer { superArg match { case Ident(name) => if (vparamss.exists(.exists(vp => vp.symbol == superArg.symbol))) { - var alias = superAcc.initialize.aliasSym; + var alias = superAcc.initialize.alias; if (alias == NoSymbol) alias = superAcc.getter; if (alias != NoSymbol && superClazz.info.nonPrivateMember(alias.name) != alias) @@ -1098,7 +1127,7 @@ abstract class Typers: Analyzer { val rhs1 = typed(rhs, lhs1.tpe); copy.Assign(tree, lhs1, rhs1) setType UnitClass.tpe; } else { - System.out.println("" + lhs1 + " " + varsym + " " + flagsToString(varsym.flags));//debug + System.out.println("" + lhs1 + " " + varsym + " " + varsym.isValue + " " + flagsToString(varsym.flags));//debug if (!lhs1.tpe.isError) error(tree.pos, "assignment to non-variable "); setError(tree) } |