@@ -309,17 +309,22 @@ abstract class LambdaLift extends InfoTransform {
309
309
afterOwnPhase {
310
310
for ((owner, freeValues) <- free.toList) {
311
311
val newFlags = SYNTHETIC | (
312
- if (owner.isClass) PARAMACCESSOR | PrivateLocal
312
+ if (owner.isTrait) PARAMACCESSOR | TRANS_FLAG // will need an impl in subclass that mixes in the trait
313
+ else if (owner.isClass) PARAMACCESSOR | PrivateLocal
313
314
else PARAM )
314
315
315
316
proxies(owner) =
316
317
for (fv <- freeValues.toList) yield {
317
318
val proxyName = proxyNames.getOrElse(fv, fv.name)
318
- debuglog(s " new proxy ${proxyName} in ${owner.fullLocationString}" )
319
- val proxy = owner.newValue(proxyName.toTermName, owner.pos, newFlags.toLong) setInfo fv.info
319
+ println(s " new proxy ${proxyName} in ${owner.fullLocationString}" )
320
+ val proxy =
321
+ if (owner.isTrait) owner.newMethod(proxyName.toTermName, owner.pos, newFlags.toLong) setInfo MethodType (Nil , fv.info)
322
+ else owner.newValue(proxyName.toTermName, owner.pos, newFlags.toLong) setInfo fv.info
320
323
if (owner.isClass) owner.info.decls enter proxy
321
324
proxy
322
325
}
326
+
327
+ proxies(owner.toInterface) = proxies(owner)
323
328
}
324
329
}
325
330
}
@@ -368,7 +373,11 @@ abstract class LambdaLift extends InfoTransform {
368
373
369
374
qual match {
370
375
case EmptyTree => EmptyTree
371
- case qual => Select (qual, sym) setType sym.tpe
376
+ case qual =>
377
+ val sel = Select (qual, sym) setType sym.tpe
378
+
379
+ if (sym.isParamAccessor && (sym hasFlag TRANS_FLAG )) Apply (sel, Nil ) setType sym.tpe.finalResultType
380
+ else sel
372
381
}
373
382
}
374
383
@@ -379,19 +388,43 @@ abstract class LambdaLift extends InfoTransform {
379
388
380
389
def freeArgsOrNil (sym : Symbol ) = free.getOrElse(sym, Nil ).toList
381
390
382
- private def freeArgs (sym : Symbol ): List [Symbol ] =
383
- freeArgsOrNil(sym)
391
+ private def transformApply (tree : Apply ) = {
392
+ val Apply (fn, args) = tree
393
+ val sym = tree.symbol
394
+ val pos = tree.pos
384
395
385
- private def addFreeArgs (pos : Position , sym : Symbol , args : List [Tree ]) =
386
- freeArgs(sym) match {
387
- case Nil => args
388
- case fvs => addFree(sym, free = fvs map (fv => atPos(pos)(proxyRef(fv))), original = args)
396
+ if (sym.isMethod && sym.isConstructor && sym.owner.isTrait) {
397
+ // TODO: add types / symbols
398
+ val inits = freeParams(currentOwner).map { ctorParam =>
399
+ ugh, since we just mutate trees without first transforming infos, we can' t get to the symbol
400
+ val proxyFieldSym = currentClass.info.decl(ctorParam.name)
401
+ val proxyField = gen.mkAttributedSelect(gen.mkAttributedThis(currentClass), proxyFieldSym)
402
+
403
+ atPos(currentOwner.pos)(Assign (proxyField, Ident (ctorParam))) setType BoxedUnitTpe
404
+ }
405
+ Block (inits, tree) setType tree.tpe setPos tree.pos
406
+ } else {
407
+ val newArgs =
408
+ freeArgsOrNil(sym) match {
409
+ case Nil => args
410
+ case fvs => addFree (sym, free = fvs map (fv => atPos (pos) (proxyRef (fv) ) ), original = args)
411
+ }
412
+
413
+ treeCopy.Apply (tree, fn, newArgs)
389
414
}
415
+ }
390
416
391
417
def proxiesOrNil (sym : Symbol ) = proxies.getOrElse(sym, Nil )
392
418
419
+ private def mixinProxies (mixin : Symbol ): List [Symbol ] = {
420
+ proxiesOrNil(mixin) map (mixedin => mixedin.cloneSymbol setFlag TRANS_FLAG )
421
+ }
422
+
393
423
private def freeParams (sym : Symbol ): List [Symbol ] =
394
- proxiesOrNil(sym)
424
+ if (sym.isMethod && sym.isConstructor && sym.owner.isTrait) Nil
425
+ else if (sym.isClass && ! sym.isTrait)
426
+ proxiesOrNil(sym) ++ (sym.mixinClasses flatMap mixinProxies)
427
+ else proxiesOrNil(sym)
395
428
396
429
private def addFreeParams (tree : Tree , sym : Symbol ): Tree =
397
430
tree match {
@@ -407,12 +440,31 @@ abstract class LambdaLift extends InfoTransform {
407
440
copyDefDef(tree)(vparamss = List (addFree(sym, free = paramDefs, original = vparams)))
408
441
}
409
442
410
- case ClassDef (_, _, _, _) =>
443
+ case ClassDef (_, _, _, _) if ! sym.isTrait =>
411
444
val freeParamDefs = freeParams(sym) map (p => ValDef (p) setPos tree.pos setType NoType )
412
445
413
446
if (freeParamDefs isEmpty) tree
414
447
else deriveClassDef(tree)(impl => deriveTemplate(impl)(_ ::: freeParamDefs))
415
448
449
+ case ClassDef (_, _, _, _) =>
450
+ // SI-2897, SI-6231
451
+ // Disabled attempt to to add getters to freeParams
452
+ // this does not work yet. Problem is that local symbols need local names
453
+ // and references to local symbols need to be transformed into
454
+ // method calls to setters.
455
+ // def paramGetter(param: Symbol): Tree = {
456
+ // val getter = param.newGetter setFlag TRANS_FLAG resetFlag PARAMACCESSOR // mark because we have to add them to interface
457
+ // sym.info.decls.enter(getter)
458
+ // val rhs = Select(gen.mkAttributedThis(sym), param) setType param.tpe
459
+ // DefDef(getter, rhs) setPos tree.pos setType NoType
460
+ // }
461
+ val ps = freeParams(sym)
462
+ if (ps isEmpty) tree
463
+ else {
464
+ val freeParams = ps map (p => DefDef (p, EmptyTree ) setPos tree.pos setType NoType )
465
+ deriveClassDef(tree)(impl => deriveTemplate(impl)(_ ::: freeParams))
466
+ }
467
+
416
468
case _ => tree
417
469
}
418
470
@@ -504,8 +556,7 @@ abstract class LambdaLift extends InfoTransform {
504
556
case Return (expr) =>
505
557
assert(sym == currentMethod, sym)
506
558
tree
507
- case Apply (fn, args) =>
508
- treeCopy.Apply (tree, fn, addFreeArgs(tree.pos, sym, args))
559
+ case tree : Apply => transformApply(tree)
509
560
case Assign (Apply (TypeApply (sel @ Select (qual, _), _), List ()), rhs) =>
510
561
// eliminate casts introduced by selecting a captured variable field
511
562
// on the lhs of an assignment.
0 commit comments