@@ -8,6 +8,7 @@ import scala.collection._
8
8
import ast .{NavigateAST , Trees , tpd , untpd }
9
9
import core ._ , core .Decorators .{sourcePos => _ , _ }
10
10
import Contexts ._ , Flags ._ , Names ._ , NameOps ._ , Symbols ._ , Trees ._ , Types ._
11
+ import transform .SymUtils .decorateSymbol
11
12
import util .Positions ._ , util .SourceFile , util .SourcePosition
12
13
import core .Denotations .SingleDenotation
13
14
import NameKinds .SimpleNameKind
@@ -33,6 +34,7 @@ object Interactive {
33
34
def isDefinitions : Boolean = (bits & definitions.bits) != 0
34
35
def isLinkedClass : Boolean = (bits & linkedClass.bits) != 0
35
36
def isImports : Boolean = (bits & imports.bits) != 0
37
+ def isLocal : Boolean = (bits & local.bits) != 0
36
38
}
37
39
38
40
/** The empty set */
@@ -59,6 +61,9 @@ object Interactive {
59
61
/** Include imports in the results */
60
62
val imports : Set = Set (1 << 5 )
61
63
64
+ /** Include local symbols, inspect local trees */
65
+ val local : Set = Set (1 << 6 )
66
+
62
67
/** All the flags */
63
68
val all : Set = Set (~ 0 )
64
69
}
@@ -164,40 +169,44 @@ object Interactive {
164
169
else
165
170
namedTrees(trees, include, matchSymbol(_, sym, include))
166
171
167
- /** Find named trees with a non-empty position whose name contains `nameSubstring` in `trees`.
168
- */
169
- def namedTrees (trees : List [SourceTree ], nameSubstring : String )
170
- (implicit ctx : Context ): List [SourceTree ] = {
171
- val predicate : NameTree => Boolean = _.name.toString.contains(nameSubstring)
172
- namedTrees(trees, Include .empty, predicate)
173
- }
174
-
175
172
/** Find named trees with a non-empty position satisfying `treePredicate` in `trees`.
176
173
*
177
- * @param includeReferences If true, include references and not just definitions
174
+ * @param trees The trees to inspect.
175
+ * @param include Whether to include references, definitions, etc.
176
+ * @param treePredicate An additional predicate that the trees must match.
177
+ * @return The trees with a non-empty position satisfying `treePredicate`.
178
178
*/
179
- def namedTrees (trees : List [SourceTree ], include : Include .Set , treePredicate : NameTree => Boolean )
180
- (implicit ctx : Context ): List [SourceTree ] = safely {
179
+ def namedTrees (trees : List [SourceTree ],
180
+ include : Include .Set ,
181
+ treePredicate : NameTree => Boolean = util.common.alwaysTrue
182
+ )(implicit ctx : Context ): List [SourceTree ] = safely {
181
183
val buf = new mutable.ListBuffer [SourceTree ]
182
184
183
185
def traverser (source : SourceFile ) = {
184
186
new untpd.TreeTraverser {
187
+ private def handle (utree : untpd.NameTree ): Unit = {
188
+ val tree = utree.asInstanceOf [tpd.NameTree ]
189
+ if (tree.symbol.exists
190
+ && ! tree.symbol.is(Synthetic )
191
+ && ! tree.symbol.isPrimaryConstructor
192
+ && tree.pos.exists
193
+ && ! tree.pos.isZeroExtent
194
+ && (include.isReferences || isDefinition(tree))
195
+ && treePredicate(tree))
196
+ buf += SourceTree (tree, source)
197
+ }
185
198
override def traverse (tree : untpd.Tree )(implicit ctx : Context ) = {
186
199
tree match {
187
200
case imp : untpd.Import if include.isImports && tree.hasType =>
188
201
val tree = imp.asInstanceOf [tpd.Import ]
189
202
val selections = tpd.importSelections(tree)
190
203
traverse(imp.expr)
191
204
selections.foreach(traverse)
205
+ case utree : untpd.ValOrDefDef if tree.hasType =>
206
+ handle(utree)
207
+ if (include.isLocal) traverseChildren(tree)
192
208
case utree : untpd.NameTree if tree.hasType =>
193
- val tree = utree.asInstanceOf [tpd.NameTree ]
194
- if (tree.symbol.exists
195
- && ! tree.symbol.is(Synthetic )
196
- && tree.pos.exists
197
- && ! tree.pos.isZeroExtent
198
- && (include.isReferences || isDefinition(tree))
199
- && treePredicate(tree))
200
- buf += SourceTree (tree, source)
209
+ handle(utree)
201
210
traverseChildren(tree)
202
211
case tree : untpd.Inlined =>
203
212
traverse(tree.call)
@@ -228,8 +237,7 @@ object Interactive {
228
237
)(implicit ctx : Context ): List [SourceTree ] = {
229
238
val linkedSym = symbol.linkedClass
230
239
val fullPredicate : NameTree => Boolean = tree =>
231
- ( ! tree.symbol.isPrimaryConstructor
232
- && (includes.isDefinitions || ! Interactive .isDefinition(tree))
240
+ ( (includes.isDefinitions || ! Interactive .isDefinition(tree))
233
241
&& ( Interactive .matchSymbol(tree, symbol, includes)
234
242
|| ( includes.isLinkedClass
235
243
&& linkedSym.exists
@@ -329,6 +337,7 @@ object Interactive {
329
337
def findDefinitions (path : List [Tree ], pos : SourcePosition , driver : InteractiveDriver )(implicit ctx : Context ): List [SourceTree ] = {
330
338
enclosingSourceSymbols(path, pos).flatMap { sym =>
331
339
val enclTree = enclosingTree(path)
340
+ val includeLocal = if (sym.exists && sym.isLocal) Include .local else Include .empty
332
341
333
342
val (trees, include) =
334
343
if (enclTree.isInstanceOf [MemberDef ])
@@ -347,7 +356,7 @@ object Interactive {
347
356
(Nil , Include .empty)
348
357
}
349
358
350
- findTreesMatching(trees, include, sym)
359
+ findTreesMatching(trees, include | includeLocal , sym)
351
360
}
352
361
}
353
362
0 commit comments