summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-09-06 14:10:41 +0000
committerMartin Odersky <odersky@gmail.com>2005-09-06 14:10:41 +0000
commit7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671 (patch)
treebf40f0447b7b2f165aea41c57ae70b06ded6ced1
parent16632c98c6b3213bf6e8dd9e41f76a6b23f524fe (diff)
downloadscala-7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671.tar.gz
scala-7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671.tar.bz2
scala-7fa7c9317aac5bc9c40e47ef19cf13b6d84ad671.zip
*** empty log message ***
-rwxr-xr-xsources/scala/tools/nsc/Global.scala6
-rw-r--r--sources/scala/tools/nsc/ast/TreePrinters.scala6
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala41
-rwxr-xr-xsources/scala/tools/nsc/symtab/Scopes.scala7
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala23
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/Pickler.scala4
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/UnPickler.scala2
-rwxr-xr-xsources/scala/tools/nsc/transform/AddInterfaces.scala6
-rwxr-xr-xsources/scala/tools/nsc/transform/ExplicitOuter.scala26
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Infer.scala4
-rwxr-xr-xsources/scala/tools/nsc/typechecker/RefChecks.scala4
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala53
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)
}