Skip to content

Commit f952dd2

Browse files
committed
First draft of add nn quick fix
1 parent 97896fa commit f952dd2

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ extends NotFoundMsg(MissingIdentID) {
300300
class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tree], addenda: => String*)(using Context)
301301
extends TypeMismatchMsg(found, expected)(TypeMismatchID):
302302

303+
private var shouldSuggestNN = false
304+
// Ensures that shouldSuggestNN will always be correctly computed before `actions` is called
305+
msg
306+
303307
def msg(using Context) =
304308
// replace constrained TypeParamRefs and their typevars by their bounds where possible
305309
// and the bounds are not f-bounds.
@@ -344,6 +348,7 @@ class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tre
344348
val (found2, expected2) =
345349
if (found1 frozen_<:< expected1) || reported.fbounded then (found, expected)
346350
else (found1, expected1)
351+
if found2 frozen_<:< OrNull(expected) then shouldSuggestNN = true
347352
val (foundStr, expectedStr) = Formatting.typeDiff(found2.normalized, expected2.normalized)
348353
i"""|Found: $foundStr
349354
|Required: $expectedStr${reported.notes}"""
@@ -360,6 +365,28 @@ class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tre
360365
val treeStr = inTree.map(x => s"\nTree:\n\n${x.show}\n").getOrElse("")
361366
treeStr + "\n" + super.explain
362367

368+
override def actions(using Context) =
369+
if shouldSuggestNN then
370+
inTree match {
371+
case Some(tree) if tree != null =>
372+
val content = tree.source.content().slice(tree.srcPos.startPos.start, tree.srcPos.endPos.end).mkString
373+
val replacement = tree match
374+
case a @ Apply(fun, args) => "(" + content + ").nn"
375+
case _ => content
376+
List(
377+
CodeAction(title = """Add .nn""",
378+
description = None,
379+
patches = List(
380+
ActionPatch(tree.srcPos.sourcePos, replacement)
381+
)
382+
)
383+
)
384+
case _ =>
385+
List()
386+
}
387+
else
388+
List()
389+
363390
end TypeMismatch
364391

365392
class NotAMember(site: Type, val name: Name, selected: String, proto: Type, addendum: => String = "")(using Context)

compiler/test/dotty/tools/dotc/reporting/CodeActionTest.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ class CodeActionTest extends DottyTest:
179179
ctxx = ctxx
180180
)
181181

182+
@Test def addNN =
183+
val ctxx = newContext
184+
ctxx.setSetting(ctxx.settings.YexplicitNulls, true)
185+
checkCodeAction(
186+
code =
187+
"""val s: String|Null = ???
188+
| val t: String = s""".stripMargin,
189+
title = "Add .nn",
190+
expected =
191+
"""val s: String|Null = ???
192+
| val t: String = (s).nn""".stripMargin,
193+
ctxx = ctxx
194+
)
195+
182196
// Make sure we're not using the default reporter, which is the ConsoleReporter,
183197
// meaning they will get reported in the test run and that's it.
184198
private def newContext =

0 commit comments

Comments
 (0)