From 6ba8f4729952ed6cc9a8691f5a1cb3f525a6ca8f Mon Sep 17 00:00:00 2001 From: scarf Date: Sat, 23 Nov 2024 15:57:49 +0900 Subject: [PATCH 1/2] feat: implement `Convert to collect` code action --- docs/features/code-actions.md | 6 + docs/features/gifs/FilterMapToCollect.gif | Bin 0 -> 71213 bytes .../codeactions/CodeActionProvider.scala | 1 + .../FilterMapToCollectCodeAction.scala | 155 ++++++++++ .../FilterMapToCollectCodeActionSuite.scala | 277 ++++++++++++++++++ 5 files changed, 439 insertions(+) create mode 100644 docs/features/gifs/FilterMapToCollect.gif create mode 100644 metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala create mode 100644 tests/unit/src/test/scala/tests/codeactions/FilterMapToCollectCodeActionSuite.scala diff --git a/docs/features/code-actions.md b/docs/features/code-actions.md index a6aca9559c8..5095141d1a4 100644 --- a/docs/features/code-actions.md +++ b/docs/features/code-actions.md @@ -55,6 +55,12 @@ It converts a chain of `map`, `flatMap`, `filter` and `filterNot` methods into a ![To For Comprehension](./gifs/FlatMapToForComprehension.gif) +## filter then map to collect + +It converts a chain of `filter` and `map` methods into a `collect` method. + +![To Collect](./gifs/FilterMapToCollect.gif) + ## Implement Abstract Members of the Parent Type Upon inheriting from a type, you also have to implement its abstract members. But manually looking them all up and copying their signature is time consuming, isn't it? You can just use this code action instead. diff --git a/docs/features/gifs/FilterMapToCollect.gif b/docs/features/gifs/FilterMapToCollect.gif new file mode 100644 index 0000000000000000000000000000000000000000..24601f2b7ec3a34a26d48d64b686b75f89d0bb06 GIT binary patch literal 71213 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 t0t)C%69*fobnctTd57b$|M|!@{Re0)(ntUR literal 0 HcmV?d00001 diff --git a/metals/src/main/scala/scala/meta/internal/metals/codeactions/CodeActionProvider.scala b/metals/src/main/scala/scala/meta/internal/metals/codeactions/CodeActionProvider.scala index 5ed5356e5e3..97d1c6f3f5d 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/codeactions/CodeActionProvider.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/codeactions/CodeActionProvider.scala @@ -43,6 +43,7 @@ final class CodeActionProvider( new InlineValueCodeAction(trees, compilers, languageClient), new ConvertToNamedArguments(trees, compilers), new FlatMapToForComprehensionCodeAction(trees, buffers), + new FilterMapToCollectCodeAction(trees), new MillifyDependencyCodeAction(buffers), new MillifyScalaCliDependencyCodeAction(buffers), new ConvertCommentCodeAction(buffers), diff --git a/metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala b/metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala new file mode 100644 index 00000000000..ca7164510df --- /dev/null +++ b/metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala @@ -0,0 +1,155 @@ +package scala.meta.internal.metals.codeactions + +import scala.concurrent.ExecutionContext +import scala.concurrent.Future + +import scala.meta._ +import scala.meta.internal.metals.MetalsEnrichments._ +import scala.meta.internal.metals.codeactions.CodeAction +import scala.meta.internal.metals.codeactions.CodeActionBuilder +import scala.meta.internal.parsing.Trees +import scala.meta.pc.CancelToken + +import org.eclipse.lsp4j.CodeActionParams +import org.eclipse.{lsp4j => l} + +class FilterMapToCollectCodeAction(trees: Trees) extends CodeAction { + override def kind: String = l.CodeActionKind.RefactorRewrite + + override def contribute(params: CodeActionParams, token: CancelToken)(implicit + ec: ExecutionContext + ): Future[Seq[l.CodeAction]] = Future { + val uri = params.getTextDocument().getUri() + + val path = uri.toAbsolutePath + val range = params.getRange() + + trees + .findLastEnclosingAt[Term.Apply](path, range.getStart()) + .flatMap(findFilterMapChain) + .map(toTextEdit(_)) + .map(toCodeAction(uri, _)) + .toSeq + } + + private def toTextEdit(chain: FilterMapChain) = { + val param = chain.filterFn.params.head + val paramName = Term.Name(param.name.value) + val paramPatWithType = param.decltpe match { + case Some(tpe) => Pat.Typed(Pat.Var(paramName), tpe) + case None => Pat.Var(paramName) + } + + val collectCall = Term.Apply( + fun = Term.Select(chain.qual, Term.Name("collect")), + argClause = Term.ArgClause( + values = List( + Term.PartialFunction( + cases = List( + Case( + pat = paramPatWithType, + cond = Some(chain.filterFn.renameParam(paramName)), + body = chain.mapFn.renameParam(paramName), + ) + ) + ) + ) + ), + ) + val indented = collectCall.syntax.linesIterator.zipWithIndex + .map { + case (line, 0) => line + case (line, _) => " " + line + } + .mkString("\n") + + new l.TextEdit(chain.pos.toLsp, indented) + } + + private def toCodeAction(uri: String, textEdit: l.TextEdit): l.CodeAction = + CodeActionBuilder.build( + title = FilterMapToCollectCodeAction.title, + kind = this.kind, + changes = List(uri.toAbsolutePath -> List(textEdit)), + ) + + private implicit class FunctionOps(fn: Term.Function) { + def renameParam(to: Term.Name): Term = { + val fnParamName = fn.params.head.name.value + fn.body + .transform { case Term.Name(name) if name == fnParamName => to } + .asInstanceOf[Term] + } + } + + private def findFilterMapChain(tree: Term.Apply): Option[FilterMapChain] = { + val x = Term.Name("x") + def extractFunction(arg: Tree): Option[Term.Function] = arg match { + case fn: Term.Function => Some(fn) + case Term.Block(List(fn: Term.Function)) => extractFunction(fn) + case ref: Term.Name => { + Some( + Term.Function( + UnaryParameterList(x), + Term.Apply(ref, Term.ArgClause(List(x))), + ) + ) + } + case _ => None + } + + def findChain(tree: Term.Apply): Option[FilterMapChain] = + tree match { + case MapFunctionApply(FilterFunctionApply(base, filterArg), mapArg) => + for { + filterFn <- extractFunction(filterArg) + mapFn <- extractFunction(mapArg) + } yield FilterMapChain(tree.pos, base, filterFn, mapFn) + case _ => None + } + + findChain(tree).orElse { + // If we're inside the chain, look at our parent + tree.parent.flatMap { + // We're in a method call or function, look at parent apply + case Term.Select(_, Term.Name("map" | "filter")) | Term.Function(_) => + tree.parent + .flatMap(_.parent) + .collectFirst { case parent: Term.Apply => parent } + .flatMap(findChain) + case _ => None + } + } + } + + private object UnaryParameterList { + def unapply(tree: Tree): Option[Name] = tree match { + case Term.Param(_, name, _, _) => Some(name) + case _ => None + } + def apply(name: Name): List[Term.Param] = List( + Term.Param(Nil, name, None, None) + ) + } + + private case class FunctionApply(val name: String) { + def unapply(tree: Tree): Option[(Term, Term)] = tree match { + case Term.Apply(Term.Select(base, Term.Name(`name`)), List(args)) => + Some((base, args)) + case _ => None + } + } + private val FilterFunctionApply = new FunctionApply("filter") + private val MapFunctionApply = new FunctionApply("map") + + private case class FilterMapChain( + pos: Position, + qual: Term, + filterFn: Term.Function, + mapFn: Term.Function, + ) +} + +object FilterMapToCollectCodeAction { + val title = "Convert to collect" +} diff --git a/tests/unit/src/test/scala/tests/codeactions/FilterMapToCollectCodeActionSuite.scala b/tests/unit/src/test/scala/tests/codeactions/FilterMapToCollectCodeActionSuite.scala new file mode 100644 index 00000000000..bd386d002a3 --- /dev/null +++ b/tests/unit/src/test/scala/tests/codeactions/FilterMapToCollectCodeActionSuite.scala @@ -0,0 +1,277 @@ +package tests.codeactions + +import scala.meta.internal.metals.codeactions.FilterMapToCollectCodeAction +import scala.meta.internal.metals.codeactions.FlatMapToForComprehensionCodeAction +import scala.meta.internal.metals.codeactions.RewriteBracesParensCodeAction + +class FilterMapToCollectCodeActionSuite + extends BaseCodeActionLspSuite("filterMapToCollect") { + val simpleOutput: String = + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.collect { + | case x if x > 2 => + | x * 2 + | } + |} + |""".stripMargin + + check( + "cursor-on-filter", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.fil<<>>ter(x => x > 2).map(x => x * 2) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + simpleOutput, + selectedActionIndex = 2, + ) + + check( + "cursor-on-filter-newline", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.fil<<>>ter{ + | x => x > 2 + | }.map{ + | x => x * 2 + | } + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toParens("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + simpleOutput, + selectedActionIndex = 2, + ) + + check( + "cursor-on-map", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.filter(x => x > 2).m<<>>ap(x => x * 2) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("map")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + simpleOutput, + selectedActionIndex = 2, + ) + + check( + "higher-order-function", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | def check = (x: Int) => x > 2 + | def double = (x: Int) => x * 2 + | numbers.fil<<>>ter(check).map(double) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val numbers = List(1, 2, 3, 4) + | def check = (x: Int) => x > 2 + | def double = (x: Int) => x * 2 + | numbers.collect { + | case x if check(x) => + | double(x) + | } + |} + |""".stripMargin, + selectedActionIndex = 2, + ) + + check( + "higher-order-function-rename-filter-argument", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | def double = (x: Int) => x * 2 + | numbers.fil<<>>ter(x => x > 0).map(double) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val numbers = List(1, 2, 3, 4) + | def double = (x: Int) => x * 2 + | numbers.collect { + | case x if x > 0 => + | double(x) + | } + |} + |""".stripMargin, + selectedActionIndex = 2, + ) + + check( + "higher-order-function-rename-map-argument", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | def check = (x: Int) => x > 2 + | numbers.fil<<>>ter(check).map(y => y * 2) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val numbers = List(1, 2, 3, 4) + | def check = (x: Int) => x > 2 + | numbers.collect { + | case x if check(x) => + | x * 2 + | } + |} + |""".stripMargin, + selectedActionIndex = 2, + ) + + check( + "multiple-map-calls", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.fil<<>>ter(x => x > 2).map(x => x * 2).map(x => x * 2) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.collect { + | case x if x > 2 => + | x * 2 + | }.map(x => x * 2) + |} + |""".stripMargin, + selectedActionIndex = 2, + ) + + check( + "complex-predicate", + """|object Main { + | val users = List(("Alice", 25), ("Bob", 30)) + | users.fil<<>>ter(u => u._2 >= 18 && u._1.startsWith("A")).map(u => u._1) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val users = List(("Alice", 25), ("Bob", 30)) + | users.collect { + | case u if u._2 >= 18 && u._1.startsWith("A") => + | u._1 + | } + |} + |""".stripMargin, + selectedActionIndex = 2, + ) + + check( + "multiline-predicate", + """|object Main { + | val users = List(("Alice", 25), ("Bob", 30)) + | users + | .fil<<>>ter(u => + | u._2 >= 18 && + | u._1.startsWith("A") + | ) + | .map { u => + | // format user name into multline card + | val card = Seq( + | s"Name: ${u._1}", + | s"Age: ${u._2}", + | ) + | card.mkString("\n") + | } + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val users = List(("Alice", 25), ("Bob", 30)) + | users.collect { + | case u if u._2 >= 18 && u._1.startsWith("A") => + | val card = Seq(s"Name: ${ + | u._1 + | }", s"Age: ${ + | u._2 + | }") + | card.mkString("\n") + | } + |} + |""".stripMargin, + selectedActionIndex = 2, + ) + + check( + "multiline-predicate-block", + """|object Main { + | val users = List(("Alice", 25), ("Bob", 30)) + | users + | .fil<<>>ter { u => + | val nameLength = u._1.length + | + | nameLength > 3 + | } + | .map { u => u._2 } + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toParens("map")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val users = List(("Alice", 25), ("Bob", 30)) + | users.collect { + | case u if { + | val nameLength = u._1.length + | nameLength > 3 + | } => + | u._2 + | } + |} + |""".stripMargin, + selectedActionIndex = 2, + ) + + check( + "with-type-annotations", + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.fil<<>>ter((x: Int) => x > 2).map((x: Int) => x * 2) + |} + |""".stripMargin, + s"""|${RewriteBracesParensCodeAction.toBraces("filter")} + |${FlatMapToForComprehensionCodeAction.flatMapToForComprehension} + |${FilterMapToCollectCodeAction.title} + |""".stripMargin, + """|object Main { + | val numbers = List(1, 2, 3, 4) + | numbers.collect { + | case x: Int if x > 2 => + | x * 2 + | } + |} + |""".stripMargin, + selectedActionIndex = 2, + ) +} From 5c4d2a76fead43bfe639981674a3e0e09bd0d588 Mon Sep 17 00:00:00 2001 From: scarf Date: Sat, 30 Nov 2024 14:11:25 +0900 Subject: [PATCH 2/2] perf: migrate to `codeAction/resolve` --- .../FilterMapToCollectCodeAction.scala | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala b/metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala index ca7164510df..7d3c0d9f39d 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/codeactions/FilterMapToCollectCodeAction.scala @@ -4,6 +4,7 @@ import scala.concurrent.ExecutionContext import scala.concurrent.Future import scala.meta._ +import scala.meta.internal.metals.JsonParser._ import scala.meta.internal.metals.MetalsEnrichments._ import scala.meta.internal.metals.codeactions.CodeAction import scala.meta.internal.metals.codeactions.CodeActionBuilder @@ -16,19 +17,62 @@ import org.eclipse.{lsp4j => l} class FilterMapToCollectCodeAction(trees: Trees) extends CodeAction { override def kind: String = l.CodeActionKind.RefactorRewrite + private case class FilterMapCollectParams( + param: l.TextDocumentIdentifier, + pos: l.Position, + ) + + override def resolveCodeAction(codeAction: l.CodeAction, token: CancelToken)( + implicit ec: ExecutionContext + ): Option[Future[l.CodeAction]] = { + println(codeAction.getData.toJson) + val edits = for { + data <- codeAction.getData.toJson.as[FilterMapCollectParams].toOption + params = data.param + uri = params.getUri() + path = uri.toAbsolutePath + } yield trees + .findLastEnclosingAt[Term.Apply](path, data.pos) + .flatMap(findFilterMapChain) + .map(toTextEdit(_)) + .map(edit => List(uri -> List(edit))) + .getOrElse(Nil) + + edits match { + case None | (Some(Nil)) => None + case Some(xs) => { + val workspaceEdit = new l.WorkspaceEdit( + xs.map { case (uri, edits) => uri -> edits.asJava }.toMap.asJava + ) + codeAction.setEdit(workspaceEdit) + Some(Future.successful(codeAction)) + } + } + } + override def contribute(params: CodeActionParams, token: CancelToken)(implicit ec: ExecutionContext ): Future[Seq[l.CodeAction]] = Future { val uri = params.getTextDocument().getUri() val path = uri.toAbsolutePath - val range = params.getRange() + val start = params.getRange.getStart trees - .findLastEnclosingAt[Term.Apply](path, range.getStart()) + .findLastEnclosingAt[Term.Apply](path, start) .flatMap(findFilterMapChain) - .map(toTextEdit(_)) - .map(toCodeAction(uri, _)) + .map(_ => { + val data = + FilterMapCollectParams( + params.getTextDocument(), + start, + ) + CodeActionBuilder.build( + title = FilterMapToCollectCodeAction.title, + kind = this.kind, + data = Some(data.toJsonObject), + ) + }) .toSeq } @@ -66,13 +110,6 @@ class FilterMapToCollectCodeAction(trees: Trees) extends CodeAction { new l.TextEdit(chain.pos.toLsp, indented) } - private def toCodeAction(uri: String, textEdit: l.TextEdit): l.CodeAction = - CodeActionBuilder.build( - title = FilterMapToCollectCodeAction.title, - kind = this.kind, - changes = List(uri.toAbsolutePath -> List(textEdit)), - ) - private implicit class FunctionOps(fn: Term.Function) { def renameParam(to: Term.Name): Term = { val fnParamName = fn.params.head.name.value