@@ -196,10 +196,12 @@ object TreeTransforms {
196
196
}
197
197
}
198
198
199
- @ sharable val NoTransform = new TreeTransform {
199
+ private class NoTreeTransform extends TreeTransform {
200
200
def phase = unsupported(" phase" )
201
201
}
202
202
203
+ @ sharable val NoTransform : TreeTransform = new NoTreeTransform
204
+
203
205
type Mutator [T ] = (TreeTransform , T , Context ) => TreeTransform
204
206
205
207
class TransformerInfo (val transformers : Array [TreeTransform ], val nx : NXTransformations , val group : TreeTransformer )
@@ -209,15 +211,29 @@ object TreeTransforms {
209
211
* @see NXTransformations.index for format of plan
210
212
*/
211
213
class NXTransformations {
214
+ private val clsMethodsCache = new java.util.IdentityHashMap [Class [_], Array [java.lang.reflect.Method ]]
212
215
216
+ // TODO: We spend too much time here. See if we can call it less or make it faster,
217
+ // e.g. by checking `cls.getMethod(name, ...).getDeclaringClass != classOf[TreeTransform]` instead.
213
218
private def hasRedefinedMethod (cls : Class [_], name : String ): Boolean = {
214
- val clsMethods = cls.getDeclaredMethods
219
+ if (cls.eq(classOf [TreeTransform ]) || cls.eq(classOf [NoTreeTransform ]) ||
220
+ cls.eq(classOf [MiniPhaseTransform ]))
221
+ return false
222
+
223
+ // Class#getDeclaredMethods is slow, so we cache its output
224
+ var clsMethods = clsMethodsCache.get(cls)
225
+ if (clsMethods eq null ) {
226
+ clsMethods = cls.getDeclaredMethods
227
+ clsMethodsCache.put(cls, clsMethods)
228
+ }
229
+
215
230
var i = clsMethods.length - 1
216
231
while (i >= 0 ) {
217
232
if (clsMethods(i).getName == name)
218
- return cls != classOf [ TreeTransform ]
233
+ return true
219
234
i -= 1
220
235
}
236
+
221
237
hasRedefinedMethod(cls.getSuperclass, name)
222
238
}
223
239
0 commit comments