@@ -6,6 +6,9 @@ import Contexts.Context, Types._, Decorators._, Symbols._, DenotTransformers._
6
6
import SymDenotations ._ , Scopes ._ , StdNames ._ , NameOps ._ , Names ._
7
7
import MegaPhase .MiniPhase
8
8
9
+ import scala .collection .mutable
10
+
11
+
9
12
/** This phase synthesizes specialized methods for FunctionN, this is done
10
13
* since there are no scala signatures in the bytecode for the specialized
11
14
* methods.
@@ -19,75 +22,95 @@ class SpecializedApplyMethods extends MiniPhase with InfoTransformer {
19
22
20
23
val phaseName = " specializedApplyMethods"
21
24
22
- private [this ] var func0Applys : collection.Set [Symbol ] = _
23
- private [this ] var func1Applys : collection.Set [Symbol ] = _
24
- private [this ] var func2Applys : collection.Set [Symbol ] = _
25
- private [this ] var func0 : Symbol = _
26
- private [this ] var func1 : Symbol = _
27
- private [this ] var func2 : Symbol = _
28
-
29
- private def init ()(using Context ): Unit = if (func0Applys eq null ) {
30
- def specApply (sym : Symbol , args : List [Type ], ret : Type )(using Context ): Symbol = {
31
- val name = nme.apply.specializedFunction(ret, args)
32
- newSymbol(sym, name, Flags .Method , MethodType (args, ret))
33
- }
25
+ private def specApply (sym : Symbol , args : List [Type ], ret : Type )(using Context ): Symbol = {
26
+ val name = nme.apply.specializedFunction(ret, args)
27
+ newSymbol(sym, name, Flags .Method , MethodType (args, ret))
28
+ }
34
29
35
- func0 = defn.FunctionClass (0 )
36
- func0Applys = for (r <- defn.Function0SpecializedReturnTypes ) yield specApply(func0, Nil , r)
30
+ private def specFun0 (op : Type => Unit )(using Context ): Unit = {
31
+ for (r <- defn.Function0SpecializedReturnTypes ) do
32
+ op(r)
33
+ }
37
34
38
- func1 = defn. FunctionClass ( 1 )
39
- func1Applys = for {
35
+ private def specFun1 ( op : ( Type , Type ) => Unit )( using Context ) : Unit = {
36
+ for
40
37
r <- defn.Function1SpecializedReturnTypes
41
38
t1 <- defn.Function1SpecializedParamTypes
42
- } yield specApply(func1, List (t1), r)
39
+ do
40
+ op(t1, r)
41
+ }
43
42
44
- func2 = defn. FunctionClass ( 2 )
45
- func2Applys = for {
43
+ private def specFun2 ( op : ( Type , Type , Type ) => Unit )( using Context ) : Unit = {
44
+ for
46
45
r <- defn.Function2SpecializedReturnTypes
47
46
t1 <- defn.Function2SpecializedParamTypes
48
47
t2 <- defn.Function2SpecializedReturnTypes
49
- } yield specApply(func2, List (t1, t2), r)
48
+ do
49
+ op(t1, t2, r)
50
50
}
51
51
52
52
/** Add symbols for specialized methods to FunctionN */
53
53
override def transformInfo (tp : Type , sym : Symbol )(using Context ) = tp match {
54
54
case tp : ClassInfo if defn.isPlainFunctionClass(sym) => {
55
- init()
56
- val newDecls = sym.name.functionArity match {
57
- case 0 => func0Applys.foldLeft(tp.decls.cloneScope) {
58
- (decls, sym) => decls.enter(sym); decls
59
- }
60
- case 1 => func1Applys.foldLeft(tp.decls.cloneScope) {
61
- (decls, sym) => decls.enter(sym); decls
62
- }
63
- case 2 => func2Applys.foldLeft(tp.decls.cloneScope) {
64
- (decls, sym) => decls.enter(sym); decls
65
- }
66
- case _ => tp.decls
67
- }
55
+ sym.name.functionArity match {
56
+ case 0 =>
57
+ val scope = tp.decls.cloneScope
58
+ specFun0 { r => scope.enter(specApply(sym, Nil , r)) }
59
+ tp.derivedClassInfo(decls = scope)
60
+
61
+ case 1 =>
62
+ val scope = tp.decls.cloneScope
63
+ specFun1 { (t1, r) => scope.enter(specApply(sym, List (t1), r)) }
64
+ tp.derivedClassInfo(decls = scope)
68
65
69
- tp.derivedClassInfo(decls = newDecls)
66
+ case 2 =>
67
+ val scope = tp.decls.cloneScope
68
+ specFun2 { (t1, t2, r) => scope.enter(specApply(sym, List (t1, t2), r)) }
69
+ tp.derivedClassInfo(decls = scope)
70
+
71
+ case _ =>
72
+ tp
73
+ }
70
74
}
71
75
case _ => tp
72
76
}
73
77
74
78
/** Create bridge methods for FunctionN with specialized applys */
75
79
override def transformTemplate (tree : Template )(using Context ) = {
76
- val owner = tree.symbol.owner
77
- val additionalSymbols =
78
- if (owner eq func0) func0Applys
79
- else if (owner eq func1) func1Applys
80
- else if (owner eq func2) func2Applys
81
- else Nil
82
-
83
- if (additionalSymbols eq Nil ) tree
84
- else cpy.Template (tree)(body = tree.body ++ additionalSymbols.map { apply =>
85
- DefDef (apply.asTerm, { vparamss =>
86
- This (owner.asClass)
87
- .select(nme.apply)
88
- .appliedToArgss(vparamss)
89
- .ensureConforms(apply.info.finalResultType)
90
- })
91
- })
80
+ val cls = tree.symbol.owner.asInstanceOf [ClassSymbol ]
81
+
82
+ if (! defn.isPlainFunctionClass(cls)) return tree
83
+
84
+ def synthesizeApply (names : collection.Set [TermName ]): Tree = {
85
+ val applyBuf = new mutable.ListBuffer [DefDef ]
86
+ names.foreach { name =>
87
+ val applySym = cls.info.decls.lookup(name)
88
+ val ddef = DefDef (
89
+ applySym.asTerm,
90
+ { vparamss =>
91
+ This (cls)
92
+ .select(nme.apply)
93
+ .appliedToArgss(vparamss)
94
+ .ensureConforms(applySym.info.finalResultType)
95
+ }
96
+ )
97
+ applyBuf += ddef
98
+ }
99
+ cpy.Template (tree)(body = tree.body ++ applyBuf)
100
+ }
101
+
102
+ cls.name.functionArity match {
103
+ case 0 =>
104
+ synthesizeApply(defn.Function0SpecializedApplyNames ())
105
+
106
+ case 1 =>
107
+ synthesizeApply(defn.Function1SpecializedApplyNames ())
108
+
109
+ case 2 =>
110
+ synthesizeApply(defn.Function2SpecializedApplyNames ())
111
+
112
+ case _ =>
113
+ tree
114
+ }
92
115
}
93
116
}
0 commit comments