diff options
author | Martin Odersky <odersky@gmail.com> | 2005-11-30 16:57:50 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-11-30 16:57:50 +0000 |
commit | 634e743658f07343913457108339e5b93bb0ef14 (patch) | |
tree | 16f8e8116222893a475bb5e3c88b197d5e7c283b /sources | |
parent | c037162241748b0b19612051c6fded8dc81916ca (diff) | |
download | scala-634e743658f07343913457108339e5b93bb0ef14.tar.gz scala-634e743658f07343913457108339e5b93bb0ef14.tar.bz2 scala-634e743658f07343913457108339e5b93bb0ef14.zip |
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/tools/nsc/symtab/Flags.scala | 5 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Symbols.scala | 10 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/classfile/UnPickler.scala | 4 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/ExplicitOuter.scala | 37 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/LambdaLift.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/UnCurry.scala | 45 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Contexts.scala | 16 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Namers.scala | 8 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 7 |
9 files changed, 96 insertions, 38 deletions
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala index 92a4e05971..d47551b893 100644 --- a/sources/scala/tools/nsc/symtab/Flags.scala +++ b/sources/scala/tools/nsc/symtab/Flags.scala @@ -51,7 +51,9 @@ object Flags { final val PARAMACCESSOR = 0x20000000; // for value definitions: is an access method for a final val parameter // for parameters: is a val parameter - final val LABEL = 0x40000000; // symbol is a label. Set by TailCall + final val LABEL = 0x40000000; // method symbol is a label. Set by TailCall + final val INCONSTRUCTOR = 0x40000000; // class symbol is defined in this/superclass constructor. + final val CAPTURED = 0x80000000L; // variable is accessed from nested function. Set by LambdaLift final val IS_ERROR = 0x100000000L; // symbol is an error symbol @@ -63,7 +65,6 @@ object Flags { final val EXPANDEDNAME = 0x1000000000L; // name has been expanded with class suffix final val IMPLCLASS = 0x2000000000L; // symbol is an implementation class final val TRANS_FLAG = 0x4000000000L; // transient flag guaranteed to be reset after each phase. - final val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer final val LOCKED = 0x8000000000L; // temporary flag to catch cyclic dependencies diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index 80b037e068..132dafd6b2 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -163,6 +163,7 @@ import Flags._; final def isAbstractType = isType && !isClass && hasFlag(DEFERRED); final def isTypeParameterOrSkolem = isType && hasFlag(PARAM); final def isTypeParameter = isTypeParameterOrSkolem && deSkolemize == this; + final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR); final def isAnonymousClass = isClass && (originalName startsWith nme.ANON_CLASS_NAME); // startsWith necessary because name may grow when lifted and also because of anonymous function classes final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME.toTypeName; // no lifting for refinement classes @@ -192,10 +193,12 @@ import Flags._; final def isModuleVar: boolean = isVariable && nme.isModuleVarName(name); /** Is this symbol static (i.e. with no outer instance)? */ - final def isStatic: boolean = hasFlag(STATIC) || isRoot || owner.isStaticOwner; + final def isStatic: boolean = + hasFlag(STATIC) || isRoot || owner.isStaticOwner; /** Does this symbol denote a class that defines static symbols? */ - final def isStaticOwner: boolean = isPackageClass || isStatic && isModuleClass; + final def isStaticOwner: boolean = + isPackageClass || isModuleClass && isStatic; /** Is this symbol final?*/ final def isFinal: boolean = @@ -260,6 +263,8 @@ import Flags._; def owner: Symbol = rawowner; final def owner_=(owner: Symbol): unit = { rawowner = owner } + def ownerChain: List[Symbol] = this :: owner.ownerChain; + def name: Name = rawname; final def name_=(name: Name): unit = { rawname = name } @@ -1017,6 +1022,7 @@ import Flags._; override def toplevelClass: Symbol = this; override def enclMethod: Symbol = this; override def owner: Symbol = throw new Error(); + override def ownerChain: List[Symbol] = List(); override def alternatives: List[Symbol] = List(); override def reset(completer: Type): unit = {} def cloneSymbolImpl(owner: Symbol): Symbol = throw new Error(); diff --git a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala index 3205cb00c1..091e8024a8 100755 --- a/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/sources/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -177,12 +177,12 @@ abstract class UnPickler { TypeBounds(readTypeRef(), readTypeRef()) case REFINEDtpe => val clazz = readSymbolRef(); +/* val ps = until(end, readTypeRef); val dcls = symScope(clazz); new RefinedType(ps, dcls) { override def symbol = clazz } -/* //todo replace with but need to rethink initialization first - new RefinedType(until(end, readTypeRef), )) { override def symbol = clazz } */ + new RefinedType(until(end, readTypeRef), symScope(clazz)) { override def symbol = clazz } case CLASSINFOtpe => val clazz = readSymbolRef(); ClassInfoType(until(end, readTypeRef), symScope(clazz), clazz) diff --git a/sources/scala/tools/nsc/transform/ExplicitOuter.scala b/sources/scala/tools/nsc/transform/ExplicitOuter.scala index e68d68e77c..2c6e4272d9 100755 --- a/sources/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/sources/scala/tools/nsc/transform/ExplicitOuter.scala @@ -24,6 +24,13 @@ abstract class ExplicitOuter extends InfoTransform { protected def newTransformer(unit: CompilationUnit): Transformer = new ExplicitOuterTransformer(unit); + private def outerClass(clazz: Symbol): Symbol = + if (clazz.owner.isClass) clazz.owner + else outerClass(if (clazz.isClassLocalToConstructor) clazz.owner.owner else clazz.owner); + + private def isStatic(clazz: Symbol) = + clazz.isPackageClass || outerClass(clazz).isStaticOwner; + /** The type transformation method: * 1. Add an outer paramter to the formal parameters of a constructor or mixin constructor * in a non-static class; @@ -33,24 +40,23 @@ abstract class ExplicitOuter extends InfoTransform { def transformInfo(sym: Symbol, tp: Type): Type = tp match { case MethodType(formals, restpe) => if (sym.owner.isTrait && (sym hasFlag PROTECTED)) sym setFlag notPROTECTED; - if (sym.isConstructor && !sym.owner.isStatic) - MethodType(formals ::: List(sym.owner.owner.enclClass.toInterface.thisType), restpe) + if (sym.isConstructor && !isStatic(sym.owner)) + MethodType(formals ::: List(outerClass(sym.owner).toInterface.thisType), restpe) else tp; case ClassInfoType(parents, decls, clazz) => var decls1 = decls; if (!(clazz hasFlag INTERFACE)) { - if (!clazz.isStatic) { + if (!isStatic(clazz)) { decls1 = new Scope(decls1.toList); - val outerType = clazz.owner.enclClass.thisType; val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER); if ((clazz hasFlag TRAIT) || (decls.toList exists (.isClass))) outerAcc.expandName(clazz); decls1 enter ( outerAcc setFlag (PARAMACCESSOR | ACCESSOR | STABLE) - setInfo MethodType(List(), outerType)); + setInfo MethodType(List(), outerClass(clazz).thisType)); decls1 enter (clazz.newValue(clazz.pos, nme.getterToLocal(outerAcc.name)) setFlag (LOCAL | PRIVATE | PARAMACCESSOR | (outerAcc getFlag EXPANDEDNAME)) - setInfo outerType); + setInfo outerClass(clazz).thisType); } if (clazz.isTrait) { decls1 = new Scope(decls1.toList); @@ -101,12 +107,10 @@ abstract class ExplicitOuter extends InfoTransform { /** Select and apply outer accessor from `base' */ private def outerSelect(base: Tree): Tree = { - assert(base.tpe != null, base); - assert(base.tpe.symbol != null, base); - val clazz = base.tpe.symbol.owner.enclClass; + val otp = outerClass(base.tpe.symbol).thisType; Apply( - Select(base, outerMember(base.tpe)) setType MethodType(List(), clazz.thisType), - List()) setType clazz.thisType + Select(base, outerMember(base.tpe)) setType MethodType(List(), otp), + List()) setType otp } override def transform(tree: Tree): Tree = { @@ -116,7 +120,7 @@ abstract class ExplicitOuter extends InfoTransform { case Template(_, _) => outerParam = NoSymbol; case DefDef(_, _, _, vparamss, _, _) => - if (tree.symbol.isConstructor && !(tree.symbol.owner.isStatic)) { + if (tree.symbol.isConstructor && !(isStatic(tree.symbol.owner))) { val lastParam = vparamss.head.last; assert(lastParam.name.startsWith(nme.OUTER), tree); outerParam = lastParam.symbol @@ -232,7 +236,7 @@ abstract class ExplicitOuter extends InfoTransform { localTyper = localTyper.atOwner(tree, currentOwner); var decls1 = decls; if (!(currentOwner hasFlag INTERFACE)) { - if (!currentOwner.isStatic) + if (!isStatic(currentOwner)) decls1 = decls1 ::: outerDefs(currentOwner); // (1) if (currentOwner.isTrait) decls1 = decls1 ::: List(mixinConstructorDef(currentOwner)) // (2) @@ -242,7 +246,7 @@ abstract class ExplicitOuter extends InfoTransform { case constrDef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) if (sym.isConstructor) => val vparamss1 = - if (sym.owner.isStatic) vparamss + if (isStatic(sym.owner)) vparamss else { // (4) val outerField = outerMember(sym.owner.info).accessed; val outerParam = sym.newValueParameter(sym.pos, nme.OUTER) setInfo outerField.info; @@ -257,14 +261,13 @@ abstract class ExplicitOuter extends InfoTransform { if (sym == currentOwner.enclClass || (sym hasFlag MODULE) && sym.isStatic) tree else atPos(tree.pos)(outerPath(outerValue, sym)); // (5) case Apply(sel @ Select(qual, name), args) - if ((name == nme.CONSTRUCTOR || name == nme.MIXIN_CONSTRUCTOR) - && !sel.symbol.owner.isStatic) => + if ((name == nme.CONSTRUCTOR || name == nme.MIXIN_CONSTRUCTOR) && !isStatic(sel.symbol.owner)) => val outerVal = atPos(tree.pos) { if (qual.isInstanceOf[This]) { assert(outerParam != NoSymbol); outerValue } // (8) else { var pre = qual.tpe.prefix; - if (pre == NoPrefix) pre = sym.owner.owner.enclClass.thisType; + if (pre == NoPrefix) pre = outerClass(sym.owner).thisType; gen.mkQualifier(pre) } } diff --git a/sources/scala/tools/nsc/transform/LambdaLift.scala b/sources/scala/tools/nsc/transform/LambdaLift.scala index 04baae1782..21a0870bd0 100755 --- a/sources/scala/tools/nsc/transform/LambdaLift.scala +++ b/sources/scala/tools/nsc/transform/LambdaLift.scala @@ -207,7 +207,7 @@ abstract class LambdaLift extends InfoTransform { case None => searchIn(outer(owner)) } } - if (settings.debug.value) log("proxy " + sym + " in " + sym.owner + " from " + currentOwner + " " + enclMethOrClass(sym.owner));//debug + if (settings.debug.value) log("proxy " + sym + " in " + sym.owner + " from " + currentOwner.ownerChain + " " + enclMethOrClass(sym.owner));//debug if (enclMethOrClass(sym.owner) == enclMethOrClass(currentOwner)) sym else searchIn(currentOwner) } diff --git a/sources/scala/tools/nsc/transform/UnCurry.scala b/sources/scala/tools/nsc/transform/UnCurry.scala index 4a22f9711f..c778be212d 100755 --- a/sources/scala/tools/nsc/transform/UnCurry.scala +++ b/sources/scala/tools/nsc/transform/UnCurry.scala @@ -37,8 +37,6 @@ abstract class UnCurry extends InfoTransform { def newTransformer(unit: CompilationUnit): Transformer = new UnCurryTransformer(unit); override def changesBaseClasses = false; - var needTryLift = false; - private val uncurry = new TypeMap { def apply(tp: Type): Type = tp match { case MethodType(formals, MethodType(formals1, restpe)) => @@ -65,7 +63,9 @@ abstract class UnCurry extends InfoTransform { class UnCurryTransformer(unit: CompilationUnit) extends Transformer { + private var needTryLift = false; private var inPattern = false; + private var inConstructorFlag = 0; override def transform(tree: Tree): Tree = try { //debug postTransform(mainTransform(tree)); @@ -121,7 +121,8 @@ abstract class UnCurry extends InfoTransform { * def isDefinedAt(x: T): boolean = true */ def transformFunction(fun: Function): Tree = { - val anonClass = fun.symbol.owner.newAnonymousFunctionClass(fun.pos) setFlag (FINAL | SYNTHETIC); + val anonClass = fun.symbol.owner.newAnonymousFunctionClass(fun.pos) + setFlag (FINAL | SYNTHETIC | inConstructorFlag); val formals = fun.tpe.typeArgs.init; val restpe = fun.tpe.typeArgs.last; anonClass setInfo ClassInfoType( @@ -197,6 +198,7 @@ abstract class UnCurry extends InfoTransform { } def mainTransform(tree: Tree): Tree = { + def withNeedLift(needLift: Boolean)(f: => Tree): Tree = { val savedNeedTryLift = needTryLift; needTryLift = needLift; @@ -205,9 +207,36 @@ abstract class UnCurry extends InfoTransform { t } + def withInConstructorFlag(inConstructorFlag: int)(f: => Tree): Tree = { + val savedInConstructorFlag = this.inConstructorFlag; + this.inConstructorFlag = inConstructorFlag; + val t = f; + this.inConstructorFlag = savedInConstructorFlag; + t + } + tree match { - case DefDef(_, _, _, _, _, _) => - withNeedLift(false) { super.transform(tree) } + case DefDef(mods, name, tparams, vparamss, tpt, rhs) => + withNeedLift(false) { + if (tree.symbol.isConstructor) { + atOwner(tree.symbol) { + val rhs1 = rhs match { + case Block(stat :: stats, expr) => + copy.Block( + rhs, + withInConstructorFlag(INCONSTRUCTOR) { transform(stat) } :: transformTrees(stats), + transform(expr)); + case _ => + withInConstructorFlag(INCONSTRUCTOR) { transform(rhs) } + } + copy.DefDef( + tree, mods, name, transformAbsTypeDefs(tparams), + transformValDefss(vparamss), transform(tpt), rhs1) + } + } else { + super.transform(tree) + } + } case ValDef(_, _, _, rhs) if (!tree.symbol.owner.isSourceMethod) => @@ -249,10 +278,14 @@ abstract class UnCurry extends InfoTransform { val pat1 = transform(pat); inPattern = false; copy.CaseDef(tree, pat1, transform(guard), transform(body)) + case fun @ Function(_, _) => mainTransform(transformFunction(fun)) + + case Template(_, _) => + withInConstructorFlag(0) { super.transform(tree) } + case _ => - assert(!tree.isInstanceOf[Function]); val tree1 = super.transform(tree); if (isByNameRef(tree1)) typed(atPos(tree1.pos)( diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala index 8035c227a0..3130252f74 100755 --- a/sources/scala/tools/nsc/typechecker/Contexts.scala +++ b/sources/scala/tools/nsc/typechecker/Contexts.scala @@ -64,6 +64,8 @@ import scala.tools.nsc.util.Position; var imports: List[ImportInfo] = List(); var prefix: Type = NoPrefix; + var inConstructorSuffix = false; // are we in a secondary constructor + // after the this constructor call? var reportAmbiguousErrors = false; var reportGeneralErrors = false; var checking = false; @@ -85,10 +87,12 @@ import scala.tools.nsc.util.Position; tree match { case Template(_, _) | PackageDef(_, _) => c.enclClass = c; - c.prefix = skolemizedThisType(this.tree, this.prefix, c.owner) + c.prefix = skolemizedThisType(this.tree, this.prefix, c.owner); + c.inConstructorSuffix = false; case _ => c.enclClass = this.enclClass; - c.prefix = if (c.owner != this.owner && c.owner.isTerm) NoPrefix else this.prefix + c.prefix = if (c.owner != this.owner && c.owner.isTerm) NoPrefix else this.prefix; + c.inConstructorSuffix = this.inConstructorSuffix; } c.variance = this.variance; c.depth = if (scope == this.scope) this.depth else this.depth + 1; @@ -129,13 +133,19 @@ import scala.tools.nsc.util.Position; c } - def constructorContext = { + def makeConstructorContext = { val baseContext = enclClass.outer; val argContext = baseContext.makeNewScope(tree, owner); for (val sym <- scope.toList) argContext.scope enter sym; argContext } + def makeConstructorSuffixContext = { + val c = make(tree); + c.inConstructorSuffix = true; + c + } + def skolemizedThisType(encl: Tree, pre: Type, clazz: Symbol): Type = if (settings.Xgadt.value) { encl match { case ClassDef(_, _, tparamdefs, _, _) => diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala index ae41a3067b..a40a6ea5d8 100755 --- a/sources/scala/tools/nsc/typechecker/Namers.scala +++ b/sources/scala/tools/nsc/typechecker/Namers.scala @@ -95,12 +95,16 @@ trait Namers: Analyzer { } } + private def inConstructorFlag: long = + if (context.owner.isConstructor && !context.inConstructorSuffix) INCONSTRUCTOR + else 0l; + private def enterClassSymbol(pos: int, mods: int, name: Name): Symbol = { var c: Symbol = context.scope.lookup(name); if (c.isType && c.isExternal && context.scope == c.owner.info.decls) { updatePosFlags(c, pos, mods); } else { - c = enterInScope(context.owner.newClass(pos, name).setFlag(mods)) + c = enterInScope(context.owner.newClass(pos, name).setFlag(mods | inConstructorFlag)) } if (c.owner.isPackageClass) currentRun.symSource(c) = context.unit.source.getFile(); c @@ -115,7 +119,7 @@ trait Namers: Analyzer { context.scope.unlink(m); m = context.owner.newModule(pos, name); m.setFlag(mods); - m.moduleClass.setFlag(mods); + m.moduleClass.setFlag(mods | inConstructorFlag); enterInScope(m) } if (m.owner.isPackageClass) currentRun.symSource(m) = context.unit.source.getFile(); diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index 97a56f75f4..0df5c37f30 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -581,7 +581,7 @@ import collection.mutable.HashMap; def typedValDef(vdef: ValDef): ValDef = { val sym = vdef.symbol; val typer1 = if (sym.hasFlag(PARAM) && sym.owner.isConstructor) - newTyper(context.constructorContext) + newTyper(context.makeConstructorContext) else this; var tpt1 = checkNoEscaping.privates(sym, typer1.typedType(vdef.tpt)); checkNonCyclic(vdef.pos, tpt1.tpe, sym); @@ -676,7 +676,8 @@ import collection.mutable.HashMap; val result = ddef.rhs match { case Block(stat :: stats, expr) => val stat1 = typedSuperCall(stat); - typed(copy.Block(ddef.rhs, stats, expr), UnitClass.tpe) match { + newTyper(context.makeConstructorSuffixContext).typed( + copy.Block(ddef.rhs, stats, expr), UnitClass.tpe) match { case block1 @ Block(stats1, expr1) => copy.Block(block1, stat1 :: stats1, expr1) } @@ -840,7 +841,7 @@ import collection.mutable.HashMap; } def typedArg(arg: Tree, pt: Type): Tree = { - val argTyper = if ((mode & INCONSTRmode) != 0) newTyper(context.constructorContext) + val argTyper = if ((mode & INCONSTRmode) != 0) newTyper(context.makeConstructorContext) else this; argTyper.typed(arg, mode & stickyModes, pt) } |