Skip to content

Commit

Permalink
fix: convert to named args for extends
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Jun 27, 2024
1 parent 5a05ecf commit 13f7ed7
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package scala.meta.internal.metals.codeactions
import scala.concurrent.ExecutionContext
import scala.concurrent.Future

import scala.meta.Init
import scala.meta.Term
import scala.meta.Tree
import scala.meta.XtensionSyntax
Expand Down Expand Up @@ -57,7 +58,7 @@ class ConvertToNamedArguments(
}

def getTermWithArgs(
apply: Term,
apply: Tree,
args: List[Tree],
nameEnd: Int,
): Option[ApplyTermWithArgIndices] = {
Expand Down Expand Up @@ -85,14 +86,14 @@ class ConvertToNamedArguments(
term match {
case Some(apply: Term.Apply) =>
getTermWithArgs(apply, apply.args, apply.fun.pos.end)
case Some(newAppl @ Term.New(init)) =>
getTermWithArgs(newAppl, init.argss.flatten, init.name.pos.end)
case Some(init: Init) =>
getTermWithArgs(init, init.argss.flatten, init.name.pos.end)
case Some(t) => firstApplyWithUnnamedArgs(t.parent)
case _ => None
}
}

private def methodName(t: Term, isFirst: Boolean = false): String = {
private def methodName(t: Tree, isFirst: Boolean = false): String = {
t match {
// a.foo(a)
case Term.Select(_, name) =>
Expand All @@ -106,7 +107,7 @@ class ConvertToNamedArguments(
// foo(a)
case Term.Name(name) =>
name
case Term.New(init) =>
case init: Init =>
init.tpe.syntax + "(...)"
case _ =>
t.syntax
Expand All @@ -119,14 +120,14 @@ class ConvertToNamedArguments(

val path = params.getTextDocument().getUri().toAbsolutePath
val range = params.getRange()
def predicate(t: Term): Boolean =
def predicate(t: Tree): Boolean =
t match {
case Term.Apply(fun, _) => !fun.pos.encloses(range)
case Term.New(init) => init.pos.encloses(range)
case _: Init => true
case _ => false
}
val maybeApply = for {
term <- trees.findLastEnclosingAt[Term](
term <- trees.findLastEnclosingAt[Tree](
path,
range.getStart(),
term => predicate(term),
Expand Down Expand Up @@ -165,7 +166,7 @@ class ConvertToNamedArguments(
}

object ConvertToNamedArguments {
case class ApplyTermWithArgIndices(app: Term, argIndices: List[Int])
case class ApplyTermWithArgIndices(app: Tree, argIndices: List[Int])
def title(funcName: String): String =
s"Convert '$funcName' to named arguments"
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,25 @@ final class ConvertToNamedArgumentsProvider(
fun.symbol,
makeTextEdits(fun.tpe.params, args, fun.pos.end, app.pos.end - 1)
)
// class A extends <<B(1)>>
// this is a workaround case, since the position seems to off by one here
case Template(
_,
_,
List(DefDef(_, _, _, _, _, Block(List(app @ Apply(fun, args)), _)))
)
if fun.symbol != null && !fun.symbol.isJava && app.pos.includes(
unit.position(params.offset - 1)
) =>
handleWithJavaFilter(
fun.symbol,
makeTextEdits(
fun.tpe.params,
args,
fun.pos.end + 1,
app.pos.end
)
)
case _ => Right(Nil)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,64 @@ class ConvertToNamedArgumentsSuite extends BaseCodeActionSuite {
|""".stripMargin
)

checkEdit(
"extends",
"""|abstract class AAA(a: Int)
|
|class B extends <<AAA(2)>>
|""".stripMargin,
List(0),
"""|abstract class AAA(a: Int)
|
|class B extends AAA(a = 2)
|""".stripMargin
)

checkEdit(
"extends-ugly-formatting",
"""|abstract class A(a: Int)
|
|class B
| extends <<A (2)>>
|""".stripMargin,
List(0),
"""|abstract class A(a: Int)
|
|class B
| extends A (a = 2)
|""".stripMargin
)

checkEdit(
"extends1".tag(IgnoreScala2),
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends <<A(2)>> with C(4)
|""".stripMargin,
List(0),
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends A(a = 2) with C(4)
|""".stripMargin
)

checkEdit(
"extends2".tag(IgnoreScala2),
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends A(2) with <<C(4)>>
|""".stripMargin,
List(0),
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends A(2) with C(c = 4)
|""".stripMargin
)

def checkError(
name: TestOptions,
original: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,36 @@ class Scala3CodeActionLspSuite
|""".stripMargin,
)

check(
"convert-to-named-args-extends-1",
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends A<<(>>2) with C(4)
|""".stripMargin,
s"${ConvertToNamedArguments.title("A(...)")}",
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends A(a = 2) with C(4)
|""".stripMargin,
)

check(
"convert-to-named-args-extends-2",
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends A(2) with C<<(>>4)
|""".stripMargin,
s"${ConvertToNamedArguments.title("C(...)")}",
"""|abstract class A(a: Int)
|trait C(c: Int)
|
|class B extends A(2) with C(c = 4)
|""".stripMargin,
)

private def getPath(name: String) = s"a/src/main/scala/a/$name"

def checkExtractedMember(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,19 @@ class ConvertToNamedArgumentsLspSuite
filterAction = filterAction,
)

check(
"extends",
"""|abstract class A(a: Int)
|
|class B extends A(<<2>>)
|""".stripMargin,
s"${ConvertToNamedArguments.title("A(...)")}",
"""|abstract class A(a: Int)
|
|class B extends A(a = 2)
|""".stripMargin,
)

checkNoAction(
"cursor-outside-func",
"""|object Something {
Expand Down

0 comments on commit 13f7ed7

Please sign in to comment.