@@ -38,17 +38,11 @@ class AnnotationsMappingBenchmark:
38
38
@ Param (Array (" v1" , " v2" , " v3" , " v4" ))
39
39
var valName : String = null
40
40
41
- @ Param (Array (" current" , " oldCheck" , " newCheckEquals" , " newCheckEq" , " noCheck" , " noCheckCopySymbols" ))
42
- var typeMapName : String = null
43
-
44
41
@ Param (Array (" id" , " mapInts" ))
45
42
var typeFunctionName : String = null
46
43
47
44
@ Setup (Level .Iteration )
48
45
def setup (): Unit =
49
- /** A custom phase that is used to retrieve the `Type`s and `Context` to be
50
- * used in the benchmark.
51
- */
52
46
val testPhase =
53
47
new Phase :
54
48
final override def phaseName = " testPhase"
@@ -58,20 +52,15 @@ class AnnotationsMappingBenchmark:
58
52
specialIntTp = pkg.requiredClass(" Test" ).requiredType(" SpecialInt" ).typeRef
59
53
context = ctx
60
54
61
- /** A custom compiler that only runs the `Parser`, `TyperPhase` and
62
- * `testPhase`.
63
- */
64
55
val compiler =
65
56
new Compiler :
66
57
private final val baseCompiler = new Compiler ()
67
58
final override def phases = List (List (Parser ()), List (TyperPhase ()), List (testPhase))
68
59
69
- /** A custom driver that uses `compiler`. */
70
60
val driver =
71
61
new Driver :
72
62
final override def newCompiler (using Context ): Compiler = compiler
73
63
74
- // Runs the driver with the test file.
75
64
driver.process(Array (" -classpath" , System .getProperty(" BENCH_CLASS_PATH" ), " tests/someAnnotatedTypes.scala" ))
76
65
77
66
typeFunction =
@@ -80,142 +69,8 @@ class AnnotationsMappingBenchmark:
80
69
case " mapInts" => tp => (if tp frozen_=:= defn.IntType then specialIntTp else tp)
81
70
case _ => throw new IllegalArgumentException (s " Unknown type function: $typeFunctionName" )
82
71
83
- /** Creates a new `TypeMap` that uses `mapConcreteAnnotationWith` to map
84
- * concrete annotations. It is used to compare several ways to map these
85
- * annotations.
86
- */
87
- def makeTypeMap (mapConcreteAnnotationWith : (ConcreteAnnotation , TypeMap ) => Context ?=> Annotation ) =
72
+ typeMap =
88
73
new TypeMap (using context):
89
74
final override def apply (tp : Type ): Type = typeFunction(mapOver(tp))
90
- final override def mapOver (tp : Type ) =
91
- tp match
92
- case tp @ AnnotatedType (underlying, annot) =>
93
- val underlying1 = this (underlying)
94
- val annot1 =
95
- annot match
96
- case annot : ConcreteAnnotation => mapConcreteAnnotationWith(annot, this )
97
- case _ => annot.mapWith(this )
98
- if annot1 eq EmptyAnnotation then underlying1
99
- else derivedAnnotatedType(tp, underlying1, annot1)
100
- case _ => super .mapOver(tp)
101
-
102
- /** Retrieves all argument from a tree. This old implementation does not
103
- * include type arguments.
104
- */
105
- def oldAllArguments (tree : Tree )(using Context ): List [Tree ] =
106
- tpd.unsplice(tree) match
107
- case Apply (fn, args) => oldAllArguments(fn) ::: args
108
- case TypeApply (fn, _) => oldAllArguments(fn)
109
- case Block (_, expr) => oldAllArguments(expr)
110
- case _ => Nil
111
-
112
- /** This is the old (<= d1489734b7) implementation of `Annotation.mapWith`.
113
- * It 1. does not include type arguments and 2. uses `frozen_=:=` to
114
- * compare types and 3. does not copy all symbols.
115
- */
116
- def oldMapWith (annot : ConcreteAnnotation , tm : TypeMap )(using Context ): Annotation =
117
- val tree = annot.tree
118
- val args = oldAllArguments(tree)
119
- if args.isEmpty then annot
120
- else
121
- val findDiff = new TreeAccumulator [Type ]:
122
- def apply (x : Type , tree : Tree )(using Context ): Type =
123
- if tm.isRange(x) then x
124
- else
125
- val tp1 = tm(tree.tpe)
126
- foldOver(if tp1 frozen_=:= tree.tpe then x else tp1, tree)
127
- val diff = findDiff(NoType , args)
128
- if tm.isRange(diff) then EmptyAnnotation
129
- else if diff.exists then annot.derivedAnnotation(tm.mapOver(tree))
130
- else annot
131
-
132
- /** Retrieves all argument from a tree, including type arguments. */
133
- def newAllArguments (tree : Tree )(using Context ): List [Tree ] =
134
- tpd.unsplice(tree) match
135
- case Apply (fn, args) => newAllArguments(fn) ::: args
136
- case TypeApply (fn, args) => newAllArguments(fn) ::: args
137
- case Block (_, expr) => newAllArguments(expr)
138
- case _ => Nil
139
-
140
- /** This is the new implementation of `Annotation.mapWith`. It 1. includes
141
- * type arguments and 2. uses `==` to compare types and 3. copies all
142
- * symbols by using a custom `TreeTypeMap` that overrides `withMappedSyms`.
143
- */
144
- def newMapWithEquals (annot : ConcreteAnnotation , tm : TypeMap )(using Context ): Annotation =
145
- val tree = annot.tree
146
- val args = newAllArguments(tree)
147
- if args.isEmpty then annot
148
- else
149
- val findDiff = new TreeAccumulator [Type ]:
150
- def apply (x : Type , tree : Tree )(using Context ): Type =
151
- if tm.isRange(x) then x
152
- else
153
- val tp1 = tm(tree.tpe)
154
- foldOver(if tp1 == tree.tpe then x else tp1, tree)
155
- val diff = findDiff(NoType , args)
156
- if tm.isRange(diff) then EmptyAnnotation
157
- else if diff.exists then
158
- val ttm =
159
- new TreeTypeMap (tm):
160
- final override def withMappedSyms (syms : List [Symbol ]): TreeTypeMap =
161
- withMappedSyms(syms, mapSymbols(syms, this , mapAlways = true ))
162
- annot.derivedAnnotation(ttm.transform(tree))
163
- else annot
164
-
165
- /** Exactly the same as `newMapWithEquals`, but uses `eq` instead of `==` to
166
- * compare types.
167
- */
168
- def newMapWithEq (annot : ConcreteAnnotation , tm : TypeMap )(using Context ): Annotation =
169
- val tree = annot.tree
170
- val args = newAllArguments(tree)
171
- if args.isEmpty then annot
172
- else
173
- val findDiff = new TreeAccumulator [Type ]:
174
- def apply (x : Type , tree : Tree )(using Context ): Type =
175
- if tm.isRange(x) then x
176
- else
177
- val tp1 = tm(tree.tpe)
178
- foldOver(if tp1 eq tree.tpe then x else tp1, tree)
179
- val diff = findDiff(NoType , args)
180
- if tm.isRange(diff) then EmptyAnnotation
181
- else if diff.exists then
182
- val ttm =
183
- new TreeTypeMap (tm):
184
- final override def withMappedSyms (syms : List [Symbol ]): TreeTypeMap =
185
- withMappedSyms(syms, mapSymbols(syms, this , mapAlways = true ))
186
- annot.derivedAnnotation(ttm.transform(tree))
187
- else annot
188
-
189
- def noCheckMapWith (annot : ConcreteAnnotation , tm : TypeMap )(using Context ): Annotation =
190
- annot.derivedAnnotation(tm.mapOver(annot.tree))
191
-
192
- def noCheckCopySymbolsMapWith (annot : ConcreteAnnotation , tm : TypeMap )(using Context ): Annotation =
193
- val ttm =
194
- new TreeTypeMap (tm):
195
- final override def withMappedSyms (syms : List [Symbol ]): TreeTypeMap =
196
- withMappedSyms(syms, mapSymbols(syms, this , mapAlways = true ))
197
- annot.derivedAnnotation(ttm.transform(annot.tree))
198
-
199
- typeMap =
200
- typeMapName match
201
- case " current" =>
202
- new TypeMap (using context):
203
- final override def apply (tp : Type ): Type = typeFunction(mapOver(tp))
204
- case " oldCheck" =>
205
- makeTypeMap(oldMapWith)
206
- case " newCheckEquals" =>
207
- // This should be the same as `current`, modulo a few indirections.
208
- makeTypeMap(newMapWithEq)
209
- case " newCheckEq" =>
210
- makeTypeMap(newMapWithEq)
211
- case " noCheck" =>
212
- makeTypeMap(noCheckMapWith)
213
- case " noCheckCopySymbols" =>
214
- makeTypeMap(noCheckCopySymbolsMapWith)
215
- case _ =>
216
- throw new IllegalArgumentException (s " Unknown type map: $typeMapName" )
217
75
218
- @ Benchmark
219
- def applyTypeMap () =
220
- val res = typeMap.apply(tp)
221
- // println(res.show(using context))
76
+ @ Benchmark def applyTypeMap () = typeMap.apply(tp)
0 commit comments