@@ -16,6 +16,8 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
1616 val phaseName = " specializeFunctions"
1717 override def runsAfter = Set (classOf [ElimByName ])
1818
19+ private val jFunction = " scala.compat.java8.JFunction" .toTermName
20+
1921 /** Transforms the type to include decls for specialized applys */
2022 override def transformInfo (tp : Type , sym : Symbol )(implicit ctx : Context ) = tp match {
2123 case tp : ClassInfo if ! sym.is(Flags .Package ) && (tp.decls ne EmptyScope ) =>
@@ -26,9 +28,15 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
2628 val func = defn.FunctionClass (arity)
2729 if (parent.derivesFrom(func)) {
2830 val typeParams = tp.cls.typeRef.baseType(func).argInfos
29- val interface = specInterface(typeParams)
30-
31- if (interface.exists && tp.decls.lookup(nme.apply).exists) {
31+ val isSpecializable =
32+ defn.isSpecializableFunction(
33+ parent.classSymbol.asClass,
34+ typeParams.init,
35+ typeParams.last
36+ )
37+
38+ if (isSpecializable && tp.decls.lookup(nme.apply).exists) {
39+ val interface = specInterface(typeParams)
3240 val specializedMethodName = nme.apply.specializedFunction(typeParams.last, typeParams.init)
3341 newApplys += (specializedMethodName -> interface)
3442 }
@@ -63,13 +71,12 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
6371 val applyBuf = new mutable.ListBuffer [Tree ]
6472 val newBody = tree.body.mapConserve {
6573 case dt : DefDef if dt.name == nme.apply && dt.vparamss.length == 1 =>
66- val specName = nme.apply.specializedFunction(
67- dt.tpe.widen.finalResultType,
68- dt.vparamss.head.map(_.symbol.info)
69- )
70-
71- val specializedApply = tree.symbol.enclosingClass.info.decls.lookup(specName)
74+ val cls = tree.symbol.enclosingClass.asClass
75+ val typeParams = dt.vparamss.head.map(_.symbol.info)
76+ val retType = dt.tpe.widen.finalResultType
7277
78+ val specName = specializedName(nme.apply, typeParams :+ retType)
79+ val specializedApply = cls.info.decls.lookup(specName)
7380 if (specializedApply.exists) {
7481 val apply = specializedApply.asTerm
7582 val specializedDecl =
@@ -104,9 +111,14 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
104111 fun.symbol.owner.derivesFrom(defn.FunctionClass (args.length))
105112 =>
106113 val params = (fun.tpe.widen.firstParamTypes :+ tree.tpe).map(_.widenSingleton.dealias)
107- val specializedApply = specializedName(nme.apply, params)
108-
109- if (! params.exists(_.isInstanceOf [ExprType ]) && fun.symbol.owner.info.decls.lookup(specializedApply).exists) {
114+ val isSpecializable =
115+ defn.isSpecializableFunction(
116+ fun.symbol.owner.asClass,
117+ params.init,
118+ params.last)
119+
120+ if (isSpecializable && ! params.exists(_.isInstanceOf [ExprType ])) {
121+ val specializedApply = specializedName(nme.apply, params)
110122 val newSel = fun match {
111123 case Select (qual, _) =>
112124 qual.select(specializedApply)
@@ -126,14 +138,12 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
126138 case _ => tree
127139 }
128140
129- @ inline private def specializedName (name : Name , args : List [Type ])(implicit ctx : Context ) =
130- name.specializedFor (args, args.map(_.typeSymbol.name), Nil , Nil )
141+ private def specializedName (name : Name , args : List [Type ])(implicit ctx : Context ) =
142+ name.specializedFunction (args.last , args.init )
131143
132- @ inline private def specInterface (typeParams : List [Type ])(implicit ctx : Context ) = {
133- val specName =
134- (" JFunction" + (typeParams.length - 1 )).toTermName
135- .specializedFunction(typeParams.last, typeParams.init)
144+ private def functionName (typeParams : List [Type ])(implicit ctx : Context ) =
145+ jFunction ++ (typeParams.length - 1 ).toString
136146
137- ctx.getClassIfDefined( " scala.compat.java8. " .toTermName ++ specName)
138- }
147+ private def specInterface ( typeParams : List [ Type ])( implicit ctx : Context ) =
148+ ctx.getClassIfDefined(functionName(typeParams).specializedFunction(typeParams.last, typeParams.init))
139149}
0 commit comments