Skip to content

Commit c65a5be

Browse files
committed
Code refactoring
1 parent b70564e commit c65a5be

File tree

2 files changed

+98
-50
lines changed

2 files changed

+98
-50
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,31 @@ class Definitions {
14361436
false
14371437
})
14381438

1439+
@tu lazy val Function0SpecializedApplyNames: PerRun[collection.Set[TermName]] =
1440+
new PerRun({
1441+
for r <- defn.Function0SpecializedReturnTypes
1442+
yield nme.apply.specializedFunction(r, Nil).asTermName
1443+
})
1444+
1445+
@tu lazy val Function1SpecializedApplyNames: PerRun[collection.Set[TermName]] =
1446+
new PerRun({
1447+
for
1448+
r <- Function1SpecializedReturnTypes
1449+
t1 <- Function1SpecializedParamTypes
1450+
yield
1451+
nme.apply.specializedFunction(r, List(t1)).asTermName
1452+
})
1453+
1454+
@tu lazy val Function2SpecializedApplyNames: PerRun[collection.Set[TermName]] =
1455+
new PerRun({
1456+
for
1457+
r <- Function2SpecializedReturnTypes
1458+
t1 <- Function2SpecializedParamTypes
1459+
t2 <- Function2SpecializedReturnTypes
1460+
yield
1461+
nme.apply.specializedFunction(r, List(t1, t2)).asTermName
1462+
})
1463+
14391464
def functionArity(tp: Type)(using Context): Int = tp.dropDependentRefinement.dealias.argInfos.length - 1
14401465

14411466
/** Return underlying context function type (i.e. instance of an ContextFunctionN class)

compiler/src/dotty/tools/dotc/transform/SpecializedApplyMethods.scala

Lines changed: 73 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import Contexts.Context, Types._, Decorators._, Symbols._, DenotTransformers._
66
import SymDenotations._, Scopes._, StdNames._, NameOps._, Names._
77
import MegaPhase.MiniPhase
88

9+
import scala.collection.mutable
10+
11+
912
/** This phase synthesizes specialized methods for FunctionN, this is done
1013
* since there are no scala signatures in the bytecode for the specialized
1114
* methods.
@@ -19,75 +22,95 @@ class SpecializedApplyMethods extends MiniPhase with InfoTransformer {
1922

2023
val phaseName = "specializedApplyMethods"
2124

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+
}
3429

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+
}
3734

38-
func1 = defn.FunctionClass(1)
39-
func1Applys = for {
35+
private def specFun1(op: (Type, Type) => Unit)(using Context): Unit = {
36+
for
4037
r <- defn.Function1SpecializedReturnTypes
4138
t1 <- defn.Function1SpecializedParamTypes
42-
} yield specApply(func1, List(t1), r)
39+
do
40+
op(t1, r)
41+
}
4342

44-
func2 = defn.FunctionClass(2)
45-
func2Applys = for {
43+
private def specFun2(op: (Type, Type, Type) => Unit)(using Context): Unit = {
44+
for
4645
r <- defn.Function2SpecializedReturnTypes
4746
t1 <- defn.Function2SpecializedParamTypes
4847
t2 <- defn.Function2SpecializedReturnTypes
49-
} yield specApply(func2, List(t1, t2), r)
48+
do
49+
op(t1, t2, r)
5050
}
5151

5252
/** Add symbols for specialized methods to FunctionN */
5353
override def transformInfo(tp: Type, sym: Symbol)(using Context) = tp match {
5454
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)
6865

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+
}
7074
}
7175
case _ => tp
7276
}
7377

7478
/** Create bridge methods for FunctionN with specialized applys */
7579
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+
}
92115
}
93116
}

0 commit comments

Comments
 (0)