Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add methods to scalafix api to be able to retrieve patches #1223

Merged
merged 8 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion project/Mima.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ object Mima {
Seq(
ProblemFilters.exclude[MissingTypesProblem]("scalafix.testkit.DiffAssertions"),
ProblemFilters.exclude[MissingTypesProblem]("scalafix.testkit.SemanticRuleSuite"),
ProblemFilters.exclude[Problem]("scalafix.internal.*")
ProblemFilters.exclude[Problem]("scalafix.internal.*"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.ScalafixArguments.evaluate")
)
}
}
5 changes: 5 additions & 0 deletions scalafix-cli/src/main/scala/scalafix/cli/ExitStatus.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,9 @@ object ExitStatus {

def merge(exit1: ExitStatus, exit2: ExitStatus): ExitStatus =
apply(exit1.code | exit2.code)

def merge(exitStatus: Seq[ExitStatus]): ExitStatus =
exitStatus.foldLeft(ExitStatus.Ok) { (status, next) =>
apply(status.code | next.code)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ import scala.jdk.CollectionConverters._
import scala.meta.io.AbsolutePath
import scala.meta.io.Classpath
import scala.util.control.NoStackTrace
import scalafix.interfaces.ScalafixArguments
import scalafix.interfaces.ScalafixError
import scalafix.interfaces.ScalafixException
import scalafix.interfaces.ScalafixMainCallback
import scalafix.interfaces.ScalafixMainMode
import scalafix.interfaces.ScalafixRule
import scalafix.interfaces.{
ScalafixArguments,
ScalafixError,
ScalafixException,
ScalafixMainCallback,
ScalafixMainMode,
ScalafixEvaluation,
ScalafixRule
}
import scalafix.internal.v1.Args
import scalafix.internal.v1.MainOps
import scalafix.internal.v1.Rules
import scalafix.v1.RuleDecoder
import scalafix.Versions
import scalafix.cli.ExitStatus

final case class ScalafixArgumentsImpl(args: Args = Args.default)
extends ScalafixArguments {
Expand All @@ -36,6 +40,15 @@ final case class ScalafixArgumentsImpl(args: Args = Args.default)
ScalafixErrorImpl.fromScala(exit)
}

override def evaluate(): ScalafixEvaluation = {
args.validate match {
case Configured.Ok(validated) =>
MainOps.runWithResult(validated)
case Configured.NotOk(err) =>
ScalafixEvaluationImpl(ExitStatus.CommandLineError, Some(err.msg))
}
}

override def withRules(rules: util.List[String]): ScalafixArguments =
copy(args = args.copy(rules = rules.asScala.toList))

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package scalafix.internal.interfaces

import java.util.Optional

import scalafix.cli.ExitStatus
import scalafix.interfaces.{
ScalafixError,
ScalafixFileEvaluation,
ScalafixEvaluation
}
import scalafix.internal.util.OptionOps._

final case class ScalafixEvaluationImpl(
error: ExitStatus,
getMessageError: Optional[String],
fileEvaluations: Seq[ScalafixFileEvaluationImpl]
) extends ScalafixEvaluation {

override def isSuccessful: Boolean = error.isOk

override def getErrors: Array[ScalafixError] = {
ScalafixErrorImpl.fromScala(error)
}

override def getFileEvaluations: Array[ScalafixFileEvaluation] =
fileEvaluations.toArray

override def apply(): Array[ScalafixError] = {
fileEvaluations.flatMap(o => o.applyPatches()).toArray
}
}

object ScalafixEvaluationImpl {

def apply(
error: ExitStatus,
errorMessage: Option[String] = None
): ScalafixEvaluationImpl = {
new ScalafixEvaluationImpl(error, errorMessage.asJava, Nil)
}

def from(
fileEvaluations: Seq[ScalafixFileEvaluationImpl],
exitStatus: ExitStatus
): ScalafixEvaluationImpl = {
ScalafixEvaluationImpl(exitStatus, Optional.empty(), fileEvaluations)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package scalafix.internal.interfaces

import java.nio.file.Path
import java.util.Optional

import scalafix.cli.ExitStatus
import scalafix.interfaces.{
ScalafixDiagnostic,
ScalafixError,
ScalafixFileEvaluation,
ScalafixPatch,
ScalafixRule
}
import scalafix.internal.diff.DiffUtils
import scalafix.internal.v1.{MainOps, ValidatedArgs}
import scalafix.lint.RuleDiagnostic
import scalafix.internal.util.OptionOps._
import scalafix.v0
import scalafix.v0.RuleCtx

import scala.meta.io.AbsolutePath

final case class ScalafixFileEvaluationImpl(
originalPath: AbsolutePath,
fixedOpt: Option[String],
error: ExitStatus,
errorMessage: Option[String],
diagnostics: Seq[RuleDiagnostic],
patches: Seq[ScalafixPatchImpl]
)(
args: ValidatedArgs,
ctxOpt: Option[RuleCtx],
index: Option[v0.SemanticdbIndex]
) extends ScalafixFileEvaluation {
val rules: Seq[ScalafixRuleImpl] =
args.rules.rules.map(new ScalafixRuleImpl(_))
val pathToReplace = args.pathReplace(originalPath)

override def getEvaluatedPath: Path = originalPath.toNIO

override def getEvaluatedRules: Array[ScalafixRule] = rules.toArray

override def previewPatches(): Optional[String] = fixedOpt.asJava

override def getUnifiedDiff: Optional[String] = {
fixedOpt
.flatMap(fixed => {
val input = args.input(originalPath).text
if (input == fixed) None
else
Some(
DiffUtils.unifiedDiff(
originalPath.toString(),
"<expected fix>",
input.linesIterator.toList,
fixed.linesIterator.toList,
3
)
)
})
.asJava
}

override def getErrors(): Array[ScalafixError] =
ScalafixErrorImpl.fromScala(error)

override def isSuccessful: Boolean = error.isOk

override def getDiagnostics: Array[ScalafixDiagnostic] =
diagnostics.map(ScalafixDiagnosticImpl.fromScala).toArray

override def getPatches: Array[ScalafixPatch] = {
patches.toArray
}

override def applyPatches(): Array[ScalafixError] = {
val exitStatus = fixedOpt.toTry
.flatMap(MainOps.applyDiff(args, file = originalPath, _))
.getOrElse(ExitStatus.UnexpectedError)
ScalafixErrorImpl.fromScala(exitStatus).toSeq.toArray
}

override def previewPatches(
selectedPatches: Array[ScalafixPatch]
): Optional[String] = {
val selectedPatchesSet =
new java.util.IdentityHashMap[ScalafixPatch, Unit](selectedPatches.length)
for (patch <- selectedPatches)
selectedPatchesSet.put(patch, ())
val filteredPatches = patches.filter(selectedPatchesSet.containsKey(_))
ctxOpt
.flatMap(ctx =>
MainOps.previewPatches(filteredPatches.map(_.patch), ctx, index)
)
.asJava
}
override def applyPatches(
selectedPatches: Array[ScalafixPatch]
): Array[ScalafixError] = {
val selectedPatchesSet =
new java.util.IdentityHashMap[ScalafixPatch, Unit](selectedPatches.length)
for (patch <- selectedPatches)
selectedPatchesSet.put(patch, ())
val filteredPatches = patches.filter(selectedPatchesSet.containsKey(_))
val exitStatus =
ctxOpt.toTry
.flatMap(ctx =>
MainOps.applyPatches(
args,
filteredPatches.map(_.patch),
ctx,
index,
pathToReplace
)
)
.getOrElse(ExitStatus.UnexpectedError)
ScalafixErrorImpl.fromScala(exitStatus)
}

}

object ScalafixFileEvaluationImpl {

def from(
originalPath: AbsolutePath,
fixed: Option[String],
exitStatus: ExitStatus,
patches: Seq[v0.Patch],
diagnostics: Seq[RuleDiagnostic]
)(
args: ValidatedArgs,
ctx: RuleCtx,
index: Option[v0.SemanticdbIndex]
): ScalafixFileEvaluationImpl = {
val scalafixPatches = patches.map(ScalafixPatchImpl)
ScalafixFileEvaluationImpl(
originalPath = originalPath,
fixedOpt = fixed,
error = exitStatus,
errorMessage = None,
diagnostics = diagnostics,
patches = scalafixPatches
)(args, Some(ctx), index)
}
def from(
originalPath: AbsolutePath,
exitStatus: ExitStatus,
errorMessage: String
)(
args: ValidatedArgs
): ScalafixFileEvaluationImpl =
ScalafixFileEvaluationImpl(
originalPath,
None,
exitStatus,
Some(errorMessage),
Nil,
Nil
)(args, None, None)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package scalafix.internal.interfaces

import scalafix.interfaces.ScalafixPatch
import scalafix.Patch

case class ScalafixPatchImpl(patch: Patch) extends ScalafixPatch
Loading