diff options
author | Martin Odersky <odersky@gmail.com> | 2015-03-11 16:14:35 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-03-11 16:17:19 +0100 |
commit | 72dd9ea1ccbb98ee2dc4bf080772e8d9f13f3d75 (patch) | |
tree | a734f0862ceb8f8a177d45045e47afef7df91f8d /src/dotty/tools/dotc/transform/Constructors.scala | |
parent | 8195baf78b3305710174fca6f0e3ba58e60ca156 (diff) | |
download | dotty-72dd9ea1ccbb98ee2dc4bf080772e8d9f13f3d75.tar.gz dotty-72dd9ea1ccbb98ee2dc4bf080772e8d9f13f3d75.tar.bz2 dotty-72dd9ea1ccbb98ee2dc4bf080772e8d9f13f3d75.zip |
Fixes to class field initialization
Class fields were not initialized from constructor parameters before.
This is now fixed. The fix uncovered some problems with the treatement
of outer parameters which are now also corrected.
Diffstat (limited to 'src/dotty/tools/dotc/transform/Constructors.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/Constructors.scala | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/src/dotty/tools/dotc/transform/Constructors.scala b/src/dotty/tools/dotc/transform/Constructors.scala index 1df4df1e4..d68f20696 100644 --- a/src/dotty/tools/dotc/transform/Constructors.scala +++ b/src/dotty/tools/dotc/transform/Constructors.scala @@ -17,6 +17,7 @@ import Types._ import Decorators._ import DenotTransformers._ import util.Positions._ +import Constants.Constant import collection.mutable /** This transform @@ -64,20 +65,13 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor // Produce aligned accessors and constructor parameters. We have to adjust // for any outer parameters, which are last in the sequence of original - // parameter accessors but should come first in the constructor parameter list. - var accessors = cls.paramAccessors.filterNot(_.isSetter) - var vparamsWithOuter = vparams - if (!accessors.hasSameLengthAs(vparams)) { - accessors.reverse match { - case last :: _ if (last.name == nme.OUTER) => - accessors = last :: accessors.init // align wth calling convention - vparamsWithOuter = ValDef(last.asTerm) :: vparams - case _ => - } - assert(accessors.hasSameLengthAs(vparamsWithOuter), - i"lengths differ for $cls, param accs = $accessors, params = ($vparamsWithOuter%, %)") + // parameter accessors but come first in the constructor parameter list. + val accessors = cls.paramAccessors.filterNot(_.isSetter) + val vparamsWithOuterLast = vparams match { + case vparam :: rest if vparam.name == nme.OUTER => rest ::: vparam :: Nil + case _ => vparams } - val paramSyms = vparamsWithOuter map (_.symbol) + val paramSyms = vparamsWithOuterLast map (_.symbol) // Adjustments performed when moving code into the constructor: // (1) Replace references to param accessors by constructor parameters @@ -179,11 +173,27 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor } splitStats(tree.body) - val accessorFields = accessors.filterNot(_ is Method) - // The initializers for the retained accessors */ - val copyParams = accessorFields.filter(isRetained).map(acc => - Assign(ref(acc), ref(acc.subst(accessors, paramSyms))).withPos(tree.pos)) + val copyParams = accessors flatMap { acc => + if (!isRetained(acc)) Nil + else { + val target = if (acc.is(Method)) acc.field else acc + if (!target.exists) Nil // this case arises when the parameter accessor is an alias + else { + val param = acc.subst(accessors, paramSyms) + val assigns = Assign(ref(target), ref(param)).withPos(tree.pos) :: Nil + if (acc.name != nme.OUTER) assigns + else { + // insert test: if ($outer eq null) throw new NullPointerException + val nullTest = + If(ref(param).select(defn.Object_eq).appliedTo(Literal(Constant(null))), + Throw(New(defn.NullPointerExceptionClass.typeRef, Nil)), + unitLiteral) + nullTest :: assigns + } + } + } + } // Drop accessors that are not retained from class scope val dropped = usage.dropped |