@@ -8,6 +8,7 @@ import scala.collection._
88import ast .{NavigateAST , Trees , tpd , untpd }
99import core ._ , core .Decorators .{sourcePos => _ , _ }
1010import Contexts ._ , Flags ._ , Names ._ , NameOps ._ , Symbols ._ , Trees ._ , Types ._
11+ import transform .SymUtils .decorateSymbol
1112import util .Positions ._ , util .SourceFile , util .SourcePosition
1213import core .Denotations .SingleDenotation
1314import NameKinds .SimpleNameKind
@@ -33,6 +34,7 @@ object Interactive {
3334 def isDefinitions : Boolean = (bits & definitions.bits) != 0
3435 def isLinkedClass : Boolean = (bits & linkedClass.bits) != 0
3536 def isImports : Boolean = (bits & imports.bits) != 0
37+ def isLocal : Boolean = (bits & local.bits) != 0
3638 }
3739
3840 /** The empty set */
@@ -59,6 +61,9 @@ object Interactive {
5961 /** Include imports in the results */
6062 val imports : Set = Set (1 << 5 )
6163
64+ /** Include local symbols, inspect local trees */
65+ val local : Set = Set (1 << 6 )
66+
6267 /** All the flags */
6368 val all : Set = Set (~ 0 )
6469 }
@@ -164,40 +169,44 @@ object Interactive {
164169 else
165170 namedTrees(trees, include, matchSymbol(_, sym, include))
166171
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-
175172 /** Find named trees with a non-empty position satisfying `treePredicate` in `trees`.
176173 *
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`.
178178 */
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 {
181183 val buf = new mutable.ListBuffer [SourceTree ]
182184
183185 def traverser (source : SourceFile ) = {
184186 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+ }
185198 override def traverse (tree : untpd.Tree )(implicit ctx : Context ) = {
186199 tree match {
187200 case imp : untpd.Import if include.isImports && tree.hasType =>
188201 val tree = imp.asInstanceOf [tpd.Import ]
189202 val selections = tpd.importSelections(tree)
190203 traverse(imp.expr)
191204 selections.foreach(traverse)
205+ case utree : untpd.ValOrDefDef if tree.hasType =>
206+ handle(utree)
207+ if (include.isLocal) traverseChildren(tree)
192208 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)
201210 traverseChildren(tree)
202211 case tree : untpd.Inlined =>
203212 traverse(tree.call)
@@ -228,8 +237,7 @@ object Interactive {
228237 )(implicit ctx : Context ): List [SourceTree ] = {
229238 val linkedSym = symbol.linkedClass
230239 val fullPredicate : NameTree => Boolean = tree =>
231- ( ! tree.symbol.isPrimaryConstructor
232- && (includes.isDefinitions || ! Interactive .isDefinition(tree))
240+ ( (includes.isDefinitions || ! Interactive .isDefinition(tree))
233241 && ( Interactive .matchSymbol(tree, symbol, includes)
234242 || ( includes.isLinkedClass
235243 && linkedSym.exists
@@ -329,6 +337,7 @@ object Interactive {
329337 def findDefinitions (path : List [Tree ], pos : SourcePosition , driver : InteractiveDriver )(implicit ctx : Context ): List [SourceTree ] = {
330338 enclosingSourceSymbols(path, pos).flatMap { sym =>
331339 val enclTree = enclosingTree(path)
340+ val includeLocal = if (sym.exists && sym.isLocal) Include .local else Include .empty
332341
333342 val (trees, include) =
334343 if (enclTree.isInstanceOf [MemberDef ])
@@ -347,7 +356,7 @@ object Interactive {
347356 (Nil , Include .empty)
348357 }
349358
350- findTreesMatching(trees, include, sym)
359+ findTreesMatching(trees, include | includeLocal , sym)
351360 }
352361 }
353362
0 commit comments