Skip to content

Commit

Permalink
refactor: Add a common codeAction method to the presentation compiler
Browse files Browse the repository at this point in the history
together with a supportedCodeActions method
  • Loading branch information
KacperFKorban committed Aug 30, 2024
1 parent 92e0d5f commit efb0e7f
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 3 deletions.
29 changes: 29 additions & 0 deletions metals/src/main/scala/scala/meta/internal/metals/Compilers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import scala.meta.internal.{semanticdb => s}
import scala.meta.io.AbsolutePath
import scala.meta.pc.AutoImportsResult
import scala.meta.pc.CancelToken
import scala.meta.pc.CodeActionId
import scala.meta.pc.CompletionItemPriority
import scala.meta.pc.HoverSignature
import scala.meta.pc.OffsetParams
Expand Down Expand Up @@ -878,6 +879,34 @@ class Compilers(
}
}.getOrElse(Future.successful(Nil.asJava))

def codeAction(
params: TextDocumentPositionParams,
token: CancelToken,
codeActionId: CodeActionId,
codeActionPayload: Object,
): Future[ju.List[TextEdit]] = {
withPCAndAdjustLsp(params) { (pc, pos, adjust) =>
pc.codeAction(
CompilerOffsetParamsUtils.fromPos(
pos,
token,
outlineFilesProvider.getOutlineFiles(pc.buildTargetId()),
),
codeActionId,
codeActionPayload,
).asScala
.map { edits =>
adjust.adjustTextEdits(edits)
}
}
}.getOrElse(Future.successful(Nil.asJava))

def supportedCodeActions(path: AbsolutePath): ju.List[CodeActionId] = {
loadCompiler(path).map { pc =>
pc.supportedCodeActions()
}
}.getOrElse(Nil.asJava)

def hover(
params: HoverExtParams,
token: CancelToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import scala.concurrent.Future
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.ParametrizedCommand
import scala.meta.pc.CancelToken
import scala.meta.pc.CodeActionId

import org.eclipse.{lsp4j => l}

Expand All @@ -18,6 +19,12 @@ trait CodeAction {
*/
def kind: String

/**
* The CodeActionId for this code action, if applicable. CodeActionId is only
* used for code actions that require the use of the presentation compiler.
*/
def maybeCodeActionId: Option[CodeActionId] = None

type CommandData
type ActionCommand = ParametrizedCommand[CommandData]
def command: Option[ActionCommand] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.jdk.CollectionConverters._

import scala.meta.internal.metals.MetalsEnrichments.XtensionString
import scala.meta.internal.metals._
import scala.meta.internal.metals.clients.language.MetalsLanguageClient
import scala.meta.internal.metals.codeactions.CodeAction
Expand Down Expand Up @@ -60,6 +61,12 @@ final class CodeActionProvider(
new ConvertCommentCodeAction(buffers),
)

def actionsForParams(params: l.CodeActionParams): List[CodeAction] = {
val path = params.getTextDocument.getUri.toAbsolutePath
val supportedCodeActions = compilers.supportedCodeActions(path)
allActions.filter(_.maybeCodeActionId.forall(supportedCodeActions.contains))
}

def codeActions(
params: l.CodeActionParams,
token: CancelToken,
Expand All @@ -73,7 +80,7 @@ final class CodeActionProvider(
case None => true
}

val actions = allActions.collect {
val actions = actionsForParams(params).collect {
case action if isRequestedKind(action) =>
action.contribute(params, token)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import scala.meta.internal.metals.codeactions.CodeActionBuilder
import scala.meta.internal.metals.logging
import scala.meta.internal.parsing.Trees
import scala.meta.pc.CancelToken
import scala.meta.pc.CodeActionId

import org.eclipse.{lsp4j => l}

Expand All @@ -28,6 +29,10 @@ class ConvertToNamedArguments(
import ConvertToNamedArguments._
override val kind: String = l.CodeActionKind.RefactorRewrite

override val maybeCodeActionId: Option[CodeActionId] = Some(
CodeActionId.ConvertToNamedArguments
)

override type CommandData = ServerCommands.ConvertToNamedArgsRequest

override def command: Option[ActionCommand] = Some(
Expand Down Expand Up @@ -57,7 +62,7 @@ class ConvertToNamedArguments(
} yield ()
}

def getTermWithArgs(
private def getTermWithArgs(
apply: Tree,
args: List[Tree],
nameEnd: Int,
Expand All @@ -80,7 +85,7 @@ class ConvertToNamedArguments(
}
}

def firstApplyWithUnnamedArgs(
private def firstApplyWithUnnamedArgs(
term: Option[Tree]
): Option[ApplyTermWithArgIndices] = {
term match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import scala.meta.internal.metals.clients.language.MetalsLanguageClient
import scala.meta.internal.metals.logging
import scala.meta.internal.parsing.Trees
import scala.meta.pc.CancelToken
import scala.meta.pc.CodeActionId

import org.eclipse.lsp4j.CodeActionParams
import org.eclipse.{lsp4j => l}
Expand All @@ -32,6 +33,10 @@ class ExtractMethodCodeAction(
)
override def kind: String = l.CodeActionKind.RefactorExtract

override val maybeCodeActionId: Option[CodeActionId] = Some(
CodeActionId.ExtractMethod
)

override def handleCommand(
data: ServerCommands.ExtractMethodParams,
token: CancelToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.ScalacDiagnostic
import scala.meta.internal.metals.codeactions.CodeAction
import scala.meta.pc.CancelToken
import scala.meta.pc.CodeActionId

import org.eclipse.{lsp4j => l}

class ImplementAbstractMembers(compilers: Compilers) extends CodeAction {

override def kind: String = l.CodeActionKind.QuickFix

override val maybeCodeActionId: Option[CodeActionId] = Some(
CodeActionId.ImplementAbstractMembers
)

override def contribute(
params: l.CodeActionParams,
token: CancelToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import scala.meta.internal.metals.ScalaVersions
import scala.meta.internal.metals.ScalacDiagnostic
import scala.meta.internal.metals.codeactions.CodeAction
import scala.meta.pc.CancelToken
import scala.meta.pc.CodeActionId

import org.eclipse.{lsp4j => l}

Expand All @@ -18,6 +19,10 @@ class ImportMissingSymbol(compilers: Compilers, buildTargets: BuildTargets)

override def kind: String = l.CodeActionKind.QuickFix

override val maybeCodeActionId: Option[CodeActionId] = Some(
CodeActionId.ImportMissingSymbol
)

override def contribute(
params: l.CodeActionParams,
token: CancelToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import scala.meta.internal.metals.codeactions.CodeAction
import scala.meta.internal.parsing.Trees
import scala.meta.io.AbsolutePath
import scala.meta.pc.CancelToken
import scala.meta.pc.CodeActionId

import org.eclipse.{lsp4j => l}

Expand All @@ -32,6 +33,10 @@ class InlineValueCodeAction(

override def kind: String = l.CodeActionKind.RefactorInline

override val maybeCodeActionId: Option[CodeActionId] = Some(
CodeActionId.InlineValue
)

override def contribute(params: l.CodeActionParams, token: CancelToken)(
implicit ec: ExecutionContext
): Future[Seq[l.CodeAction]] = Future {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ 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 scala.meta.pc.CodeActionId

import org.eclipse.{lsp4j => l}

Expand All @@ -33,6 +34,10 @@ class InsertInferredType(
import InsertInferredType._
override def kind: String = l.CodeActionKind.QuickFix

override val maybeCodeActionId: Option[CodeActionId] = Some(
CodeActionId.InsertInferredType
)

override def handleCommand(
textDocumentParams: l.TextDocumentPositionParams,
token: CancelToken,
Expand Down
10 changes: 10 additions & 0 deletions mtags-interfaces/src/main/java/scala/meta/pc/CodeActionId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package scala.meta.pc;

public enum CodeActionId {
ConvertToNamedArguments,
ExtractMethod,
ImplementAbstractMembers,
ImportMissingSymbol,
InlineValue,
InsertInferredType,
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.net.URI;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;
import java.util.List;
Expand Down Expand Up @@ -111,6 +112,27 @@ public CompletableFuture<java.util.List<ReferencesResult>> references(References
return CompletableFuture.completedFuture(Collections.emptyList());
}

/**
* Execute the given code action
*/
public CompletableFuture<List<TextEdit>> codeAction(OffsetParams params, CodeActionId codeActionId, Object codeActionPayload) {
return CompletableFuture.completedFuture(Collections.emptyList());
}

/**
* Returns the list of code actions supported by the current presentation compiler.
*/
public List<CodeActionId> supportedCodeActions() {
return Arrays.asList(
CodeActionId.ConvertToNamedArguments,
CodeActionId.ExtractMethod,
CodeActionId.ImplementAbstractMembers,
CodeActionId.ImportMissingSymbol,
CodeActionId.InlineValue,
CodeActionId.InsertInferredType
);
}

/**
* Return decoded and pretty printed TASTy content for .scala or .tasty file.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ case class ScalaPresentationCompiler(
case Right(edits: List[l.TextEdit]) => edits.asJava
}
end convertToNamedArguments

override def selectionRange(
params: ju.List[OffsetParams]
): CompletableFuture[ju.List[l.SelectionRange]] =
Expand Down

0 comments on commit efb0e7f

Please sign in to comment.