Skip to content

Commit c5b85a3

Browse files
committed
improvement: Allow passing -explain to the presentation compiler
1 parent ba45875 commit c5b85a3

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

presentation-compiler/src/main/dotty/tools/pc/DiagnosticProvider.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import scala.jdk.CollectionConverters.*
1515
import scala.meta.pc.VirtualFileParams
1616

1717
class DiagnosticProvider(driver: InteractiveDriver, params: VirtualFileParams):
18-
1918
def diagnostics(): List[lsp4j.Diagnostic] =
2019
if params.shouldReturnDiagnostics then
2120
val diags = driver.run(params.uri().nn, params.text().nn)
@@ -25,9 +24,13 @@ class DiagnosticProvider(driver: InteractiveDriver, params: VirtualFileParams):
2524

2625
private def toLsp(diag: Diagnostic)(using Context): Option[lsp4j.Diagnostic] =
2726
Option.when(diag.pos.exists):
27+
val message =
28+
if Diagnostic.shouldExplain(diag) then
29+
diag.msg.message + "\n\n# Explanation (enabled by `-explain`)\n\n" + diag.msg.explanation
30+
else diag.msg.message
2831
val lspDiag = lsp4j.Diagnostic(
2932
diag.pos.toLsp,
30-
diag.msg.message,
33+
message,
3134
toDiagnosticSeverity(diag.level),
3235
"presentation compiler",
3336
)

presentation-compiler/test/dotty/tools/pc/tests/DiagnosticProviderSuite.scala

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import org.eclipse.lsp4j.CodeAction
1919
class DiagnosticProviderSuite extends PcAssertions {
2020
case class TestDiagnostic(startIndex: Int, endIndex: Int, msg: String, severity: DiagnosticSeverity)
2121

22-
val pc = RawScalaPresentationCompiler().newInstance("", TestResources.classpath.asJava, Nil.asJava)
22+
val pc = RawScalaPresentationCompiler().newInstance("", TestResources.classpath.asJava, List("-explain").asJava)
2323

2424
case class TestVirtualFileParams(uri: URI, text: String) extends VirtualFileParams {
2525
override def shouldReturnDiagnostics: Boolean = true
@@ -45,6 +45,47 @@ class DiagnosticProviderSuite extends PcAssertions {
4545
| Int.maaxValue
4646
|""".stripMargin,
4747
List(TestDiagnostic(12,25, "value maaxValue is not a member of object Int - did you mean Int.MaxValue?", DiagnosticSeverity.Error))
48+
)
49+
50+
@Test def error1 =
51+
check(
52+
"""|object C:
53+
| def m(x: Int) = 1
54+
| object T extends K:
55+
| val x = m(1) // error
56+
|class K:
57+
| def m(i: Int) = 2
58+
|""".stripMargin,
59+
List(
60+
TestDiagnostic(
61+
64,65,
62+
"""|Reference to m is ambiguous.
63+
|It is both defined in object C
64+
|and inherited subsequently in object T
65+
|
66+
|# Explanation (enabled by `-explain`)
67+
|
68+
|The identifier m is ambiguous because a name binding of lower precedence
69+
|in an inner scope cannot shadow a binding with higher precedence in
70+
|an outer scope.
71+
|
72+
|The precedence of the different kinds of name bindings, from highest to lowest, is:
73+
| - Definitions in an enclosing scope
74+
| - Inherited definitions and top-level definitions in packages
75+
| - Names introduced by import of a specific name
76+
| - Names introduced by wildcard import
77+
| - Definitions from packages in other files
78+
|Note:
79+
| - As a rule, definitions take precedence over imports.
80+
| - Definitions in an enclosing scope take precedence over inherited definitions,
81+
| which can result in ambiguities in nested classes.
82+
| - When importing, you can avoid naming conflicts by renaming:
83+
| import scala.{m => mTick}
84+
|""".stripMargin,
85+
DiagnosticSeverity.Error
86+
87+
)
88+
)
4889
)
4990

5091
@Test def warning =

0 commit comments

Comments
 (0)