Skip to content

Commit 4f88a96

Browse files
committed
IDE: Look for overrides in the whole project
When doing go-to-definition, we used to look for symbols that override the symbol selected for go to definition only in the same source file as the one that was selected. This commit changes that, as suggested in the review of scala#5208.
1 parent 2b84d7c commit 4f88a96

File tree

3 files changed

+58
-29
lines changed

3 files changed

+58
-29
lines changed

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

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ object Interactive {
4343
/** Include trees whose symbol is overridden by `sym` */
4444
val overridden: Set = Set(1 << 0)
4545

46-
/**
47-
* Include trees whose symbol overrides `sym` (but for performance only in same source
48-
* file)
49-
*/
46+
/** Include trees whose symbol overrides `sym` */
5047
val overriding: Set = Set(1 << 1)
5148

5249
/** Include references */
@@ -328,34 +325,45 @@ object Interactive {
328325
path.find(_.isInstanceOf[DefTree]).getOrElse(EmptyTree)
329326

330327
/**
331-
* Find the definitions of the symbol at the end of `path`.
328+
* Find the definitions of the symbol at the end of `path`. In the case of an import node,
329+
* all imported symbols will be considered.
332330
*
333331
* @param path The path to the symbol for which we want the definitions.
334332
* @param driver The driver responsible for `path`.
335333
* @return The definitions for the symbol at the end of `path`.
336334
*/
337-
def findDefinitions(path: List[Tree], pos: SourcePosition, driver: InteractiveDriver)(implicit ctx: Context): List[SourceTree] = {
338-
enclosingSourceSymbols(path, pos).flatMap { sym =>
339-
val enclTree = enclosingTree(path)
340-
val includeLocal = if (sym.exists && sym.isLocal) Include.local else Include.empty
341-
342-
val (trees, include) =
343-
if (enclTree.isInstanceOf[MemberDef])
344-
(driver.allTreesContaining(sym.name.sourceModuleName.toString),
345-
Include.definitions | Include.overriding | Include.overridden)
346-
else sym.topLevelClass match {
347-
case cls: ClassSymbol =>
348-
val trees = Option(cls.sourceFile).flatMap(InteractiveDriver.toUriOption) match {
349-
case Some(uri) if driver.openedTrees.contains(uri) =>
350-
driver.openedTrees(uri)
351-
case _ => // Symbol comes from the classpath
352-
SourceTree.fromSymbol(cls).toList
353-
}
354-
(trees, Include.definitions | Include.overriding)
355-
case _ =>
356-
(Nil, Include.empty)
357-
}
335+
def findDefinitions(path: List[Tree], pos: SourcePosition, driver: InteractiveDriver): List[SourceTree] = {
336+
implicit val ctx = driver.currentCtx
337+
val enclTree = enclosingTree(path)
338+
val includeOverridden = enclTree.isInstanceOf[MemberDef]
339+
val symbols = enclosingSourceSymbols(path, pos)
340+
val includeExternal = symbols.exists(!_.isLocal)
341+
findDefinitions(symbols, driver, includeOverridden, includeExternal)
342+
}
358343

344+
/**
345+
* Find the definitions of `symbols`.
346+
*
347+
* @param symbols The list of symbols for which to find a definition.
348+
* @param driver The driver responsible for the given symbols.
349+
* @param includeOverridden If true, also include the symbols overridden by any of `symbols`.
350+
* @param includeExternal If true, also look for definitions on the classpath.
351+
* @return The definitions for the symbols in `symbols`, and if `includeOverridden` is set, the
352+
* definitions for the symbols that they override.
353+
*/
354+
def findDefinitions(symbols: List[Symbol],
355+
driver: InteractiveDriver,
356+
includeOverridden: Boolean,
357+
includeExternal: Boolean): List[SourceTree] = {
358+
implicit val ctx = driver.currentCtx
359+
val include = Include.definitions | Include.overriding |
360+
(if (includeOverridden) Include.overridden else Include.empty)
361+
symbols.flatMap { sym =>
362+
val name = sym.name.sourceModuleName.toString
363+
val includeLocal = if (sym.exists && sym.isLocal) Include.local else Include.empty
364+
val trees =
365+
if (includeExternal) driver.allTreesContaining(name)
366+
else driver.sourceTreesContaining(name)
359367
findTreesMatching(trees, include | includeLocal, sym)
360368
}
361369
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,9 @@ class DottyLanguageServer extends LanguageServer
289289
/*isIncomplete = */ false, items.map(completionItem).asJava))
290290
}
291291

292-
/** If cursor is on a reference, show its definition and all overriding definitions in
293-
* the same source as the primary definition.
292+
/** If cursor is on a reference, show its definition and all overriding definitions.
294293
* If cursor is on a definition, show this definition together with all overridden
295-
* and overriding definitions (in all sources).
294+
* and overriding definitions.
296295
*/
297296
override def definition(params: TextDocumentPositionParams) = computeAsync { cancelToken =>
298297
val uri = new URI(params.getTextDocument.getUri)

language-server/test/dotty/tools/languageserver/DefinitionTest.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,4 +322,26 @@ class DefinitionTest {
322322
.definition(m11 to m12, List(m3 to m4))
323323
}
324324

325+
@Test def definitionShowOverrides: Unit = {
326+
withSources(
327+
code"""class A { def ${m1}foo${m2}: Int = 0 }""",
328+
code"""class B extends A { def ${m3}foo${m4}: Int = 1 }""",
329+
code"""class C extends A { def ${m5}foo${m6}: Int = 2 }""",
330+
code"""class D extends C { def ${m7}foo${m8}: Int = 3 }""",
331+
code"""object O {
332+
val a = new A().${m9}foo${m10}
333+
val b = new B().${m11}foo${m12}
334+
val c = new C().${m13}foo${m14}
335+
val d = new D().${m15}foo${m16}
336+
}"""
337+
).definition(m1 to m2, List(m1 to m2, m3 to m4, m5 to m6, m7 to m8))
338+
.definition(m3 to m4, List(m1 to m2, m3 to m4))
339+
.definition(m5 to m6, List(m1 to m2, m5 to m6, m7 to m8))
340+
.definition(m7 to m8, List(m1 to m2, m5 to m6, m7 to m8))
341+
.definition(m9 to m10, List(m1 to m2, m3 to m4, m5 to m6, m7 to m8))
342+
.definition(m11 to m12, List(m3 to m4))
343+
.definition(m13 to m14, List(m5 to m6, m7 to m8))
344+
.definition(m15 to m16, List(m7 to m8))
345+
}
346+
325347
}

0 commit comments

Comments
 (0)