diff options
author | Martin Odersky <odersky@gmail.com> | 2006-09-11 19:49:03 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-09-11 19:49:03 +0000 |
commit | 1237c5202669272825990e0c41803bd39a0846c8 (patch) | |
tree | 2583a67e460da54fd23acfeb1887f0e7a47ec51a /src | |
parent | 9a8e9075dc345207d1979e703907ce923fff8691 (diff) | |
download | scala-1237c5202669272825990e0c41803bd39a0846c8.tar.gz scala-1237c5202669272825990e0c41803bd39a0846c8.tar.bz2 scala-1237c5202669272825990e0c41803bd39a0846c8.zip |
changed explicit outer scheme
repaired tree checkers
Diffstat (limited to 'src')
13 files changed, 389 insertions, 389 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 00d336cc1e..c38f462857 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -337,8 +337,8 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, newScope)) def phaseDescriptors: List[SubComponent] = List( - analyzer.namerFactory, - analyzer.typerFactory, + analyzer.namerFactory: SubComponent, // note: types are there because otherwise + analyzer.typerFactory: SubComponent, // consistency check after refchecks would fail. superAccessors, pickler, refchecks, diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 64daebb8a7..c69f55da1b 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -144,7 +144,7 @@ abstract class TreePrinters { printModifiers(tree, mods) print((if (mods hasFlag TRAIT) "trait " else "class ") + symName(tree, name)) printTypeParams(tparams) - printOpt("requires ", tp); print(" extends "); print(impl) + printOpt(" requires ", tp); print(" extends "); print(impl) case PackageDef(packaged, stats) => printAttributes(tree) diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index d2214148b6..002ffb2ba3 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -85,7 +85,9 @@ trait StdNames requires SymbolTable { def isSetterName(name: Name) = name.endsWith(SETTER_SUFFIX) def isLocalDummyName(name: Name) = name.startsWith(LOCALDUMMY_PREFIX) -// def originalName(name: Name): Name = { + /** If `name' is an expandedName, the original name. Otherwise `name' itself. + * @see Symbol.expandedName + */ def originalName(name: Name): Name = { var i = name.length; while (i >= 2 && !(name(i - 1) == '$' && name(i - 2) == '$')) i = i - 1; @@ -94,10 +96,6 @@ trait StdNames requires SymbolTable { name.subName(i, name.length) } else name } -// val result = originalName(name) -// System.out.println("oroginal " + name + " = " + result) -// result -// } def localToGetter(name: Name): Name = { assert(isLocalName(name))//debug @@ -192,7 +190,6 @@ trait StdNames requires SymbolTable { val Function = newTermName("Function") val Int = newTermName("Int") val Labelled = newTermName("Labelled") - val List = newTermName("List") val Long = newTermName("Long") val Nil = newTermName("Nil") val Object = newTermName("Object") diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 7784bd24b8..bd191710bf 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -124,6 +124,15 @@ trait Symbols requires SymbolTable { .setFlag(OVERLOADED) .setInfo(OverloadedType(pre, alternatives)) + final def newOuterAccessor(pos: PositionType) = { + val sym = newMethod(pos, nme.OUTER) + sym setFlag STABLE + if (isTrait) sym setFlag DEFERRED + sym.expandName(this) + sym.referenced = this + sym + } + final def newErrorValue(name: Name) = newValue(pos, name).setFlag(SYNTHETIC | IS_ERROR).setInfo(ErrorType) final def newAliasType(pos: PositionType, name: Name) = @@ -316,8 +325,12 @@ trait Symbols requires SymbolTable { def ownerChain: List[Symbol] = this :: owner.ownerChain def name: Name = rawname + final def name_=(name: Name): unit = { rawname = name } + /** If this symbol has an expanded name, its original name, otherwise its name itself. + * @see expandName + */ def originalName = nme.originalName(name) final def flags = { @@ -616,10 +629,24 @@ trait Symbols requires SymbolTable { final def implClass: Symbol = owner.info.decl(nme.implClassName(name)) + /** The class that is logically an outer class of given `clazz'. + * This is the enclosing class, except for classes defined locally to constructors, + * where it is the outer class of the enclosing class + */ + final def outerClass: Symbol = + if (owner.isClass) owner + else if (isClassLocalToConstructor) owner.owner.outerClass + else owner.outerClass + /** For a paramaccessor: a superclass paramaccessor for which this symbol * is an alias, NoSymbol for all others */ def alias: Symbol = NoSymbol + /** For an outer accessor: The class from which the outer originates. + * For all other symbols: NoSymbol + */ + def outerSource: Symbol = NoSymbol + /** The superclass of this class */ def superClass: Symbol = if (info.parents.isEmpty) NoSymbol else info.parents.head.symbol @@ -780,8 +807,10 @@ trait Symbols requires SymbolTable { /** The expanded name of `name' relative to this class as base */ - def expandedName(name: Name): Name = + def expandedName(name: Name): Name = { + newTermName(fullNameString('$') + nme.EXPAND_SEPARATOR_STRING + name) + } def sourceFile: AbstractFile = (if (isModule) moduleClass else toplevelClass).sourceFile @@ -798,7 +827,7 @@ trait Symbols requires SymbolTable { /** A tag which (in the ideal case) uniquely identifies class symbols */ final def tag: int = fullNameString.hashCode() - /** The simple name of this Symbol (this is always a term name) */ + /** The simple name of this Symbol */ final def simpleName: Name = name /** String representation of symbol's definition key word */ @@ -848,8 +877,8 @@ trait Symbols requires SymbolTable { final def fullNameString(separator: char): String = { assert(owner != NoSymbol, this) var str = - if (owner.isRoot || owner.isEmptyPackageClass) simpleName.toString() - else owner.fullNameString(separator) + separator + simpleName + if (owner.isRoot || owner.isEmptyPackageClass) simpleName.toString + else owner.enclClass.fullNameString(separator) + separator + simpleName if (str.charAt(str.length - 1) == ' ') str = str.substring(0, str.length - 1) str } @@ -953,6 +982,10 @@ trait Symbols requires SymbolTable { this } + override def outerSource: Symbol = + if (name endsWith nme.OUTER) initialize.referenced + else NoSymbol + override def moduleClass: Symbol = if (hasFlag(MODULE)) referenced else NoSymbol diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 36d9b6b08c..a1787b8c3c 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -916,7 +916,7 @@ trait Types requires SymbolTable { packagePrefix + str else if (sym.isModuleClass) objectPrefix + str - else if (sym.isAnonymousClass && sym.isInitialized) + else if (sym.isAnonymousClass && sym.isInitialized && !settings.debug.value) sym.info.parents.mkString("", " with ", "{ ... }") else if (sym.isRefinementClass && sym.isInitialized) sym.info.toString() @@ -1719,7 +1719,9 @@ trait Types requires SymbolTable { (tparams.head.isContravariant || (tps1.head <:< tps2.head)) && isSubArgs(tps1.tail, tps2.tail, tparams.tail) ); - (sym1 == sym2 && (pre1 <:< pre2) && isSubArgs(args1, args2, sym1.typeParams) + (sym1 == sym2 && + (phase.erasedTypes || pre1 <:< pre2) && + isSubArgs(args1, args2, sym1.typeParams) || sym1.isAbstractType && !(tp1 =:= tp1.bounds.hi) && (tp1.bounds.hi <:< tp2) || diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 64030f0c45..2ca9c99296 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -45,10 +45,13 @@ abstract class Constructors extends Transform { assert(constr != null && constrBody != null, impl) val paramAccessors = clazz.constrParamAccessors - def parameter(acc: Symbol) = { - val accname = nme.getterName(acc.originalName) - val ps = constrParams.filter { param => accname == param.name } - if (ps.isEmpty) assert(false, "" + accname + " not in " + constrParams) + + def parameter(acc: Symbol): Symbol = + parameterNamed(nme.getterName(acc.originalName)) + + def parameterNamed(name: Name): Symbol = { + val ps = constrParams.filter(param => param.name == name) + if (ps.isEmpty) assert(false, "" + name + " not in " + constrParams) ps.head } @@ -56,9 +59,13 @@ abstract class Constructors extends Transform { val intoConstructorTransformer = new Transformer { override def transform(tree: Tree): Tree = tree match { - case Apply(Select(This(_), _), List()) - if ((tree.symbol hasFlag PARAMACCESSOR) && tree.symbol.owner == clazz) => - gen.mkAttributedIdent(parameter(tree.symbol.accessed)) setPos tree.pos + case Apply(Select(This(_), _), List()) => + if ((tree.symbol hasFlag PARAMACCESSOR) && tree.symbol.owner == clazz) + gen.mkAttributedIdent(parameter(tree.symbol.accessed)) setPos tree.pos + else if (tree.symbol.outerSource == clazz && !clazz.isImplClass) + gen.mkAttributedIdent(parameterNamed(nme.OUTER)) + else + super.transform(tree) case Select(This(_), _) if ((tree.symbol hasFlag PARAMACCESSOR) && tree.symbol.owner == clazz) => gen.mkAttributedIdent(parameter(tree.symbol)) setPos tree.pos diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index f02d662149..f99daa5cc8 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -602,7 +602,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { if (fn.symbol == Any_asInstanceOf || fn.symbol == Any_asInstanceOfErased) fn match { case TypeApply(Select(qual, _), List(targ)) => - if (qual.tpe <:< targ.tpe) Typed(qual, TypeTree(qual.tpe)) + if (qual.tpe <:< targ.tpe) atPos(tree.pos) { Typed(qual, TypeTree(qual.tpe)) } else tree } // todo: get rid of instanceOfErased @@ -613,7 +613,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { targ.tpe match { case SingleType(pre, sym) => val cmpOp = if (targ.tpe <:< AnyValClass.tpe) Any_equals else Object_eq - Apply(Select(qual, cmpOp), List(gen.mkAttributedQualifier(targ.tpe))) + atPos(tree.pos) { + Apply(Select(qual, cmpOp), List(gen.mkAttributedQualifier(targ.tpe))) + } case _ => tree } diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 762572b7af..d85e491739 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -10,65 +10,92 @@ import symtab._ import Flags._ import scala.collection.mutable.{HashMap, ListBuffer} import matching.{TransMatcher, PatternNodes, CodeFactory, PatternMatchers} -abstract class ExplicitOuter extends InfoTransform -with TransMatcher -with PatternNodes -with CodeFactory -with PatternMatchers { + +abstract class ExplicitOuter extends InfoTransform with TransMatcher with PatternNodes with CodeFactory with PatternMatchers with TypingTransformers { import global._ import definitions._ import posAssigner.atPos + /** The following flags may be set by this phase: */ override def phaseNewFlags: long = notPRIVATE | notPROTECTED - /** the following two members override abstract members in Transform */ + /** the name of the phase: */ val phaseName: String = "explicitouter" + + /** This class does not change linearization */ override def changesBaseClasses = false 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) + /** Is given `clazz' an inner class? */ + private def isInner(clazz: Symbol) = + !clazz.isPackageClass && !clazz.outerClass.isStaticOwner + + private def outerField(clazz: Symbol): Symbol = { + val result = clazz.info.member(nme.getterToLocal(nme.OUTER)) + if (result == NoSymbol) assert(false, "no outer field in "+clazz+clazz.info.decls+" at "+phase) + result + } - private def isStatic(clazz: Symbol) = - clazz.isPackageClass || outerClass(clazz).isStaticOwner + private def outerAccessor(clazz: Symbol): Symbol = { + val firstTry = clazz.info.decl(clazz.expandedName(nme.OUTER)) + if (firstTry != NoSymbol && firstTry.outerSource == clazz) firstTry + else { + var e = clazz.info.decls.elems; + while (e != null && e.sym.outerSource != clazz) e = e.next + if (e != null) e.sym else NoSymbol + } + } /** The type transformation method: - * 1. Add an outer paramter to the formal parameters of a constructor or mixin constructor - * in a non-static class; - * 2. Add a mixin constructor $init$ to all mixins except interfaces - * Leave all other types unchanged. + * 1. Add an outer parameter to the formal parameters of a constructor + * in a inner non-trait class; + * 2. Add a protected $outer field to an inner class which is not a trait. + * 3. Add an outer accessor $outer$$C to every inner class with fully qualified name C + * that is not an interface. The outer accesssor is abstract for traits, concrete + * for other classes. + * 3a. Also add overriding accessor defs to every class that inherits mixin classes + * with outer accessor defs (unless the superclass already inherits the same mixin). + * 4. Add a mixin constructor $init$ to all mixins except interfaces + * Leave all other types unchanged. todo: move to later + * 5. Make all super accessors and modules in traits non-private, mangling their names. + * 6. Remove protected flag from all members of traits. */ def transformInfo(sym: Symbol, tp: Type): Type = tp match { case MethodType(formals, restpe) => - if (sym.owner.isTrait && ((sym hasFlag SUPERACCESSOR) || sym.isModule)) - sym.makeNotPrivate(sym.owner); - if (sym.owner.isTrait && (sym hasFlag PROTECTED)) sym setFlag notPROTECTED - if (sym.isConstructor && !isStatic(sym.owner)) { - // Move outer paramater to first position - MethodType(outerClass(sym.owner).toInterface.thisType :: formals, restpe) - //MethodType(formals ::: List(outerClass(sym.owner).toInterface.thisType), restpe) - } + if (sym.owner.isTrait && ((sym hasFlag SUPERACCESSOR) || sym.isModule)) // 5 + sym.makeNotPrivate(sym.owner) + if (sym.owner.isTrait && (sym hasFlag PROTECTED)) sym setFlag notPROTECTED // 6 + if (sym.isClassConstructor && isInner(sym.owner)) // 1 + MethodType(sym.owner.outerClass.thisType :: formals, restpe) else tp case ClassInfoType(parents, decls, clazz) => var decls1 = decls if (!(clazz hasFlag INTERFACE)) { - if (!isStatic(clazz)) { - decls1 = newScope(decls1.toList) - val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER) - if (clazz.isTrait || (decls.toList exists (.isClass))) - outerAcc.expandName(clazz); + if (isInner(clazz)) { + if (decls1 eq decls) decls1 = newScope(decls1.toList) + val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER) // 3 + outerAcc.expandName(clazz) decls1 enter ( - outerAcc setFlag (PARAMACCESSOR | ACCESSOR | STABLE) - setInfo MethodType(List(), outerClass(clazz).thisType)); - decls1 enter (clazz.newValue(clazz.pos, nme.getterToLocal(outerAcc.name)) - setFlag (LOCAL | PRIVATE | PARAMACCESSOR | (outerAcc getFlag EXPANDEDNAME)) - setInfo outerClass(clazz).thisType) + clazz.newOuterAccessor(clazz.pos) + setInfo MethodType(List(), clazz.outerClass.thisType)) + if (!parents.isEmpty) { + for (val mc <- clazz.mixinClasses) { + val mixinOuterAcc: Symbol = atPhase(phase.next)(outerAccessor(mc)) + if (mixinOuterAcc != NoSymbol) + decls1 enter (mixinOuterAcc.cloneSymbol(clazz) resetFlag DEFERRED) + } + } + if (!clazz.isTrait) // 2 + //todo: avoid outer field if superclass has same outer value? + decls1 enter ( + clazz.newValue(clazz.pos, nme.getterToLocal(nme.OUTER)) + setFlag (PROTECTED | PARAMACCESSOR) + setInfo clazz.outerClass.thisType) } - if (clazz.isTrait) { - decls1 = newScope(decls1.toList) + if (clazz.isTrait) { // 4 (todo: can go into next phase?) + if (decls1 eq decls) decls1 = newScope(decls1.toList) decls1 enter makeMixinConstructor(clazz) } } @@ -80,16 +107,6 @@ with PatternMatchers { tp } - private def outerMember(tp: Type): Symbol = { - var e = tp.symbol.info.decls.elems - // note: tp.decls does not work here, because tp might be a ThisType, in which case - // its decls would be the decls of the required type of the class. - while (e != null && !(e.sym.originalName.startsWith(nme.OUTER) && (e.sym hasFlag ACCESSOR))) - e = e.next; - assert(e != null, tp) - e.sym - } - private def makeMixinConstructor(clazz: Symbol): Symbol = clazz.newMethod(clazz.pos, nme.MIXIN_CONSTRUCTOR) setInfo MethodType(List(), UnitClass.tpe) @@ -97,348 +114,291 @@ with PatternMatchers { * outer parameters of constructors. * The class provides methods for referencing via outer. */ - class OuterPathTransformer extends Transformer { + abstract class OuterPathTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { /** The directly enclosing outer parameter, if we are in a constructor */ protected var outerParam: Symbol = NoSymbol - /** The first outer selection from currently transformed tree + /** The first outer selection from currently transformed tree. + * The result is typed but not positioned. */ protected def outerValue: Tree = if (outerParam != NoSymbol) gen.mkAttributedIdent(outerParam) - else outerSelect(gen.mkAttributedThis(currentOwner.enclClass)) - - /** The path - * `base'.$outer ... .$outer - * which refers to the outer instance 'to' of value 'base' - */ - protected def outerPath(base: Tree, to: Symbol): Tree = - if (base.tpe.symbol == to) base else outerPath(outerSelect(base), to) + else outerSelect(gen.mkAttributedThis(currentClass)) /** Select and apply outer accessor from 'base' + * The result is typed but not positioned. */ private def outerSelect(base: Tree): Tree = { - val otp = outerClass(base.tpe.symbol).thisType - Apply( - Select(base, outerMember(base.tpe)) setType MethodType(List(), otp), - List()) setType otp + localTyper.typed(Apply(Select(base, outerAccessor(base.tpe.symbol)), List())) + } + + /** The path + * `base'.$outer$$C1 ... .$outer$$Cn + * which refers to the outer instance of class 'to' of value 'base' + * The result is typed but not positioned. + */ + protected def outerPath(base: Tree, from: Symbol, to: Symbol): Tree = { + //Console.println("outerPath from "+from+" to "+to+" at "+base+":"+base.tpe) + assert(base.tpe.baseType(from.toInterface) != NoType, base.tpe) + if (from == to || from.isImplClass && from.toInterface == to) base + else outerPath(outerSelect(base), from.outerClass, to) } override def transform(tree: Tree): Tree = { - try {//debug - val savedOuterParam = outerParam; + val savedOuterParam = outerParam; + try { tree match { case Template(_, _) => outerParam = NoSymbol case DefDef(_, _, _, vparamss, _, _) => - if (tree.symbol.isConstructor && !(isStatic(tree.symbol.owner))) { - // moved outer param to first position - val firstParam = vparamss.head.head -// val lastParam = vparamss.head.last - assert(firstParam.name.startsWith(nme.OUTER), tree) - outerParam = firstParam.symbol + if (tree.symbol.isClassConstructor && isInner(tree.symbol.owner)) { + outerParam = vparamss.head.head.symbol + assert(outerParam.name == nme.OUTER) } case _ => } - val result = super.transform(tree); - outerParam = savedOuterParam - result + super.transform(tree) } catch {//debug case ex: Throwable => System.out.println("exception when transforming " + tree) throw ex + } finally { + outerParam = savedOuterParam } } } - class ExplicitOuterTransformer(unit: CompilationUnit) extends Transformer { - - /** The first step performs the following transformations: - * 1. A class which is not an interface and is not static gets an outer link - * (@see outerDefs) - * 2. A mixin which is not also an interface gets a mixin constructor - * (@see mixinConstructorDef) - * 3. Constructor bodies are augmented by calls to supermixin constructors - * (@see addMixinConstructorCalls) - * 4. A constructor of a class with an outer link gets an outer parameter. - * 5. A reference C.this where C refers to an outer class is replaced by a selection - * this.$outer ... .$outer (@see outerPath) - * 7. A call to a constructor Q.<init>(args) or Q.$init$(args) where Q != this and - * the constructor belongs to a non-static class is augmented by an outer argument. - * E.g. Q.<init>(args, OUTER) where OUTER is the qualifier corresponding to the - * singleton type Q. - * 8. A call to a constructor this.<init>(args) in a secondary constructor - * is augmented to this.<init>(args, OUTER) where OUTER is the last parameter - * of the secondary constructor. + /** The phase performs the following transformations on terms: + * 1. An class which is not an interface and is not static gets an outer accessor + * (@see outerDefs) + * 1a. A class which is not a trait gets an outer field. + * 2. A mixin which is not also an interface gets a mixin constructor + * (@see mixinConstructorDef) + * 3. Constructor bodies are augmented by calls to supermixin constructors + * (@see addMixinConstructorCalls) + * 4. A constructor of a non-trait inner class gets an outer parameter. + * 5. A reference C.this where C refers to an outer class is replaced by a selection + * this.$outer$$C1 ... .$outer$$Cn (@see outerPath) + * 7. A call to a constructor Q.<init>(args) or Q.$init$(args) where Q != this and + * the constructor belongs to a non-static class is augmented by an outer argument. + * E.g. Q.<init>(OUTER, args) where OUTER is the qualifier corresponding to the + * singleton type Q. + * 8. A call to a constructor this.<init>(args) in a secondary constructor + * is augmented to this.<init>(OUTER, args) where OUTER is the last parameter + * of the secondary constructor. + * 9. Remove `private' modifier from class members M that are accessed from an inner class. + * 10.Remove `protected' modifier from class members M that are accessed + * without a super qualifier accessed from an inner class or trait. + * 11. Remove `private' and `protected' modifiers from type symbols + * 12. Remove `private' modifiers from members of traits + * Note: The whole transform is run in phase explicitOuter.next + */ + class ExplicitOuterTransformer(unit: CompilationUnit) extends OuterPathTransformer(unit) { + + /** The definition tree of the outer accessor of current class */ - private val firstTransformer = new OuterPathTransformer { - - var localTyper: analyzer.Typer = typer - - /** The two definitions - * val outer: C.this.type _; - * def outer(): C.this.type = outer ; - * Here, C is the class enclosing the class `clazz' containing the two definitions. - */ - def outerDefs(clazz: Symbol): List[Tree] = { - val outerDef = outerMember(clazz.info) - val outerVal = outerDef.accessed - List( - localTyper.typed { - atPos(clazz.pos) { - ValDef(outerVal) - } - }, - localTyper.typed { - atPos(clazz.pos) { - DefDef(outerDef, vparamss => Select(This(clazz), outerVal)) - } - }) + def outerFieldDef: Tree = { + val outerF = outerField(currentClass) + ValDef(outerF, EmptyTree) + } + + /** The definition tree of the outer accessor of current class + */ + def outerAccessorDef: Tree = { + val outerAcc = outerAccessor(currentClass) + var rhs = if (outerAcc hasFlag DEFERRED) EmptyTree + else Select(This(currentClass), outerField(currentClass)) + localTyper.typed { + atPos(currentClass.pos) { + DefDef(outerAcc, vparamss => rhs) + } } + } - /** The mixin constructor definition - * def $init$(): Unit = () - */ - def mixinConstructorDef(clazz: Symbol): Tree = - localTyper.typed { - val constr = clazz.primaryConstructor - atPhase(currentRun.explicitOuterPhase) { - // necessary so that we do not include an outer parameter already here; - // this will be added later in transform. - DefDef(constr, vparamss => Literal(())) - } + /** The definition tree of the outer accessor for class `mixinClass' + * @param mixinClass The mixin class which defines the abstract outer accessor which is + * implemented by the generated one. + * @pre mixinClass is an inner class + */ + def mixinOuterAccessorDef(mixinClass: Symbol): Tree = { + val outerAcc = outerAccessor(mixinClass).overridingSymbol(currentClass) + if (outerAcc == NoSymbol) Console.println("cc "+currentClass+":"+currentClass.info.decls)//debug + assert(outerAcc != NoSymbol) + val path = gen.mkAttributedQualifier(currentClass.thisType.baseType(mixinClass).prefix) + val rhs = ExplicitOuterTransformer.this.transform(path) + localTyper.typed { + atPos(currentClass.pos) { + DefDef(outerAcc, vparamss => rhs) } + } + } - /** Add calls to supermixin constructors - * super[mix].$init$() - * to `tree'. `tree' which is assumed to be the body of a constructor of class `clazz'. - */ - def addMixinConstructorCalls(tree: Tree, clazz: Symbol): Tree = { - def mixinConstructorCall(mixinClass: Symbol): Tree = - atPos(tree.pos) { - Apply( - localTyper.typedOperator { - Select(This(clazz), mixinClass.primaryConstructor) - }, - List()) setType UnitClass.tpe; // don't type this with typed(...), - // as constructor arguments might be missing - } - /* - val mixinConstructorCalls = - for (val mixinClass <- clazz.info.parents.tail; - !(mixinClass.symbol hasFlag INTERFACE) && mixinClass.symbol != ScalaObjectClass) yield - mixinConstructorCall(mixinClass.symbol); - tree match { - */ - val mixinConstructorCalls: List[Tree] = { - val ps = clazz.info.parents - if (ps.isEmpty) List() - else { - val superClass = ps.head.symbol - for { - val mclazz <- clazz.info.baseClasses.tail.takeWhile(superClass ne).reverse - mclazz.needsImplClass && mclazz != ScalaObjectClass - } yield mixinConstructorCall(mclazz) - } + /** The mixin constructor definition + * def $init$(): Unit = () + */ + def mixinConstructorDef(clazz: Symbol): Tree = + localTyper.typed { + val constr = clazz.primaryConstructor + atPhase(currentRun.explicitOuterPhase) { + // necessary so that we do not include an outer parameter already here + // this will be added later in transform. + DefDef(constr, vparamss => Block(List(), Literal(()))) } + } - //val result = - tree match { - case Block(supercall :: stats, expr) => - assert(supercall match { - case Apply(Select(Super(_, _), _), _) => true - case _ => false - }) - copy.Block(tree, supercall :: mixinConstructorCalls ::: stats, expr) - case Block(_, _) => - assert(false, tree); tree + /** Add calls to supermixin constructors + * super[mix].$init$() + * to `tree'. `tree' which is assumed to be the body of a constructor of class `clazz'. + */ + def addMixinConstructorCalls(tree: Tree, clazz: Symbol): Tree = { + def mixinConstructorCall(mixinClass: Symbol): Tree = + atPos(tree.pos) { + Apply( + localTyper.typedOperator { + Select(This(clazz), mixinClass.primaryConstructor) + }, + List()) setType UnitClass.tpe; // don't type this with typed(...), + // as constructor arguments might be missing } - //System.out.println("new constructor of "+clazz+": "+result); - //result + val mixinConstructorCalls: List[Tree] = { + for (val mc <- clazz.mixinClasses.reverse; mc.needsImplClass && mc != ScalaObjectClass) + yield mixinConstructorCall(mc) } - /** The first-step transformation method */ - override def transform(tree: Tree): Tree = { - val sym = tree.symbol - val tree1 = tree match { - case Template(parents, decls) => - val savedLocalTyper = localTyper - localTyper = localTyper.atOwner(tree, currentOwner) - var decls1 = decls - if (!(currentOwner hasFlag INTERFACE) || (currentOwner hasFlag lateINTERFACE)) { - if (!isStatic(currentOwner)) - decls1 = decls1 ::: outerDefs(currentOwner); // (1) - if (currentOwner.isTrait) - decls1 = decls1 ::: List(mixinConstructorDef(currentOwner)) // (2) + //begin mixin constructor calls + tree match { + case Block(supercall :: stats, expr) => + assert(supercall match { + case Apply(Select(Super(_, _), _), _) => true + case _ => false + }) + copy.Block(tree, supercall :: mixinConstructorCalls ::: stats, expr) + case Block(_, _) => + assert(false, tree); tree + } + } + + /** The main transformation method */ + override def transform(tree: Tree): Tree = { + val sym = tree.symbol + if (sym != null && sym.isType) {//(9) + if (sym hasFlag PRIVATE) sym setFlag notPRIVATE + if (sym hasFlag PROTECTED) sym setFlag notPROTECTED + } + tree match { + case Template(parents, decls) => + val newDefs = new ListBuffer[Tree] + atOwner(tree, currentOwner) { + if (!(currentClass hasFlag INTERFACE) || (currentClass hasFlag lateINTERFACE)) { + if (isInner(currentClass)) { + if (!currentClass.isTrait) newDefs += outerFieldDef // (1a) + newDefs += outerAccessorDef // (1) + } + if (currentClass.isTrait) + newDefs += mixinConstructorDef(currentClass) + else + for (val mc <- currentClass.mixinClasses) + if (outerAccessor(mc) != NoSymbol) + newDefs += mixinOuterAccessorDef(mc) } - localTyper = savedLocalTyper - copy.Template(tree, parents, decls1) - case constrDef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) - if (sym.isConstructor) => + } + super.transform( + copy.Template(tree, parents, if (newDefs.isEmpty) decls else decls ::: newDefs.toList)) + + case DefDef(mods, name, tparams, vparamss, tpt, rhs) => + if (sym.isClassConstructor) { rhs match { case Literal(_) => - val rhs1 = Block(List(), rhs) setPos rhs.pos setType rhs.tpe; + // replace unit rhs () by empty block {()} + val rhs1 = Block(List(), rhs) setPos rhs.pos setType rhs.tpe transform(copy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs1)) case _ => - val clazz = sym.owner.toInterface + val clazz = sym.owner val vparamss1 = - if (isStatic(clazz)) vparamss - else { // (4) - val outerField = outerMember(clazz.info).accessed; - val outerParam = sym.newValueParameter(sym.pos, nme.OUTER) setInfo outerField.info; - // moved outer param to first position - List((ValDef(outerParam) setType NoType) :: vparamss.head) -// List(vparamss.head ::: List(ValDef(outerParam) setType NoType)) - } + if (isInner(clazz)) { // (4) + val outerParam = sym.newValueParameter(sym.pos, nme.OUTER) setInfo outerField(clazz).info + ((ValDef(outerParam) setType NoType) :: vparamss.head) :: vparamss.tail + } else vparamss + // todo: move val rhs1 = if (sym.isPrimaryConstructor && sym.isClassConstructor && clazz != ArrayClass) addMixinConstructorCalls(rhs, clazz); // (3) - else rhs; - copy.DefDef(tree, mods, name, tparams, vparamss1, tpt, rhs1) - } - case This(qual) => - 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) && !isStatic(sel.symbol.owner)) => - val outerVal = atPos(tree.pos) { - if (name == nme.MIXIN_CONSTRUCTOR) { - val mclazz = sym.owner.toInterface - //System.out.println("adding mixin constructor for " + currentOwner.enclClass + " " + mclazz + " " + currentOwner.enclClass.thisType.baseType(mclazz));//DEBUG - var pre = currentOwner.enclClass.thisType.baseType(mclazz).prefix - if (pre == NoPrefix) pre = outerClass(mclazz).thisType - gen.mkAttributedQualifier(pre) - } else if (qual.isInstanceOf[This]) { - assert(outerParam != NoSymbol); outerValue - } else { - var pre = qual.tpe.prefix - if (pre == NoPrefix) pre = outerClass(sym.owner).thisType; - gen.mkAttributedQualifier(pre) - } + else rhs + super.transform(copy.DefDef(tree, mods, name, tparams, vparamss1, tpt, rhs1)) } - // moved outer parameter to first position - copy.Apply(tree, sel, outerVal :: args) -// copy.Apply(tree, sel, args ::: List(outerVal)) - - case _ => - tree - } - super.transform(tree1) - } - } + } else { //todo: see whether we can move this to transformInfo + if (sym.owner.isTrait && (sym hasFlag (ACCESSOR | SUPERACCESSOR))) + sym.makeNotPrivate(sym.owner); //(2) + super.transform(tree) + } - /** The second step performs the following transformations: - * 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 or trait. - * 5. Remove `private' and `protected' modifiers from type symbols - */ - private val secondTransformer = new OuterPathTransformer { + case This(qual) => + if (sym == currentClass || (sym hasFlag MODULE) && sym.isStatic) tree + else atPos(tree.pos)(outerPath(outerValue, currentClass.outerClass, sym)) // (5) - def handleSelect(tree:Select) = tree match { case Select(qual, name) => - val sym = tree.symbol - val enclClass = currentOwner.enclClass - if (enclClass != sym.owner && enclClass != sym.moduleClass) // (3) - sym.makeNotPrivate(sym.owner); + if (currentClass != sym.owner && currentClass != sym.moduleClass) // (3) + sym.makeNotPrivate(sym.owner) val qsym = qual.tpe.widen.symbol if ((sym hasFlag PROTECTED) && //(4) - (qsym.isTrait || !(qual.isInstanceOf[Super] || (qsym isSubClass enclClass)))) - sym setFlag notPROTECTED; - } - - /** The second-step transformation method */ - override def transform(tree: Tree): Tree = { - val sym = tree.symbol - val tree1 = - if(tree.isInstanceOf[Match]) { - //Console.println("calling super.transform of Match with ncases "+ - // tree.asInstanceOf[Match].cases.length) - tree - } else { - super.transform(tree) - } - tree1 match { - case DefDef(_, _, _, _, _, _) => - if (sym.owner.isTrait && (sym hasFlag (ACCESSOR | SUPERACCESSOR))) - sym.makeNotPrivate(sym.owner); //(2) - tree1 - case tree @ Select(qual, name) => - handleSelect(tree) - tree1 + (qsym.isTrait || !(qual.isInstanceOf[Super] || (qsym isSubClass currentClass)))) + sym setFlag notPROTECTED + super.transform(tree) - case Match(selector, cases) => // <----- transmatch hook - val tid = cunit.fresh.newName("tidmark") + case Apply(sel @ Select(qual, name), args) + if (name == nme.CONSTRUCTOR && isInner(sel.symbol.owner)) => + val outerVal = atPos(tree.pos) { + if (qual.isInstanceOf[This]) { // it's a call between constructors of same class + assert(outerParam != NoSymbol) + outerValue + } else { + var pre = qual.tpe.prefix + if (pre == NoPrefix) pre = sym.owner.outerClass.thisType + gen.mkAttributedQualifier(pre) + } + } + super.transform(copy.Apply(tree, sel, outerVal :: args)) + case Match(selector, cases) => // <----- transmatch hook + val tid = unit.fresh.newName("tidmark") if(settings.debug.value) Console.println("transforming patmat with tidmark "+tid+" ncases = "+cases.length) - if((cases.length > 1)&&( treeInfo.isDefaultCase(cases(0)))) - assert(false,"transforming too much, "+tid) - val nselector = transform(selector).setType(selector.tpe) - val ncases = cases map { transform } - ExplicitOuter.this.resultType = tree.tpe - //Console.println("TransMatcher currentOwner ="+currentOwner+")") - //Console.println("TransMatcher selector.tpe ="+selector.tpe+")") - //Console.println("TransMatcher resultType ="+resultType+")") - def mytransform(tree: Tree): Tree = { - val sym = tree.symbol - tree match { - case This(qual) => - if (sym == currentOwner.enclClass || (sym hasFlag Flags.MODULE) && sym.isStatic) tree - else atPos(tree.pos)(outerPath(outerValue, sym)); // (5) - case Select(qual,name) => - val s = copy.Select(tree, mytransform(qual), name) - handleSelect(s) - s - case x => - if(settings.debug.value) - Console.println(x.getClass()) - x - } - } - val t_untyped = ExplicitOuter.this.handlePattern(nselector, ncases.asInstanceOf[List[CaseDef]], currentOwner, mytransform) + if((cases.length > 1)&&( treeInfo.isDefaultCase(cases(0)))) + assert(false,"transforming too much, "+tid) + val nselector = transform(selector) + assert(nselector.tpe =:= selector.tpe) + val ncases = transformCaseDefs(cases) - //Console.println("t_untyped "+t_untyped.toString()) - val t = atPos(tree.pos) { typer.atOwner(tree,currentOwner).typed(t_untyped, resultType) } + ExplicitOuter.this.resultType = tree.tpe + //Console.println("TransMatcher currentOwner ="+currentOwner+")") + //Console.println("TransMatcher selector.tpe ="+selector.tpe+")") + //Console.println("TransMatcher resultType ="+resultType+")") + + val t_untyped = handlePattern(nselector, ncases, currentOwner, transform) + //Console.println("t_untyped "+t_untyped.toString()) + val t = atPos(tree.pos) { localTyper.typed(t_untyped, resultType) } //t = transform(t) - //val t = atPos(tree.pos) { typed(t_untyped, resultType) } - //val t = atPos(tree.pos) { typed(t_untyped) } - //Console.println("t typed "+t.toString()) + //val t = atPos(tree.pos) { typed(t_untyped, resultType) } + //val t = atPos(tree.pos) { typed(t_untyped) } + //Console.println("t typed "+t.toString()) if(settings.debug.value) Console.println("finished translation of "+tid) - t -/*<--- end transmatch experimental */ + t - case _ => - if (sym != null && sym.isType) {//(5) - if (sym hasFlag PRIVATE) sym setFlag notPRIVATE - if (sym hasFlag PROTECTED) sym setFlag notPROTECTED - } - tree1 - } + case _ => + super.transform(tree) } } - // needed in TransMatcher - override def transformUnit(unit: CompilationUnit) = { + /** The transformation method for whole compilation units */ + override def transformUnit(unit: CompilationUnit): unit = { cunit = unit - super.transformUnit(unit) - cunit = null + atPhase(phase.next) { super.transformUnit(unit) } } - - - /** The main transformation method: - * First, perform step 1 on whole tree of compilation unit. - * Then, perform step 2 on resulting tree - */ - override def transform(tree: Tree) = - atPhase(phase.next) { - secondTransformer.transform(firstTransformer.transform(tree)) - } } } diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 1b9bf64dfd..d259a1468a 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -41,7 +41,7 @@ abstract class LambdaLift extends InfoTransform { protected def newTransformer(unit: CompilationUnit): Transformer = new LambdaLifter(unit) - class LambdaLifter(unit: CompilationUnit) extends explicitOuter.OuterPathTransformer { + class LambdaLifter(unit: CompilationUnit) extends explicitOuter.OuterPathTransformer(unit) { /** A map storing free variables of functions and classes */ private val free = new HashMap[Symbol, SymSet] @@ -286,11 +286,12 @@ abstract class LambdaLift extends InfoTransform { private def memberRef(sym: Symbol) = { val clazz = sym.owner.enclClass - val qual = if (clazz == currentOwner.enclClass) gen.mkAttributedThis(clazz) + //Console.println("memberRef from "+currentClass+" to "+sym+" in "+clazz) + val qual = if (clazz == currentClass) gen.mkAttributedThis(clazz) else { sym resetFlag(LOCAL | PRIVATE) if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType) - else outerPath(outerValue, clazz) + else outerPath(outerValue, currentClass.outerClass, clazz) } Select(qual, sym) setType sym.tpe } @@ -360,7 +361,7 @@ abstract class LambdaLift extends InfoTransform { case Return(Block(stats, value)) => Block(stats, copy.Return(tree, value)) setType tree.tpe setPos tree.pos case Return(expr) => - assert(sym == currentOwner.enclMethod, sym) + assert(sym == currentMethod, sym) tree case Apply(fn, args) => copy.Apply(tree, fn, addFreeArgs(tree.pos, sym, args)) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 167f4959e3..98ee4c001d 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -392,7 +392,7 @@ abstract class Mixin extends InfoTransform { /** Attribute given tree and anchor at given position */ def attributedDef(pos: PositionType, tree: Tree): Tree = { - if (settings.debug.value) System.out.println("add new def to " + clazz + ": " + tree); + if (settings.debug.value) log("add new def to " + clazz + ": " + tree); localTyper.typed { atPos(pos) { tree } } } diff --git a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala index 1e345a930a..c4de6f6fab 100644 --- a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala +++ b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala @@ -15,12 +15,15 @@ trait TypingTransformers { import global._ abstract class TypingTransformer(unit: CompilationUnit) extends Transformer { - var localTyper: analyzer.Typer = analyzer.newTyper(analyzer.rootContext(unit)) + var localTyper: analyzer.Typer = analyzer.newTyper( + analyzer.rootContext(unit, EmptyTree, true)) private var curTree: Tree = _ - override def atOwner[A](owner: Symbol)(trans: => A): A = { + override def atOwner[A](owner: Symbol)(trans: => A): A = atOwner(curTree, owner)(trans) + + def atOwner[A](tree: Tree, owner: Symbol)(trans: => A): A = { val savedLocalTyper = localTyper - localTyper = localTyper.atOwner(curTree, owner) + localTyper = localTyper.atOwner(tree, owner) val result = super.atOwner(owner)(trans) localTyper = savedLocalTyper result diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index f198881d7e..0e032321e0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -22,17 +22,6 @@ abstract class TreeCheckers extends Analyzer { } def check(unit: CompilationUnit): unit = { - val areporter = reporter match { - case ar: AbstractReporter => ar - case _ => null - } - - val curPrompt = if (areporter != null) { - val ret = areporter.prompt - areporter.prompt = true - ret - } else false - val context = rootContext(unit) context.checking = true tpeOfTree.clear @@ -46,9 +35,6 @@ abstract class TreeCheckers extends Analyzer { currentRun.advanceUnit assert(currentRun.currentUnit == unit) currentRun.currentUnit = unit0 - - if (areporter != null) - areporter.prompt = curPrompt } override def newTyper(context: Context): Typer = new TreeChecker(context) @@ -99,7 +85,10 @@ abstract class TreeCheckers extends Analyzer { var o = currentOwner while (o != tree.symbol) { o = o.owner - assert(o != NoSymbol, tree) + if (o == NoSymbol) { + error(tree.pos, "tree symbol "+tree.symbol+" does not point to enclosing class; tree = "+tree) + return + } } } case _ => @@ -129,20 +118,28 @@ abstract class TreeCheckers extends Analyzer { } object postcheck extends Traverser { - override def traverse(tree: Tree): unit = tree match { - case EmptyTree | TypeTree() => - ; - case _ => - tpeOfTree.get(tree) match { - case Some(oldtpe) => - if (!(oldtpe =:= tree.tpe)) - error(tree.pos, "types differ\n old: " + oldtpe + - "\n new: " + tree.tpe + "\n tree: " + tree) - tree.tpe = oldtpe - super.traverse(tree) - case None => + override def traverse(tree: Tree): unit = + try { + tree match { + case EmptyTree | TypeTree() => + ; + case _ => + tpeOfTree.get(tree) match { + case Some(oldtpe) => + if (!(oldtpe =:= tree.tpe)) + error(tree.pos, "types differ\n old: " + oldtpe + + "\n new: " + tree.tpe + "\n tree: " + tree) + tree.tpe = oldtpe + super.traverse(tree) + case None => + } } - } + } catch { + case ex: Throwable => + if (settings.debug.value) + System.out.println("exception when traversing " + tree); + throw(ex) + } } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 64e367bb33..1bfba3fc3c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -24,8 +24,6 @@ trait Typers requires Analyzer { var implcnt = 0 var impltime = 0l - final val xviews = true - private val transformed = new HashMap[Tree, Tree] private val superDefs = new HashMap[Symbol, ListBuffer[Tree]] @@ -631,7 +629,7 @@ trait Typers requires Analyzer { } } - if (!parents.head.tpe.isError) + if (!parents.isEmpty && !parents.head.tpe.isError) for (val p <- parents) validateParentClass(p, parents.head.tpe.symbol) } @@ -665,7 +663,7 @@ trait Typers requires Analyzer { val vdef = copy.ValDef(stat, mods | PRIVATE | LOCAL, nme.getterToLocal(name), tpt, rhs) val value = vdef.symbol val getter = if (mods hasFlag DEFERRED) value else value.getter(value.owner) - assert(getter != NoSymbol, getter);//debug + assert(getter != NoSymbol, stat) val getterDef: DefDef = { val result = DefDef(getter, vparamss => if (mods hasFlag DEFERRED) EmptyTree @@ -714,7 +712,9 @@ trait Typers requires Analyzer { // the following is necessary for templates generated later new Namer(context.outer.make(templ, clazz, clazz.info.decls)).enterSyms(templ.body) validateParentClasses(parents1, selfType); - val body1 = typedStats(templ.body flatMap addGetterSetter, templ.symbol) + val body = if (phase.id <= currentRun.typerPhase.id) templ.body flatMap addGetterSetter + else templ.body + val body1 = typedStats(body, templ.symbol) copy.Template(templ, parents1, body1) setType clazz.tpe } @@ -844,7 +844,7 @@ trait Typers requires Analyzer { case _ => typedSuperCall(ddef.rhs, UnitClass.tpe) } - if (meth.isPrimaryConstructor && !phase.erasedTypes && reporter.errors == 0) + if (meth.isPrimaryConstructor && phase.id <= currentRun.typerPhase.id && reporter.errors == 0) computeParamAliases(meth.owner, vparamss1, result) result } else transformedOrTyped(ddef.rhs, tpt1.tpe) @@ -1086,9 +1086,8 @@ trait Typers requires Analyzer { case _ => tp } if (fun.symbol == List_apply && args.isEmpty) { - gen.mkNil setType restpe - } - else if ((mode & CONSTmode) != 0 && fun.symbol.owner == PredefModule.tpe.symbol && fun.symbol.name == nme.Array) { + atPos(tree.pos) { gen.mkNil setType restpe } + } else if ((mode & CONSTmode) != 0 && fun.symbol.owner == PredefModule.tpe.symbol && fun.symbol.name == nme.Array) { val elems = new Array[Constant](args1.length) var i = 0; for (val arg <- args1) arg match { @@ -1665,7 +1664,7 @@ trait Typers requires Analyzer { typedTypeApply(typed(fun, funMode(mode) | TAPPmode, WildcardType), args1) case Apply(Block(stats, expr), args) => - typed1(Block(stats, Apply(expr, args)), mode, pt) + typed1(atPos(tree.pos)(Block(stats, Apply(expr, args))), mode, pt) case Apply(fun, args) => val stableApplication = fun.symbol != null && fun.symbol.isMethod && fun.symbol.isStable @@ -1680,8 +1679,7 @@ trait Typers requires Analyzer { // number of arguments and expected result type. if (settings.debug.value) log("trans app "+fun1+":"+fun1.symbol+":"+fun1.tpe+" "+args);//DEBUG if (util.Statistics.enabled) appcnt = appcnt + 1 - if (xviews && - phase.id <= currentRun.typerPhase.id && + if (phase.id <= currentRun.typerPhase.id && fun1.isInstanceOf[Select] && !fun1.tpe.isInstanceOf[ImplicitMethodType] && (fun1.symbol == null || !fun1.symbol.isConstructor) && @@ -1708,7 +1706,7 @@ trait Typers requires Analyzer { else { val ps = clazz.info.parents filter (p => p.symbol.name == mix) if (ps.isEmpty) { - if (settings.debug.value) System.out.println(clazz.info.parents map (.symbol.name));//debug + if (settings.debug.value) System.out.println(clazz.info.parents map (.symbol.name));//debug error(tree.pos, ""+mix+" does not name a parent class of "+clazz) ErrorType } else if (ps.tail.isEmpty) { |