Skip to content

Commit

Permalink
Merge pull request #1737 from LaurenceWarne/add-edit-to-api
Browse files Browse the repository at this point in the history
Add textEdits method to ScalafixPatch
  • Loading branch information
bjaglin authored May 4, 2023
2 parents d647c59 + 285a014 commit b691272
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ object ScalafixFileEvaluationImpl {
ctx: RuleCtx,
index: Option[v0.SemanticdbIndex]
): ScalafixFileEvaluationImpl = {
val scalafixPatches = patches.map(ScalafixPatchImpl.apply)
val indexOrEmpty = index.getOrElse(v0.SemanticdbIndex.empty)
val scalafixPatches = patches.map { p =>
ScalafixPatchImpl(p)(args, ctx, indexOrEmpty)
}
ScalafixFileEvaluationImpl(
originalPath = originalPath,
fixedOpt = fixed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,26 @@ package scalafix.internal.interfaces

import scalafix.Patch
import scalafix.interfaces.ScalafixPatch
import scalafix.interfaces.ScalafixTextEdit
import scalafix.internal.patch.PatchInternals
import scalafix.internal.v1.ValidatedArgs
import scalafix.v0
import scalafix.v0.RuleCtx

case class ScalafixPatchImpl(patch: Patch) extends ScalafixPatch
case class ScalafixPatchImpl(patch: Patch)(
args: ValidatedArgs,
ctx: RuleCtx,
index: v0.SemanticdbIndex
) extends ScalafixPatch {

override def textEdits(): Array[ScalafixTextEdit] =
PatchInternals
.treePatchApply(patch)(ctx, index)
.map { t =>
ScalafixTextEditImpl(
PositionImpl.fromScala(t.tok.pos),
t.newTok
): ScalafixTextEdit
}
.toArray
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package scalafix.internal.interfaces

import scalafix.interfaces.ScalafixPosition
import scalafix.interfaces.ScalafixTextEdit

final case class ScalafixTextEditImpl(
position: ScalafixPosition,
newText: String
) extends ScalafixTextEdit
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
package scalafix.interfaces;

public interface ScalafixPatch {}
public interface ScalafixPatch {
/**
*
* @return This patch as an array of text edits.
*/
default ScalafixTextEdit[] textEdits() {
throw new UnsupportedOperationException("textEdits() is not implemented");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package scalafix.interfaces;

public interface ScalafixTextEdit {
ScalafixPosition position();

String newText();
}
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,61 @@ class ScalafixArgumentsSuite extends AnyFunSuite with DiffAssertions {
assert(run.failed.toOption.map(_.getMessage) == Some(expectedErrorMessage))
}

test("textEdits returns patch as edits") {
val cwd: Path = StringFS
.string2dir(
"""|/src/Main2.scala
|import scala.concurrent.duration
|import scala.concurrent.Future
|
|object Main extends App {
| import scala.concurrent.Await
| println("test");
| println("ok")
|}""".stripMargin,
charset
)
.toNIO
val src = cwd.resolve("src")

val run = api
.withRules(List("CommentFileNonAtomic", "CommentFileAtomic").asJava)
.withSourceroot(src)

val fileEvaluation = run.evaluate().getFileEvaluations.head
val patches = fileEvaluation.getPatches

// CommentFileNonAtomic produces two patches which in turn produce one
// token patch each, whilst CommentFileAtomic produces one patch which
// in turn produces two token patches
val Array(nonAtomicEditArray1, nonAtomicEditArray2, atomicEditArray) =
patches.map(_.textEdits()).sortBy(_.length)

// Check the above holds
assert(nonAtomicEditArray1.length == 1 && nonAtomicEditArray2.length == 1)
assert(atomicEditArray.length == 2)

// Check the offsets for the atomic edits look ok (e.g. they're zero-based)
val Array(atomicEdit1, atomicEdit2) =
atomicEditArray.sortBy(_.position.startLine)
assert(
atomicEdit1.position.startLine == 0 && atomicEdit1.position.startColumn == 0
)
assert(
atomicEdit2.position.startLine == 7 && atomicEdit2.position.startColumn == 1
)

// Check the same holds for the non-atomic edit pair
val Array(nonAtomicEdit1, nonAtomicEdit2) =
(nonAtomicEditArray1 ++ nonAtomicEditArray2).sortBy(_.position.startLine)
assert(
nonAtomicEdit1.position.startLine == 0 && nonAtomicEdit1.position.startColumn == 0
)
assert(
nonAtomicEdit2.position.startLine == 7 && nonAtomicEdit2.position.startColumn == 1
)
}

def removeUnsuedRule(): SemanticRule = {
val config = RemoveUnusedConfig.default
new RemoveUnused(config)
Expand Down

0 comments on commit b691272

Please sign in to comment.