Skip to content

Commit

Permalink
aptos move lint support (#254)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkurnikov authored Nov 27, 2024
1 parent bda3084 commit 8fbf117
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 92 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ allprojects {
}
task {
systemProperty("org.move.debug.enabled", true)
systemProperty("org.move.types.highlight.unknown.as.error", true)
systemProperty("org.move.types.highlight.unknown.as.error", false)
// systemProperty("org.move.external.linter.max.duration", 30) // 30 ms
// systemProperty("org.move.aptos.bundled.force.unsupported", true)
// systemProperty("idea.log.debug.categories", "org.move.cli")
Expand Down
50 changes: 33 additions & 17 deletions src/main/kotlin/org/move/cli/externalLinter/CompilerErrors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,54 @@ import org.move.ide.annotator.AptosCompilerMessage
import org.move.ide.annotator.AptosCompilerSpan

fun parseCompilerErrors(outputLines: List<String>): List<AptosCompilerMessage> {
val errorLists = splitErrors(outputLines)
val messages = errorLists.map(::errorLinesToCompilerMessage)
val rawMessages = splitMessages(outputLines)
val messages = rawMessages.map(::rawMessageToCompilerMessage)
return messages
}

private val ERROR_START_RE = Regex("^error(\\[E\\d+\\])?:\\s+(.+)")

private fun splitErrors(outputLines: List<String>): List<List<String>> {
val errorLists = mutableListOf<List<String>>()
var thisErrorLines: MutableList<String>? = null
enum class ErrorType(val severityLevel: String) {
ERROR("error"), WARNING("warning"), WARNING_LINT("warning [lint]");
}

data class RawMessage(val errorType: ErrorType, val lines: MutableList<String>)

private fun splitMessages(outputLines: List<String>): List<RawMessage> {
val rawMessages = mutableListOf<RawMessage>()
var message: RawMessage? = null
for (line in outputLines) {
if (line.startsWith("{")) {
break
}
if (ERROR_START_RE.find(line) != null) {
// if (line.startsWith("error:")) {
val newErrorType = when {
ERROR_START_RE.find(line) != null -> ErrorType.ERROR
line.startsWith("warning: [lint]") -> ErrorType.WARNING_LINT
line.startsWith("warning:") -> ErrorType.WARNING
else -> null
}
if (newErrorType != null) {
// flush
thisErrorLines?.let { errorLists.add(it) }
thisErrorLines = mutableListOf()
message?.let { rawMessages.add(it) }
message = RawMessage(newErrorType, mutableListOf())
}
thisErrorLines?.add(line)
message?.lines?.add(line)
}
// flush
thisErrorLines?.let { errorLists.add(it) }
return errorLists
message?.let { rawMessages.add(it) }
return rawMessages
}

private fun errorLinesToCompilerMessage(errorLines: List<String>): AptosCompilerMessage {
val messageLine = errorLines.first()
val (_, message) = ERROR_START_RE.find(messageLine)!!.destructured
val spans = splitSpans(errorLines)
return AptosCompilerMessage(message, "error", spans)
private fun rawMessageToCompilerMessage(rawMessage: RawMessage): AptosCompilerMessage {
val messageLine = rawMessage.lines.first()
val message = when (rawMessage.errorType) {
ErrorType.ERROR -> ERROR_START_RE.find(messageLine)!!.destructured.component2()
ErrorType.WARNING -> messageLine.substringAfter("warning: ")
ErrorType.WARNING_LINT -> messageLine.substringAfter("warning: [lint] ")
}
// val (_, message) = ERROR_START_RE.find(messageLine)!!.destructured
val spans = splitSpans(rawMessage.lines)
return AptosCompilerMessage(message, rawMessage.errorType.severityLevel, spans)
}

private val FILE_POSITION_RE =
Expand Down
6 changes: 3 additions & 3 deletions src/main/kotlin/org/move/cli/externalLinter/ExternalLinter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

package org.move.cli.externalLinter

enum class ExternalLinter(val title: String) {
COMPILER("Aptos Compiler");
// LINTER("Move Linter");
enum class ExternalLinter(val title: String, val command: String) {
COMPILER("Aptos Compiler", "compile"),
LINTER("Aptos Linter", "lint");

override fun toString(): String = title

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class MvExternalLinterConfigurable(val project: Project): BoundConfigurable("Ext
val settings = project.externalLinterSettings
val state = settings.state.copy()

row {
checkBox("Run external linter on the fly")
.comment("Adds code highlighting based on the external linter results. May affect the IDE performance")
.bindSelected(state::runOnTheFly)
}
row("External tool:") {
comboBox(EnumComboBoxModel(ExternalLinter::class.java))
.comment("External tool for additional code analysis")
Expand All @@ -35,7 +40,9 @@ class MvExternalLinterConfigurable(val project: Project): BoundConfigurable("Ext
row("Additional arguments:") {
fullWidthCell(additionalArguments)
.resizableColumn()
.comment("Additional arguments to pass to <b>aptos move compile</b> command")
.comment(
"Additional arguments to pass to <b>aptos move compile</b> / <b>aptos move lint</b>"
)
.bind(
componentGet = { it.text },
componentSet = { component, value -> component.text = value },
Expand All @@ -52,11 +59,6 @@ class MvExternalLinterConfigurable(val project: Project): BoundConfigurable("Ext
)
}

row {
checkBox("Run external linter to analyze code on the fly")
.comment("Adds code highlighting based on the external linter results. May affect the IDE performance")
.bindSelected(state::runOnTheFly)
}
separator()
row {
checkBox("Prevent duplicate errors")
Expand Down
42 changes: 26 additions & 16 deletions src/main/kotlin/org/move/cli/runConfigurations/aptos/Aptos.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.execution.ParametersListUtil
import org.move.cli.MoveProject
import org.move.cli.MvConstants
import org.move.cli.externalLinter.ExternalLinter
import org.move.cli.runConfigurations.AptosCommandLine
import org.move.cli.settings.moveSettings
import org.move.openapiext.*
import org.move.openapiext.common.isUnitTestMode
import org.move.stdext.CollectionBuilder
import org.move.stdext.RsResult
import org.move.stdext.RsResult.Err
import org.move.stdext.RsResult.Ok
Expand Down Expand Up @@ -70,25 +70,36 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp
val commandLine =
AptosCommandLine(
subCommand = "move compile",
arguments = compileArguments(project),
arguments = compilerArguments(project),
workingDirectory = packageRoot
)
return executeAptosCommandLine(commandLine, colored = true, runner = runner)
}

fun checkProject(
project: Project,
args: AptosCompileArgs
linterArgs: AptosExternalLinterArgs
): RsResult<ProcessOutput, RsProcessExecutionException.Start> {
// val useClippy = args.linter == ExternalLinter.CLIPPY
// && !checkNeedInstallClippy(project, args.cargoProjectDirectory)
// val checkCommand = if (useClippy) "clippy" else "check"
val extraArguments = ParametersListUtil.parse(args.extraArguments)
val lintCommand = linterArgs.linter.command
val extraArguments = ParametersListUtil.parse(linterArgs.extraArguments)
val arguments = when (linterArgs.linter) {
ExternalLinter.COMPILER -> compilerArguments(project, extraArguments)
ExternalLinter.LINTER -> {
buildList {
addAll(extraArguments)
if (project.moveSettings.skipFetchLatestGitDeps
&& "--skip-fetch-latest-git-deps" !in extraArguments
) {
add("--skip-fetch-latest-git-deps")
}
}
}
}
val commandLine =
AptosCommandLine(
"move compile",
arguments = compileArguments(project) { addAll(extraArguments) },
args.moveProjectDirectory,
"move $lintCommand",
arguments,
linterArgs.moveProjectDirectory,
)
return executeCommandLine(commandLine).ignoreExitCode()
}
Expand Down Expand Up @@ -199,18 +210,17 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp
return Ok(aptosProcessOutput)
}

private fun compileArguments(
private fun compilerArguments(
project: Project,
builder: (CollectionBuilder<String>.() -> Unit)? = null
extraArguments: List<String> = emptyList(),
): List<String> {
val settings = project.moveSettings
val initialArguments = buildList { builder?.let { this.it() } }
return buildList {
addAll(initialArguments)
if (settings.enableMove2 && "--move-2" !in initialArguments) {
addAll(extraArguments)
if (settings.enableMove2 && "--move-2" !in extraArguments) {
add("--move-2")
}
if (settings.skipFetchLatestGitDeps && "--skip-fetch-latest-git-deps" !in initialArguments) {
if (settings.skipFetchLatestGitDeps && "--skip-fetch-latest-git-deps" !in extraArguments) {
add("--skip-fetch-latest-git-deps")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.move.cli.externalLinter.externalLinterSettings
import org.move.cli.settings.moveSettings
import java.nio.file.Path

data class AptosCompileArgs(
data class AptosExternalLinterArgs(
val linter: ExternalLinter,
val moveProjectDirectory: Path,
val extraArguments: String,
Expand All @@ -15,15 +15,15 @@ data class AptosCompileArgs(
val skipLatestGitDeps: Boolean,
) {
companion object {
fun forMoveProject(moveProject: MoveProject): AptosCompileArgs {
fun forMoveProject(moveProject: MoveProject): AptosExternalLinterArgs {
val linterSettings = moveProject.project.externalLinterSettings
val moveSettings = moveProject.project.moveSettings

val additionalArguments = linterSettings.additionalArguments
val enviroment = linterSettings.envs
val workingDirectory = moveProject.workingDirectory

return AptosCompileArgs(
return AptosExternalLinterArgs(
linterSettings.tool,
workingDirectory,
additionalArguments,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.intellij.openapi.util.TextRange
import org.jetbrains.annotations.TestOnly

data class AptosCompilerMessage(
val message: String,
val text: String,
val severityLevel: String,
val spans: List<AptosCompilerSpan>
) {
Expand All @@ -18,7 +18,7 @@ data class AptosCompilerMessage(
}

fun toTestString(): String {
return "$severityLevel: '$message' at ${mainSpan?.toTestString()}"
return "$severityLevel: '$text' at ${mainSpan?.toTestString()}"
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import com.intellij.psi.PsiFile
import com.intellij.util.ui.update.MergingUpdateQueue
import com.intellij.util.ui.update.Update
import org.move.cli.externalLinter.externalLinterSettings
import org.move.cli.runConfigurations.aptos.AptosCompileArgs
import org.move.cli.runConfigurations.aptos.AptosExternalLinterArgs
import org.move.cli.runConfigurations.aptos.workingDirectory
import org.move.cli.settings.getAptosCli
import org.move.ide.notifications.RsExternalLinterSlowRunNotifier
Expand Down Expand Up @@ -66,7 +66,7 @@ class RsExternalLinterPass(
.also { Disposer.register(moduleOrProject, it) }

val aptos = myProject.getAptosCli(parentDisposable = disposable) ?: return
val args = AptosCompileArgs.forMoveProject(moveProject)
val args = AptosExternalLinterArgs.forMoveProject(moveProject)
annotationInfo = RsExternalLinterUtils.checkLazily(
aptos,
myProject,
Expand Down
Loading

0 comments on commit 8fbf117

Please sign in to comment.