1
1
package dotty .tools .dotc .transform
2
2
3
- import dotty .tools .dotc .ast .Trees .{Select , Ident , SeqLiteral , Typed }
3
+ import dotty .tools .dotc .ast .Trees .{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 .StdNames ._
8
- import dotty .tools .dotc .core .{Flags , Definitions }
9
- import dotty .tools .dotc .core .Symbols .Symbol
10
- import dotty .tools .dotc .core .Types .{TermRef , Type }
11
- import dotty .tools .dotc .transform .TreeTransforms .{TransformerInfo , MiniPhaseTransform }
12
7
import dotty .tools .dotc .core .Decorators ._
8
+ import dotty .tools .dotc .core .Names .Name
9
+ import dotty .tools .dotc .core .StdNames ._
10
+ import dotty .tools .dotc .core .Symbols .{NoSymbol , Symbol }
11
+ import dotty .tools .dotc .core .Types .Type
12
+ import dotty .tools .dotc .core .{Definitions , Flags }
13
+ import dotty .tools .dotc .transform .TreeTransforms .{TreeTransform , MiniPhaseTransform , TransformerInfo }
13
14
14
15
/**
15
- * This phase retrieves all `@specialized` anotations before they are thrown away ,
16
+ * This phase retrieves all `@specialized` anotations,
16
17
* and stores them for the `TypeSpecializer` phase.
17
18
*/
18
19
class PreSpecializer extends MiniPhaseTransform {
19
20
20
21
override def phaseName : String = " prespecialize"
21
22
23
+ private var anyRefModule : Symbol = NoSymbol
24
+ private var specializableMapping : Map [Symbol , List [Type ]] = _
25
+ private var specializableModule : Symbol = NoSymbol
26
+
27
+
28
+ override def prepareForUnit (tree : tpd.Tree )(implicit ctx : Context ): TreeTransform = {
29
+ specializableModule = ctx.requiredModule(" scala.Specializable" )
30
+ anyRefModule = ctx.requiredModule(" scala.package" ) // Using nme.PACKAGE generated errors on my machine - should be further explored
31
+ def specializableField (nm : String ) = specializableModule.info.member(nm.toTermName).symbol
32
+
33
+ specializableMapping = Map (
34
+ specializableField(" Primitives" ) -> List (defn.IntType , defn.LongType , defn.FloatType , defn.ShortType ,
35
+ defn.DoubleType , defn.BooleanType , defn.UnitType , defn.CharType , defn.ByteType ),
36
+ specializableField(" Everything" ) -> List (defn.IntType , defn.LongType , defn.FloatType , defn.ShortType ,
37
+ defn.DoubleType , defn.BooleanType , defn.UnitType , defn.CharType , defn.ByteType , defn.AnyRefType ),
38
+ specializableField(" Bits32AndUp" ) -> List (defn.IntType , defn.LongType , defn.FloatType , defn.DoubleType ),
39
+ specializableField(" Integral" ) -> List (defn.ByteType , defn.ShortType , defn.IntType , defn.LongType , defn.CharType ),
40
+ specializableField(" AllNumeric" ) -> List (defn.ByteType , defn.ShortType , defn.IntType , defn.LongType ,
41
+ defn.CharType , defn.FloatType , defn.DoubleType ),
42
+ specializableField(" BestOfBreed" ) -> List (defn.IntType , defn.DoubleType , defn.BooleanType , defn.UnitType ,
43
+ defn.AnyRefType )
44
+ )
45
+ this
46
+ }
47
+
22
48
private final def primitiveCompanionToPrimitive (companion : Type )(implicit ctx : Context ) = {
23
- if (companion.termSymbol eq ctx.requiredModule( " scala.package " ). info.member(" AnyRef" .toTermName).symbol) { // Handles `@specialized(AnyRef)` cases
49
+ if (companion.termSymbol eq anyRefModule. info.member(nme. AnyRef .toTermName).symbol) {
24
50
defn.AnyRefType
25
51
}
26
52
else {
@@ -30,6 +56,13 @@ class PreSpecializer extends MiniPhaseTransform {
30
56
}
31
57
}
32
58
59
+ private def specializableToPrimitive (specializable : Type , name : Name )(implicit ctx : Context ): List [Type ] = {
60
+ if (specializable.termSymbol eq specializableModule.info.member(name).symbol) {
61
+ specializableMapping(specializable.termSymbol)
62
+ }
63
+ else Nil
64
+ }
65
+
33
66
def defn (implicit ctx : Context ): Definitions = ctx.definitions
34
67
35
68
private def primitiveTypes (implicit ctx : Context ) =
@@ -60,12 +93,13 @@ class PreSpecializer extends MiniPhaseTransform {
60
93
val args = annot.arguments
61
94
if (args.isEmpty) primitiveTypes
62
95
else args.head match {
63
- case a@ Typed (SeqLiteral (types), _) => // Matches the expected `@specialized(...)` annotations
96
+ case a @ Typed (SeqLiteral (types), _) =>
64
97
types.map(t => primitiveCompanionToPrimitive(t.tpe))
65
98
66
- case a@ Select (Ident (_), _) => primitiveTypes // Matches `Select(Ident(Specializable), Primitives)`
67
- // which is used in several instances in the compiler
68
- case _ => ctx.error(" surprising match on specialized annotation" ); Nil
99
+ case a @ Ident (groupName) if a.tpe.isInstanceOf [Type ] => // Matches `@specialized` annotations on Specializable Groups
100
+ specializableToPrimitive(a.tpe.asInstanceOf [Type ], groupName)
101
+
102
+ case _ => ctx.error(" unexpected match on specialized annotation" ); Nil
69
103
}
70
104
case nil => Nil
71
105
}
0 commit comments