Skip to content

Commit 31935f9

Browse files
committed
IDE: Factor out logic to find references
1 parent 7ee4855 commit 31935f9

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

compiler/src/dotty/tools/dotc/interactive/Interactive.scala

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ object Interactive {
2525
type Set = Int
2626
val overridden = 1 // include trees whose symbol is overridden by `sym`
2727
val overriding = 2 // include trees whose symbol overrides `sym` (but for performance only in same source file)
28-
val references = 4 // include references and not just definitions
28+
val references = 4 // include references
29+
val definitions = 8 // include definitions
30+
val linkedClass = 16 // include `symbol.linkedClass`
2931
}
3032

3133
/** Does this tree define a symbol ? */
@@ -299,6 +301,35 @@ object Interactive {
299301
buf.toList
300302
}
301303

304+
/**
305+
* Find trees that match `symbol` in `trees`.
306+
*
307+
* @param trees The trees to inspect.
308+
* @param includes Whether to include references, definitions, etc.
309+
* @param symbol The symbol for which we want to find references.
310+
*/
311+
def findTreesMatching(trees: List[SourceTree],
312+
includes: Include.Set,
313+
symbol: Symbol)(implicit ctx: Context): List[SourceTree] = {
314+
val linkedSym = symbol.linkedClass
315+
val includeReferences = (includes & Include.references) != 0
316+
val includeDeclaration = (includes & Include.definitions) != 0
317+
val includeLinkedClass = (includes & Include.linkedClass) != 0
318+
val predicate: NameTree => Boolean = tree =>
319+
( tree.pos.isSourceDerived
320+
&& !tree.symbol.isConstructor
321+
&& (includeDeclaration || !Interactive.isDefinition(tree))
322+
&& ( Interactive.matchSymbol(tree, symbol, includes)
323+
|| ( includeDeclaration
324+
&& includeLinkedClass
325+
&& linkedSym.exists
326+
&& Interactive.matchSymbol(tree, linkedSym, includes)
327+
)
328+
)
329+
)
330+
namedTrees(trees, includeReferences, predicate)
331+
}
332+
302333
/** The reverse path to the node that closest encloses position `pos`,
303334
* or `Nil` if no such path exists. If a non-empty path is returned it starts with
304335
* the tree closest enclosing `pos` and ends with an element of `trees`.

language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ class DottyLanguageServer extends LanguageServer
273273
val driver = driverFor(uri)
274274
implicit val ctx = driver.currentCtx
275275

276-
val includeDeclaration = params.getContext.isIncludeDeclaration
277276
val pos = sourcePosition(driver, uri, params.getPosition)
278277
val sym = Interactive.enclosingSourceSymbol(driver.openedTrees(uri), pos)
279278

@@ -283,11 +282,10 @@ class DottyLanguageServer extends LanguageServer
283282
// only need to look for trees in the target directory if the symbol is defined in the
284283
// current project
285284
val trees = driver.allTreesContaining(sym.name.sourceModuleName.toString)
286-
val refs = Interactive.namedTrees(trees, includeReferences = true, tree =>
287-
tree.pos.isSourceDerived
288-
&& (includeDeclaration || !Interactive.isDefinition(tree))
289-
&& !tree.symbol.isConstructor
290-
&& (Interactive.matchSymbol(tree, sym, Include.overriding)))
285+
val includeDeclaration = params.getContext.isIncludeDeclaration
286+
val includes =
287+
Include.references | Include.overriding | (if (includeDeclaration) Include.definitions else 0)
288+
val refs = Interactive.findTreesMatching(trees, includes, sym)
291289

292290
refs.map(ref => location(ref.namePos)).asJava
293291
}
@@ -304,14 +302,10 @@ class DottyLanguageServer extends LanguageServer
304302
if (sym == NoSymbol) new WorkspaceEdit()
305303
else {
306304
val trees = driver.allTreesContaining(sym.name.sourceModuleName.toString)
307-
val linkedSym = sym.linkedClass
308305
val newName = params.getNewName
309-
310-
val refs = Interactive.namedTrees(trees, includeReferences = true, tree =>
311-
tree.pos.isSourceDerived
312-
&& !tree.symbol.isConstructor
313-
&& (Interactive.matchSymbol(tree, sym, Include.overriding)
314-
|| (linkedSym != NoSymbol && Interactive.matchSymbol(tree, linkedSym, Include.overriding))))
306+
val includes =
307+
Include.references | Include.definitions | Include.linkedClass | Include.overriding
308+
val refs = Interactive.findTreesMatching(trees, includes, sym)
315309

316310
val changes = refs.groupBy(ref => toUri(ref.source).toString).mapValues(_.map(ref => new TextEdit(range(ref.namePos), newName)).asJava)
317311

0 commit comments

Comments
 (0)