@@ -196,10 +196,12 @@ object TreeTransforms {
196196 }
197197 }
198198
199- @ sharable val NoTransform = new TreeTransform {
199+ private class NoTreeTransform extends TreeTransform {
200200 def phase = unsupported(" phase" )
201201 }
202202
203+ @ sharable val NoTransform : TreeTransform = new NoTreeTransform
204+
203205 type Mutator [T ] = (TreeTransform , T , Context ) => TreeTransform
204206
205207 class TransformerInfo (val transformers : Array [TreeTransform ], val nx : NXTransformations , val group : TreeTransformer )
@@ -209,15 +211,29 @@ object TreeTransforms {
209211 * @see NXTransformations.index for format of plan
210212 */
211213 class NXTransformations {
214+ private val clsMethodsCache = new java.util.IdentityHashMap [Class [_], Array [java.lang.reflect.Method ]]
212215
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.
213218 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+
215230 var i = clsMethods.length - 1
216231 while (i >= 0 ) {
217232 if (clsMethods(i).getName == name)
218- return cls != classOf [ TreeTransform ]
233+ return true
219234 i -= 1
220235 }
236+
221237 hasRedefinedMethod(cls.getSuperclass, name)
222238 }
223239
0 commit comments