summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/Constructors.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-05-30 23:48:28 -0700
committerAdriaan Moors <adriaan@lightbend.com>2016-08-11 10:59:16 -0700
commitb79c0d124e839e9e7ae5db883488c0134642472b (patch)
tree4ffe3199624d964b538f4b31c8d00238f4badbeb /src/compiler/scala/tools/nsc/transform/Constructors.scala
parent8f792280630721bdc1e6ee9199eb0cf8cb035fce (diff)
downloadscala-b79c0d124e839e9e7ae5db883488c0134642472b.tar.gz
scala-b79c0d124e839e9e7ae5db883488c0134642472b.tar.bz2
scala-b79c0d124e839e9e7ae5db883488c0134642472b.zip
LambdaLift emits paramaccessor syms and defdefs
... instead of emitting ValDefs and field symbols, which are then promptly unlinked and transformed by the "late trait methods" logic in mixins... Mixins still synthesizes implementations for these accessors in subclasses. A paramaccessor in a trait is a method without an underlying field.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/Constructors.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index ec8dc68834..0a87e358b4 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -506,7 +506,8 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
)
/*
- * whether `sym` denotes a param-accessor (ie a field) that fulfills all of:
+ * whether `sym` denotes a param-accessor (ie in a class a PARAMACCESSOR field, or in a trait a method with same flag)
+ * that fulfills all of:
* (a) has stationary value, ie the same value provided via the corresponding ctor-arg; and
* (b) isn't subject to specialization. We might be processing statements for:
* (b.1) the constructor in the generic (super-)class; or
@@ -519,10 +520,11 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
case Apply(Select(This(_), _), List()) =>
// references to parameter accessor methods of own class become references to parameters
// outer accessors become references to $outer parameter
- if (clazz.isTrait)
+ // println(s"to param ref in $clazz for ${tree.symbol} ${tree.symbol.debugFlagString} / ${tree.symbol.outerSource} / ${canBeSupplanted(tree.symbol)}")
+ if (clazz.isTrait && !(tree.symbol hasAllFlags (ACCESSOR | PARAMACCESSOR)))
super.transform(tree)
else if (canBeSupplanted(tree.symbol))
- gen.mkAttributedIdent(parameter(tree.symbol.accessed)) setPos tree.pos
+ gen.mkAttributedIdent(parameter(tree.symbol)) setPos tree.pos
else if (tree.symbol.outerSource == clazz)
gen.mkAttributedIdent(parameterNamed(nme.OUTER)) setPos tree.pos
else
@@ -700,7 +702,9 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
def omittableStat(stat: Tree) = omittableSym(stat.symbol)
// The parameter accessor fields which are members of the class
- val paramAccessors = clazz.constrParamAccessors
+ val paramAccessors =
+ if (clazz.isTrait) clazz.info.decls.toList.filter(sym => sym.hasAllFlags(STABLE | PARAMACCESSOR)) // since a trait does not have constructor parameters (yet), these can only come from lambdalift -- right?
+ else clazz.constrParamAccessors
// Initialize all parameters fields that must be kept.
val paramInits = paramAccessors filterNot omittableSym map { acc =>
@@ -708,11 +712,15 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
// It would be better to mangle the constructor parameter name since
// it can only be used internally, but I think we need more robust name
// mangling before we introduce more of it.
- val conflict = clazz.info.nonPrivateMember(acc.name) filter (s => s.isGetter && !s.isOuterField && s.enclClass.isTrait)
+ val conflict = clazz.info.nonPrivateMember(acc.name) filter (s => (s ne acc) && s.isGetter && !s.isOuterField && s.enclClass.isTrait)
if (conflict ne NoSymbol)
reporter.error(acc.pos, "parameter '%s' requires field but conflicts with %s".format(acc.name, conflict.fullLocationString))
- copyParam(acc, parameter(acc))
+ val accSetter =
+ if (clazz.isTrait) acc.setterIn(clazz, hasExpandedName = true)
+ else acc
+
+ copyParam(accSetter, parameter(acc))
}
// Return a pair consisting of (all statements up to and including superclass and trait constr calls, rest)