@@ -4,69 +4,24 @@ import dotty.tools.dotc.ast.Trees.{Select, Ident, SeqLiteral, Typed}
4
4
import dotty .tools .dotc .ast .tpd
5
5
import dotty .tools .dotc .core .Annotations .Annotation
6
6
import dotty .tools .dotc .core .Contexts .Context
7
- import dotty .tools .dotc .core .DenotTransformers .InfoTransformer
8
7
import dotty .tools .dotc .core .StdNames ._
9
- import dotty .tools .dotc .core .{Flags , Definitions , Symbols }
8
+ import dotty .tools .dotc .core .{Flags , Definitions }
10
9
import dotty .tools .dotc .core .Symbols .Symbol
11
- import dotty .tools .dotc .core .Types .{ TermRef , TypeRef , OrType , Type }
10
+ import dotty .tools .dotc .core .Types .Type
12
11
import dotty .tools .dotc .transform .TreeTransforms .{TransformerInfo , MiniPhaseTransform }
13
12
14
- import scala .collection .mutable
15
-
16
13
/**
17
14
* This phase retrieves all `@specialized` anotations before they are thrown away,
18
15
* and stores them for the `TypeSpecializer` phase.
19
16
*/
20
- class PreSpecializer extends MiniPhaseTransform with InfoTransformer {
17
+ class PreSpecializer extends MiniPhaseTransform {
21
18
22
19
override def phaseName : String = " prespecialize"
23
20
24
- private val specTypes : mutable.HashMap [Symbols .Symbol , List [Type ]] = mutable.HashMap .empty
25
-
26
- override def transformInfo (tp : Type , sym : Symbol )(implicit ctx : Context ): Type = {
27
-
28
- def getSpecTypes (sym : Symbol )(implicit ctx : Context ): List [Type ] = {
29
-
30
- def allowedToSpecialize (sym : Symbol ): Boolean = {
31
- sym.name != nme.asInstanceOf_ &&
32
- sym.name != nme.isInstanceOf_ &&
33
- ! (sym is Flags .JavaDefined ) &&
34
- ! sym.isConstructor// isPrimaryConstructor
35
- }
36
-
37
- if (allowedToSpecialize(sym)) {
38
- val annotation = sym.denot.getAnnotation(ctx.definitions.specializedAnnot).getOrElse(Nil )
39
- annotation match {
40
- case annot : Annotation =>
41
- val args = annot.arguments
42
- if (args.isEmpty) primitiveTypes
43
- else args.head match {
44
- case a@ Typed (SeqLiteral (types), _) => types.map(t => nameToType(t.tpe)) // Matches the expected `@specialized(...)` annotations
45
- case a@ Select (Ident (_), _) => primitiveTypes // Matches `Select(Ident(Specializable), Primitives)` which is used in several instances
46
- case _ => ctx.error(" surprising match on specialized annotation" ); Nil
47
- }
48
- case nil => Nil
49
- }
50
- } else Nil
51
- }
52
- val st = getSpecTypes(sym)
53
- if (st.nonEmpty) {
54
- specTypes.put(sym.owner, st)
55
- }
56
- tp
57
- }
58
-
59
- private final def nameToType (name : Type )(implicit ctx : Context ) =
60
- name.asInstanceOf [TermRef ].name.toString match {
61
- case s if s.startsWith(" Int" ) => defn.IntType
62
- case s if s.startsWith(" Boolean" ) => defn.BooleanType
63
- case s if s.startsWith(" Byte" ) => defn.ByteType
64
- case s if s.startsWith(" Long" ) => defn.LongType
65
- case s if s.startsWith(" Short" ) => defn.ShortType
66
- case s if s.startsWith(" Float" ) => defn.FloatType
67
- case s if s.startsWith(" Unit" ) => defn.UnitType
68
- case s if s.startsWith(" Double" ) => defn.DoubleType
69
- case s if s.startsWith(" Char" ) => defn.CharType
21
+ private final def primitiveCompanionToPrimitive (companion : Type )(implicit ctx : Context ) = {
22
+ val claz = companion.termSymbol.companionClass
23
+ assert(ctx.definitions.ScalaValueClasses .contains(claz))
24
+ claz.typeRef
70
25
}
71
26
72
27
def defn (implicit ctx : Context ): Definitions = ctx.definitions
@@ -83,9 +38,42 @@ class PreSpecializer extends MiniPhaseTransform with InfoTransformer {
83
38
ctx.definitions.UnitType
84
39
)
85
40
41
+ def getSpec (sym : Symbol )(implicit ctx : Context ): List [Type ] = {
42
+
43
+ def allowedToSpecialize (sym : Symbol ): Boolean = {
44
+ sym.name != nme.asInstanceOf_ &&
45
+ sym.name != nme.isInstanceOf_ &&
46
+ ! (sym is Flags .JavaDefined ) &&
47
+ ! sym.isConstructor &&
48
+ ! sym.name.toString.contains(" Function2" )
49
+ }
50
+
51
+ if (allowedToSpecialize(sym)) {
52
+ val annotation = sym.denot.getAnnotation(ctx.definitions.specializedAnnot).getOrElse(Nil )
53
+ annotation match {
54
+ case annot : Annotation =>
55
+ val args = annot.arguments
56
+ if (args.isEmpty) primitiveTypes
57
+ else args.head match {
58
+ case a@ Typed (SeqLiteral (types), _) => types.map(t => primitiveCompanionToPrimitive(t.tpe)) // Matches the expected `@specialized(...)` annotations
59
+ case a@ Select (Ident (_), _) => primitiveTypes // Matches `Select(Ident(Specializable), Primitives)` which is used in several instances
60
+ case _ => ctx.error(" surprising match on specialized annotation" ); Nil
61
+ }
62
+ case nil => Nil
63
+ }
64
+ } else Nil
65
+ }
66
+
86
67
override def transformDefDef (tree : tpd.DefDef )(implicit ctx : Context , info : TransformerInfo ): tpd.Tree = {
87
- val st = specTypes.getOrElse(tree.symbol, List ())
88
- if (st.nonEmpty) ctx.specializePhase.asInstanceOf [TypeSpecializer ].registerSpecializationRequest(tree.symbol)(st)
68
+ val tparams = tree.tparams.map(_.symbol)
69
+ val st = tparams.map(getSpec)
70
+ if (st.nonEmpty) {
71
+ st.map{
72
+ case (types : List [Type ]) if types.nonEmpty =>
73
+ ctx.specializePhase.asInstanceOf [TypeSpecializer ].registerSpecializationRequest(tree.symbol)(types)
74
+ case _ =>
75
+ }
76
+ }
89
77
tree
90
78
}
91
- }
79
+ }
0 commit comments