diff options
Diffstat (limited to 'src/dotty/tools/dotc/transform/ExpandSAMs.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/ExpandSAMs.scala | 86 |
1 files changed, 0 insertions, 86 deletions
diff --git a/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/src/dotty/tools/dotc/transform/ExpandSAMs.scala deleted file mode 100644 index 91399f91a..000000000 --- a/src/dotty/tools/dotc/transform/ExpandSAMs.scala +++ /dev/null @@ -1,86 +0,0 @@ -package dotty.tools.dotc -package transform - -import core._ -import Contexts._, Symbols._, Types._, Flags._, Decorators._, StdNames._, Constants._ -import SymDenotations.SymDenotation -import TreeTransforms._ -import SymUtils._ -import ast.untpd -import ast.Trees._ - -/** Expand SAM closures that cannot be represented by the JVM as lambdas to anonymous classes. - * These fall into five categories - * - * 1. Partial function closures, we need to generate a isDefinedAt method for these. - * 2. Closures implementing non-trait classes. - * 3. Closures implementing classes that inherit from a class other than Object - * (a lambda cannot not be a run-time subtype of such a class) - * 4. Closures that implement traits which run initialization code. - * 5. Closures that get synthesized abstract methods in the transformation pipeline. These methods can be - * (1) superaccessors, (2) outer references, (3) accessors for fields. - */ -class ExpandSAMs extends MiniPhaseTransform { thisTransformer => - override def phaseName = "expandSAMs" - - import ast.tpd._ - - /** Is the SAMType `cls` also a SAM under the rules of the platform? */ - def isPlatformSam(cls: ClassSymbol)(implicit ctx: Context): Boolean = - ctx.platform.isSam(cls) - - override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo): Tree = tree match { - case Block(stats @ (fn: DefDef) :: Nil, Closure(_, fnRef, tpt)) if fnRef.symbol == fn.symbol => - tpt.tpe match { - case NoType => tree // it's a plain function - case tpe @ SAMType(_) if tpe.isRef(defn.PartialFunctionClass) => - toPartialFunction(tree) - case tpe @ SAMType(_) if isPlatformSam(tpe.classSymbol.asClass) => - tree - case tpe => - val Seq(samDenot) = tpe.abstractTermMembers.filter(!_.symbol.is(SuperAccessor)) - cpy.Block(tree)(stats, - AnonClass(tpe :: Nil, fn.symbol.asTerm :: Nil, samDenot.symbol.asTerm.name :: Nil)) - } - case _ => - tree - } - - private def toPartialFunction(tree: Block)(implicit ctx: Context, info: TransformerInfo): Tree = { - val Block( - (applyDef @ DefDef(nme.ANON_FUN, Nil, List(List(param)), _, _)) :: Nil, - Closure(_, _, tpt)) = tree - val applyRhs: Tree = applyDef.rhs - val applyFn = applyDef.symbol.asTerm - - val MethodType(paramNames, paramTypes) = applyFn.info - val isDefinedAtFn = applyFn.copy( - name = nme.isDefinedAt, - flags = Synthetic | Method, - info = MethodType(paramNames, paramTypes, defn.BooleanType)).asTerm - val tru = Literal(Constant(true)) - def isDefinedAtRhs(paramRefss: List[List[Tree]]) = applyRhs match { - case Match(selector, cases) => - assert(selector.symbol == param.symbol) - val paramRef = paramRefss.head.head - // Again, the alternative - // val List(List(paramRef)) = paramRefs - // fails with a similar self instantiation error - def translateCase(cdef: CaseDef): CaseDef = - cpy.CaseDef(cdef)(body = tru).changeOwner(applyFn, isDefinedAtFn) - val defaultSym = ctx.newSymbol(isDefinedAtFn, nme.WILDCARD, Synthetic, selector.tpe.widen) - val defaultCase = - CaseDef( - Bind(defaultSym, Underscore(selector.tpe.widen)), - EmptyTree, - Literal(Constant(false))) - val annotated = Annotated(paramRef, New(ref(defn.UncheckedAnnotType))) - cpy.Match(applyRhs)(annotated, cases.map(translateCase) :+ defaultCase) - case _ => - tru - } - val isDefinedAtDef = transformFollowingDeep(DefDef(isDefinedAtFn, isDefinedAtRhs(_))) - val anonCls = AnonClass(tpt.tpe :: Nil, List(applyFn, isDefinedAtFn), List(nme.apply, nme.isDefinedAt)) - cpy.Block(tree)(List(applyDef, isDefinedAtDef), anonCls) - } -} |