Skip to content

Commit f55b01c

Browse files
committed
feat: add in an action for missing empty argument list
1 parent 4f5ae4c commit f55b01c

File tree

4 files changed

+31
-8
lines changed

4 files changed

+31
-8
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import cc.CaptureSet.IdentityCaptRefMap
3232
import dotty.tools.dotc.rewrites.Rewrites.ActionPatch
3333
import dotty.tools.dotc.util.Spans.Span
3434
import dotty.tools.dotc.util.SourcePosition
35+
import scala.jdk.CollectionConverters.*
3536

3637
/** Messages
3738
* ========
@@ -1858,8 +1859,6 @@ class OnlyFunctionsCanBeFollowedByUnderscore(tp: Type, tree: untpd.PostfixOp)(us
18581859

18591860
override def actions(using Context) =
18601861
val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree: @unchecked
1861-
import scala.language.unsafeNulls
1862-
import scala.jdk.CollectionConverters.*
18631862
List(
18641863
CodeAction(title = "Rewrite to function value",
18651864
description = java.util.Optional.empty(),
@@ -1871,7 +1870,7 @@ class OnlyFunctionsCanBeFollowedByUnderscore(tp: Type, tree: untpd.PostfixOp)(us
18711870
).asJava
18721871
}
18731872

1874-
class MissingEmptyArgumentList(method: String)(using Context)
1873+
class MissingEmptyArgumentList(method: String, tree: tpd.Tree)(using Context)
18751874
extends SyntaxMsg(MissingEmptyArgumentListID) {
18761875
def msg(using Context) = i"$method must be called with ${hl("()")} argument"
18771876
def explain(using Context) = {
@@ -1886,6 +1885,16 @@ class MissingEmptyArgumentList(method: String)(using Context)
18861885
|In Dotty, this idiom is an error. The application syntax has to follow exactly the parameter syntax.
18871886
|Excluded from this rule are methods that are defined in Java or that override methods defined in Java."""
18881887
}
1888+
1889+
override def actions(using Context) =
1890+
List(
1891+
CodeAction(title = "Insert ()",
1892+
description = java.util.Optional.empty(),
1893+
patches = List(
1894+
ActionPatch(SourcePosition(tree.source, tree.span.endPos), "()"),
1895+
).asJava
1896+
)
1897+
).asJava
18891898
}
18901899

18911900
class DuplicateNamedTypeParameter(name: Name)(using Context)

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ object ErrorReporting {
5555
val meth = err.exprStr(methPart(tree))
5656
val info = if tree.symbol.exists then tree.symbol.info else mt
5757
if isCallableWithSingleEmptyArgumentList(info) then
58-
report.error(MissingEmptyArgumentList(meth), tree.srcPos)
58+
report.error(MissingEmptyArgumentList(meth, tree), tree.srcPos)
5959
else
6060
report.error(MissingArgumentList(meth, tree.symbol), tree.srcPos)
6161

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3953,7 +3953,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
39533953
def isAutoApplied(sym: Symbol): Boolean =
39543954
sym.isConstructor
39553955
|| sym.matchNullaryLoosely
3956-
|| Feature.warnOnMigration(MissingEmptyArgumentList(sym.show), tree.srcPos, version = `3.0`)
3956+
|| Feature.warnOnMigration(MissingEmptyArgumentList(sym.show, tree), tree.srcPos, version = `3.0`)
39573957
&& { patch(tree.span.endPos, "()"); true }
39583958

39593959
/** If this is a selection prototype of the form `.apply(...): R`, return the nested

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ class CodeActionTest extends DottyTest:
3030
|""".stripMargin
3131
)
3232

33+
@Test def insertBracesForEmptyArgument =
34+
checkCodeAction(
35+
"""|object Test:
36+
| def foo(): Unit = ()
37+
| val x = foo
38+
|""".stripMargin,
39+
"Insert ()",
40+
"""|object Test:
41+
| def foo(): Unit = ()
42+
| val x = foo()
43+
|""".stripMargin
44+
45+
)
46+
3347
// Make sure we're not using the default reporter, which is the ConsoleReporter,
3448
// meaning they will get reported in the test run and that's it.
3549
private def newContext =
@@ -41,11 +55,11 @@ class CodeActionTest extends DottyTest:
4155
val source = SourceFile.virtual("test", code).content
4256
val runCtx = checkCompile("typer", code) { (_, _) => () }
4357
val diagnostics = runCtx.reporter.removeBufferedMessages
44-
assertEquals(diagnostics.size, 1)
58+
assertEquals(1, diagnostics.size)
4559

4660
val diagnostic = diagnostics.head
4761
val actions = diagnostic.msg.actions.asScala.toList
48-
assertEquals(actions.size, 1)
62+
assertEquals(1, actions.size)
4963

5064
// TODO account for more than 1 action
5165
val action = actions.head
@@ -80,4 +94,4 @@ class CodeActionTest extends DottyTest:
8094
assert(outNew == result.length, s"$outNew != ${result.length}")
8195

8296
loop(patches, 0, 0)
83-
assertEquals(result.mkString, expected)
97+
assertEquals(expected, result.mkString)

0 commit comments

Comments
 (0)