Skip to content

Commit

Permalink
Rework and simplify OnTypeFormatting and RangeFormatting classes
Browse files Browse the repository at this point in the history
I mostly removed a couple of types, which were not adding much and increasing complexity. I also removed the `fn` functions and just inlined everything in the methods, which is overall shorter and simpler to understand.
  • Loading branch information
tgodzik committed Jul 22, 2021
1 parent 108b8f8 commit cd1ad40
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 222 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import java.util.concurrent.CompletionStage
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException

import scala.annotation.tailrec
import scala.collection.convert.DecorateAsJava
import scala.collection.convert.DecorateAsScala
import scala.collection.mutable
Expand Down Expand Up @@ -210,6 +211,26 @@ object MetalsEnrichments
}
}

implicit class XtensionList[T](lst: List[T]) {
def acceptFirst[R](
accept: T => Option[List[R]]
): List[R] = {
@tailrec
def loop(toCheck: List[T]): List[R] = {
toCheck match {
case prioritized :: rest =>
val contributed = accept(prioritized)
contributed match {
case Some(edits) => edits
case None => loop(rest)
}
case Nil => Nil
}
}
loop(lst)
}
}

implicit class XtensionDocumentSymbol(symbol: Seq[l.DocumentSymbol]) {

def toSymbolInformation(uri: String): List[l.SymbolInformation] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ import scala.meta.internal.metals.codelenses.WorksheetCodeLens
import scala.meta.internal.metals.debug.BuildTargetClasses
import scala.meta.internal.metals.debug.DebugParametersJsonParsers
import scala.meta.internal.metals.debug.DebugProvider
import scala.meta.internal.metals.formatting.OnTypeFormattingProvider
import scala.meta.internal.metals.formatting.RangeFormattingProvider
import scala.meta.internal.metals.newScalaFile.NewFileProvider
import scala.meta.internal.mtags._
import scala.meta.internal.parsing.ClassFinder
Expand Down Expand Up @@ -206,9 +208,9 @@ class MetalsLanguageServer(
private val trees = new Trees(buildTargets, buffers, scalaVersionSelector)
private val documentSymbolProvider = new DocumentSymbolProvider(trees)
private val onTypeFormattingProvider =
new OnTypeFormattingProvider(buffers, () => userConfig)
new OnTypeFormattingProvider(buffers, trees, () => userConfig)
private val rangeFormattingProvider =
new RangeFormattingProvider(buffers)
new RangeFormattingProvider(buffers, trees)
private val classFinder = new ClassFinder(trees)
private val foldingRangeProvider = new FoldingRangeProvider(trees, buffers)
// These can't be instantiated until we know the workspace root directory.
Expand Down Expand Up @@ -1368,15 +1370,15 @@ class MetalsLanguageServer(
params: DocumentOnTypeFormattingParams
): CompletableFuture[util.List[TextEdit]] =
CancelTokens { _ =>
onTypeFormattingProvider.format(params, trees).asJava
onTypeFormattingProvider.format(params).asJava
}

@JsonRequest("textDocument/rangeFormatting")
def rangeFormatting(
params: DocumentRangeFormattingParams
): CompletableFuture[util.List[TextEdit]] =
CancelTokens { _ =>
rangeFormattingProvider.format(params, trees).asJava
rangeFormattingProvider.format(params).asJava
}

@JsonRequest("textDocument/prepareRename")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package scala.meta.internal.metals.onTypeRangeFormatters
package scala.meta.internal.metals.formatting
import scala.util.matching.Regex

import scala.meta.internal.mtags.MtagsEnrichments._
Expand Down Expand Up @@ -50,12 +50,11 @@ object IndentOnPaste extends RangeFormatter {
}

override def contribute(
rangeFormatterParams: RangeFormatterParams,
tokensParams: TokensParams
rangeFormatterParams: RangeFormatterParams
): Option[List[TextEdit]] = {
val formattingOptions = rangeFormatterParams.formattingOptions
val startPos = tokensParams.startPos
val endPos = tokensParams.endPos
val startPos = rangeFormatterParams.startPos
val endPos = rangeFormatterParams.endPos
val splitLines = rangeFormatterParams.splitLines

val insertSpaces = formattingOptions.isInsertSpaces
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package scala.meta.internal.metals.onTypeRangeFormatters
package scala.meta.internal.metals.formatting

import scala.meta.internal.metals.UserConfiguration
import scala.meta.internal.mtags.MtagsEnrichments._
Expand Down Expand Up @@ -134,7 +134,7 @@ case class MultilineString(userConfig: () => UserConfiguration)

private def indent(
splitLines: Array[String],
startPosition: StartPosition,
startPosition: meta.Position,
range: Range
): List[TextEdit] = {
// position.startLine since we want to check current line on rangeFormatting
Expand Down Expand Up @@ -184,8 +184,8 @@ case class MultilineString(userConfig: () => UserConfiguration)
}

private def indentTokensOnTypeFormatting(
startPosition: StartPosition,
endPosition: EndPosition,
startPosition: meta.Position,
endPosition: meta.Position,
tokens: Tokens,
triggerChar: String,
splitLines: Array[String],
Expand Down Expand Up @@ -220,8 +220,8 @@ case class MultilineString(userConfig: () => UserConfiguration)
}

def isStringOrInterpolation(
startPosition: StartPosition,
endPosition: EndPosition,
startPosition: meta.Position,
endPosition: meta.Position,
token: Token,
index: Int,
text: String,
Expand Down Expand Up @@ -350,12 +350,11 @@ case class MultilineString(userConfig: () => UserConfiguration)
}

override def contribute(
onTypeFormatterParams: OnTypeFormatterParams,
tokensParams: TokensParams
onTypeFormatterParams: OnTypeFormatterParams
): Option[List[TextEdit]] = {
val tokensOpt = tokensParams.tokens
val startPos = tokensParams.startPos
val endPos = tokensParams.endPos
val tokensOpt = onTypeFormatterParams.tokens
val startPos = onTypeFormatterParams.startPos
val endPos = onTypeFormatterParams.endPos
val triggerChar = onTypeFormatterParams.triggerChar
val splitLines = onTypeFormatterParams.splitLines
val position = onTypeFormatterParams.position
Expand Down Expand Up @@ -386,12 +385,11 @@ case class MultilineString(userConfig: () => UserConfiguration)
}

override def contribute(
rangeFormatterParams: RangeFormatterParams,
tokensParams: TokensParams
rangeFormatterParams: RangeFormatterParams
): Option[List[TextEdit]] = {
val tokensOpt = tokensParams.tokens
val startPos = tokensParams.startPos
val endPos = tokensParams.endPos
val tokensOpt = rangeFormatterParams.tokens
val startPos = rangeFormatterParams.startPos
val endPos = rangeFormatterParams.endPos
val sourceText = rangeFormatterParams.sourceText
val range = rangeFormatterParams.range
val splitLines = rangeFormatterParams.splitLines
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package scala.meta.internal.metals.formatting

import scala.meta.inputs.Input
import scala.meta.internal.metals.Buffers
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.UserConfiguration
import scala.meta.internal.parsing.Trees
import scala.meta.tokens.Tokens

import org.eclipse.lsp4j.DocumentOnTypeFormattingParams
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.TextEdit

class OnTypeFormatter {
def contribute(
onTypeformatterParams: OnTypeFormatterParams
): Option[List[TextEdit]] = None

}

case class OnTypeFormatterParams(
sourceText: String,
position: Position,
triggerChar: String,
startPos: meta.Position,
endPos: meta.Position,
tokens: Option[Tokens]
) {
lazy val splitLines: Array[String] = sourceText.split("\\r?\\n")
val range = new Range(position, position)
}

class OnTypeFormattingProvider(
buffers: Buffers,
trees: Trees,
userConfig: () => UserConfiguration
) {

// The order of which this is important to know which will first return the Edits
val formatters: List[OnTypeFormatter] = List(
MultilineString(userConfig)
)

def format(
params: DocumentOnTypeFormattingParams
): List[TextEdit] = {
val uri = params.getTextDocument.getUri.toAbsolutePath
val range = new Range(params.getPosition, params.getPosition)
val triggerChar = params.getCh
val position = params.getPosition
buffers
.get(uri)
.map { sourceText =>
val virtualFile = Input.VirtualFile(sourceText.toString(), sourceText)
val startPos = range.getStart.toMeta(virtualFile)
val endPos = range.getEnd.toMeta(virtualFile)
val tokensOpt = trees.tokenized(virtualFile).toOption
val onTypeformatterParams =
OnTypeFormatterParams(
sourceText,
position,
triggerChar,
startPos,
endPos,
tokensOpt
)
formatters.acceptFirst(formater =>
formater.contribute(onTypeformatterParams)
)
}
.getOrElse(Nil)
}
}
Loading

0 comments on commit cd1ad40

Please sign in to comment.