@@ -308,11 +308,14 @@ abstract class LambdaLift extends InfoTransform {
308
308
309
309
afterOwnPhase {
310
310
for ((owner, freeValues) <- free.toList) {
311
- val newFlags = SYNTHETIC | ( if (owner.isClass) PARAMACCESSOR | PrivateLocal else PARAM )
312
- debuglog(" free var proxy: %s, %s" .format(owner.fullLocationString, freeValues.toList.mkString(" , " )))
311
+ val newFlags = SYNTHETIC | (
312
+ if (owner.isClass) PARAMACCESSOR | PrivateLocal
313
+ else PARAM )
314
+
313
315
proxies(owner) =
314
316
for (fv <- freeValues.toList) yield {
315
317
val proxyName = proxyNames.getOrElse(fv, fv.name)
318
+ debuglog(s " new proxy ${proxyName} in ${owner.fullLocationString}" )
316
319
val proxy = owner.newValue(proxyName.toTermName, owner.pos, newFlags.toLong) setInfo fv.info
317
320
if (owner.isClass) owner.info.decls enter proxy
318
321
proxy
@@ -342,73 +345,77 @@ abstract class LambdaLift extends InfoTransform {
342
345
343
346
private def memberRef (sym : Symbol ): Tree = {
344
347
val clazz = sym.owner.enclClass
345
- // Console. println("memberRef from "+ currentClass+" to "+ sym+" in "+ clazz)
346
- def prematureSelfReference () {
348
+ // println(s "memberRef from $ currentClass to $ sym in $ clazz (currentClass=$currentClass)" )
349
+ def prematureSelfReference (): Tree = {
347
350
val what =
348
351
if (clazz.isStaticOwner) clazz.fullLocationString
349
352
else s " the unconstructed `this` of ${clazz.fullLocationString}"
350
353
val msg = s " Implementation restriction: access of ${sym.fullLocationString} from ${currentClass.fullLocationString}, would require illegal premature access to $what"
351
354
reporter.error(curTree.pos, msg)
355
+ EmptyTree
352
356
}
353
- val qual =
357
+ def qual =
354
358
if (clazz == currentClass) gen.mkAttributedThis(clazz)
355
359
else {
356
360
sym resetFlag (LOCAL | PRIVATE )
357
- if (isUnderConstruction(clazz)) {
358
- prematureSelfReference()
359
- EmptyTree
360
- }
361
+ if (isUnderConstruction(clazz)) prematureSelfReference()
361
362
else if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType)
362
- else {
363
- outerValue match {
364
- case EmptyTree => prematureSelfReference(); return EmptyTree
365
- case o => outerPath(o, currentClass.outerClass, clazz)
366
- }
363
+ else outerValue match {
364
+ case EmptyTree => prematureSelfReference()
365
+ case o => outerPath(o, currentClass.outerClass, clazz)
367
366
}
368
367
}
369
- Select (qual, sym) setType sym.tpe
368
+
369
+ qual match {
370
+ case EmptyTree => EmptyTree
371
+ case qual => Select (qual, sym) setType sym.tpe
372
+ }
370
373
}
371
374
372
375
private def proxyRef (sym : Symbol ) = {
373
376
val psym = proxy(sym)
374
377
if (psym.isLocalToBlock) gen.mkAttributedIdent(psym) else memberRef(psym)
375
378
}
376
379
377
- private def addFreeArgs (pos : Position , sym : Symbol , args : List [Tree ]) = {
378
- free get sym match {
379
- case Some (fvs) => addFree(sym, free = fvs.toList map (fv => atPos(pos)(proxyRef(fv))), original = args)
380
- case _ => args
380
+ def freeArgsOrNil (sym : Symbol ) = free.getOrElse(sym, Nil ).toList
381
+
382
+ private def freeArgs (sym : Symbol ): List [Symbol ] =
383
+ freeArgsOrNil(sym)
384
+
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)
381
389
}
382
- }
383
390
384
- private def addFreeParams (tree : Tree , sym : Symbol ): Tree = proxies.get(sym) match {
385
- case Some (ps) =>
386
- val freeParams = ps map (p => ValDef (p) setPos tree.pos setType NoType )
387
- tree match {
388
- case DefDef (_, _, _, vparams :: _, _, _) =>
389
- val addParams = cloneSymbols(ps).map(_.setFlag(PARAM ))
390
- sym.updateInfo(
391
- lifted(MethodType (addFree(sym, free = addParams, original = sym.info.params), sym.info.resultType)))
391
+ def proxiesOrNil (sym : Symbol ) = proxies.getOrElse(sym, Nil )
392
+
393
+ private def freeParams (sym : Symbol ): List [Symbol ] =
394
+ proxiesOrNil(sym)
395
+
396
+ private def addFreeParams (tree : Tree , sym : Symbol ): Tree =
397
+ tree match {
398
+ case DefDef (_, _, _, vparams :: _, _, _) =>
399
+ val ps = freeParams(sym)
400
+
401
+ if (ps isEmpty) tree
402
+ else {
403
+ val paramSyms = cloneSymbols(ps).map(_.setFlag(PARAM ))
404
+ val paramDefs = ps map (p => ValDef (p) setPos tree.pos setType NoType )
405
+
406
+ sym.updateInfo(lifted(MethodType (addFree(sym, free = paramSyms, original = sym.info.params), sym.info.resultType)))
407
+ copyDefDef(tree)(vparamss = List (addFree(sym, free = paramDefs, original = vparams)))
408
+ }
409
+
410
+ case ClassDef (_, _, _, _) =>
411
+ val freeParamDefs = freeParams(sym) map (p => ValDef (p) setPos tree.pos setType NoType )
412
+
413
+ if (freeParamDefs isEmpty) tree
414
+ else deriveClassDef(tree)(impl => deriveTemplate(impl)(_ ::: freeParamDefs))
415
+
416
+ case _ => tree
417
+ }
392
418
393
- copyDefDef(tree)(vparamss = List (addFree(sym, free = freeParams, original = vparams)))
394
- case ClassDef (_, _, _, _) =>
395
- // SI-6231
396
- // Disabled attempt to to add getters to freeParams
397
- // this does not work yet. Problem is that local symbols need local names
398
- // and references to local symbols need to be transformed into
399
- // method calls to setters.
400
- // def paramGetter(param: Symbol): Tree = {
401
- // val getter = param.newGetter setFlag TRANS_FLAG resetFlag PARAMACCESSOR // mark because we have to add them to interface
402
- // sym.info.decls.enter(getter)
403
- // val rhs = Select(gen.mkAttributedThis(sym), param) setType param.tpe
404
- // DefDef(getter, rhs) setPos tree.pos setType NoType
405
- // }
406
- // val newDefs = if (sym.isTrait) freeParams ::: (ps map paramGetter) else freeParams
407
- deriveClassDef(tree)(impl => deriveTemplate(impl)(_ ::: freeParams))
408
- }
409
- case None =>
410
- tree
411
- }
412
419
413
420
/* SI-6231: Something like this will be necessary to eliminate the implementation
414
421
* restriction from paramGetter above:
0 commit comments