From 54b24134011a392de51520250f1536a16451344a Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Wed, 13 Nov 2024 16:06:19 +0100 Subject: [PATCH] fix minor things (#248) --- .../org/move/cli/MoveProjectsSyncTask.kt | 11 ++-- .../cli/runConfigurations/AptosRunState.kt | 10 +++- .../CommandConfigurationBase.kt | 7 +++ .../move/cli/runConfigurations/aptos/Aptos.kt | 47 +++++++++------- .../aptos/AptosExitStatus.kt | 25 +++++---- .../ide/annotator/RsExternalLinterUtils.kt | 5 +- .../move/ide/refactoring/MvImportOptimizer.kt | 10 ++-- src/main/kotlin/org/move/openapiext/utils.kt | 4 +- .../aptos/AptosExitStatusTest.kt | 19 +++++++ .../optimizeImports/OptimizeImportsTest.kt | 54 +++++++++++++++++++ 10 files changed, 145 insertions(+), 47 deletions(-) diff --git a/src/main/kotlin/org/move/cli/MoveProjectsSyncTask.kt b/src/main/kotlin/org/move/cli/MoveProjectsSyncTask.kt index 8528cbe5a..8ac01790c 100644 --- a/src/main/kotlin/org/move/cli/MoveProjectsSyncTask.kt +++ b/src/main/kotlin/org/move/cli/MoveProjectsSyncTask.kt @@ -139,7 +139,7 @@ class MoveProjectsSyncTask( projects: MutableList, context: SyncContext ) { - val projectRoot = moveTomlFile.parent?.toNioPathOrNull() ?: error("cannot be invalid path") + val packageRoot = moveTomlFile.parent?.toNioPathOrNull() ?: error("cannot be invalid path") var (moveProject, rootMoveToml) = runReadAction { val tomlFile = moveTomlFile.toTomlFile(project)!! @@ -156,7 +156,7 @@ class MoveProjectsSyncTask( ) } else { context.runWithChildProgress("Fetch dependencies") { childContext -> - val taskResult = fetchDependencyPackages(childContext, projectRoot) + val taskResult = fetchDependencyPackages(childContext, packageRoot) if (taskResult is TaskResult.Err) { moveProject = moveProject.copy( fetchDepsStatus = UpdateStatus.UpdateFailed("Failed to fetch dependency packages") @@ -204,17 +204,16 @@ class MoveProjectsSyncTask( } private fun fetchDependencyPackages( - childContext: SyncContext, projectRoot: Path + childContext: SyncContext, packageRoot: Path ): TaskResult { - val skipLatest = project.moveSettings.skipFetchLatestGitDeps val aptos = project.getAptosCli(parentDisposable = this) return when { aptos == null -> TaskResult.Err("Invalid Aptos CLI configuration") else -> { val aptosProcessOutput = aptos.fetchPackageDependencies( - projectRoot, - skipLatest, + project, + packageRoot, runner = { // populate progress bar addProcessListener(object: AnsiEscapedProcessAdapter() { diff --git a/src/main/kotlin/org/move/cli/runConfigurations/AptosRunState.kt b/src/main/kotlin/org/move/cli/runConfigurations/AptosRunState.kt index cc50108ce..48b1fbed8 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/AptosRunState.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/AptosRunState.kt @@ -6,11 +6,13 @@ import com.intellij.execution.process.KillableColoredProcessHandler import com.intellij.execution.process.ProcessHandler import com.intellij.execution.process.ProcessTerminatedListener import com.intellij.execution.runners.ExecutionEnvironment +import com.intellij.openapi.util.Disposer import org.move.cli.MoveFileHyperlinkFilter import org.move.cli.runConfigurations.CommandConfigurationBase.CleanConfiguration abstract class AptosRunStateBase( - environment: ExecutionEnvironment, val cleanConfiguration: CleanConfiguration.Ok + environment: ExecutionEnvironment, + val cleanConfiguration: CleanConfiguration.Ok ): CommandLineState(environment) { val project = environment.project @@ -21,7 +23,11 @@ abstract class AptosRunStateBase( val generalCommandLine = commandLine.toGeneralCommandLine(cleanConfiguration.aptosPath, emulateTerminal = true) val handler = KillableColoredProcessHandler(generalCommandLine) - consoleBuilder.console.attachToProcess(handler) + + val console = consoleBuilder.console + Disposer.register(this.environment, console) + console.attachToProcess(handler) + ProcessTerminatedListener.attach(handler) // shows exit code upon termination return handler } diff --git a/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt b/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt index e6b0403c0..87105737e 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt @@ -6,6 +6,7 @@ import com.intellij.execution.configurations.* import com.intellij.execution.runners.ExecutionEnvironment import com.intellij.openapi.options.advanced.AdvancedSettings import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.NlsContexts import com.intellij.util.execution.ParametersListUtil import org.jdom.Element @@ -17,6 +18,7 @@ import org.move.cli.runConfigurations.test.AptosTestRunState import org.move.cli.settings.aptosCliPath import org.move.cli.writePath import org.move.cli.writeString +import org.move.openapiext.rootPluginDisposable import org.move.stdext.exists import java.nio.file.Path @@ -55,6 +57,11 @@ abstract class CommandConfigurationBase( override fun getState(executor: Executor, environment: ExecutionEnvironment): AptosRunStateBase? { val config = clean().ok ?: return null + + // environment is disposable to which all internal RunState disposables are connected + // todo: find shorter living disposable? + Disposer.register(project.rootPluginDisposable, environment) + return if (showTestToolWindow(config.cmd)) { AptosTestRunState(environment, config) } else { diff --git a/src/main/kotlin/org/move/cli/runConfigurations/aptos/Aptos.kt b/src/main/kotlin/org/move/cli/runConfigurations/aptos/Aptos.kt index 8ceed8662..b5e201ed9 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/aptos/Aptos.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/aptos/Aptos.kt @@ -13,8 +13,10 @@ import com.intellij.util.execution.ParametersListUtil import org.move.cli.MoveProject import org.move.cli.MvConstants 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 @@ -61,22 +63,23 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp } fun fetchPackageDependencies( - projectDir: Path, - skipLatest: Boolean, + project: Project, + packageRoot: Path, runner: CapturingProcessHandler.() -> ProcessOutput = { runProcessWithGlobalProgress() } ): AptosProcessResult { val commandLine = AptosCommandLine( subCommand = "move compile", - arguments = listOfNotNull( - "--skip-fetch-latest-git-deps".takeIf { skipLatest } - ), - workingDirectory = projectDir + arguments = compileArguments(project), + workingDirectory = packageRoot ) return executeAptosCommandLine(commandLine, colored = true, runner = runner) } - fun checkProject(args: AptosCompileArgs): RsResult { + fun checkProject( + project: Project, + args: AptosCompileArgs + ): RsResult { // val useClippy = args.linter == ExternalLinter.CLIPPY // && !checkNeedInstallClippy(project, args.cargoProjectDirectory) // val checkCommand = if (useClippy) "clippy" else "check" @@ -84,18 +87,7 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp val commandLine = AptosCommandLine( "move compile", - buildList { -// add("--message-format=json") - if ("--skip-fetch-latest-git-deps" !in extraArguments) { - add("--skip-fetch-latest-git-deps") - } - if (args.enableMove2) { - if ("--move-2" !in extraArguments) { - add("--move-2") - } - } - addAll(ParametersListUtil.parse(args.extraArguments)) - }, + arguments = compileArguments(project) { addAll(extraArguments) }, args.moveProjectDirectory, ) return executeCommandLine(commandLine).ignoreExitCode() @@ -207,6 +199,23 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp return Ok(aptosProcessOutput) } + private fun compileArguments( + project: Project, + builder: (CollectionBuilder.() -> Unit)? = null + ): List { + val settings = project.moveSettings + val initialArguments = buildList { builder?.let { this.it() } } + return buildList { + addAll(initialArguments) + if (settings.enableMove2 && "--move-2" !in initialArguments) { + add("--move-2") + } + if (settings.skipFetchLatestGitDeps && "--skip-fetch-latest-git-deps" !in initialArguments) { + add("--skip-fetch-latest-git-deps") + } + } + } + override fun dispose() {} } diff --git a/src/main/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatus.kt b/src/main/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatus.kt index afae68d31..5442bc877 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatus.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatus.kt @@ -2,9 +2,11 @@ package org.move.cli.runConfigurations.aptos import com.fasterxml.jackson.core.JacksonException import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.registerKotlinModule import org.intellij.lang.annotations.Language +import org.move.stdext.blankToNull sealed class AptosExitStatus(val message: String) { class Result(message: String): AptosExitStatus(message) @@ -14,22 +16,23 @@ sealed class AptosExitStatus(val message: String) { companion object { @Throws(JacksonException::class) fun fromJson(@Language("JSON") json: String): AptosExitStatus { - val parsedResult = JSON_MAPPER.readValue(json, AptosJsonResult::class.java) - return when { - parsedResult.Error != null -> Error(parsedResult.Error) - parsedResult.Result != null -> Result(parsedResult.Result) - else -> Malformed(json) + val rootNode = JSON_MAPPER.readTree(json) + if (rootNode.has("Result")) { + return Result(nodeToText(rootNode.get("Result"))) } + if (rootNode.has("Error")) { + return Error(nodeToText(rootNode.get("Error"))) + } + return Malformed(json) + } + + private fun nodeToText(jsonNode: JsonNode): String { + // blank for containers + return jsonNode.asText().blankToNull() ?: jsonNode.toString() } } } -@Suppress("PropertyName") -private data class AptosJsonResult( - val Result: String?, - val Error: String? -) - private val JSON_MAPPER: ObjectMapper = ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .registerKotlinModule() diff --git a/src/main/kotlin/org/move/ide/annotator/RsExternalLinterUtils.kt b/src/main/kotlin/org/move/ide/annotator/RsExternalLinterUtils.kt index 4b7963148..33a29d67e 100644 --- a/src/main/kotlin/org/move/ide/annotator/RsExternalLinterUtils.kt +++ b/src/main/kotlin/org/move/ide/annotator/RsExternalLinterUtils.kt @@ -106,7 +106,7 @@ object RsExternalLinterUtils { override fun run(indicator: ProgressIndicator) { widget?.inProgress = true - future.complete(check(aptosCli, args)) + future.complete(check(project, aptosCli, args)) } override fun onFinished() { @@ -118,13 +118,14 @@ object RsExternalLinterUtils { } private fun check( + project: Project, aptosCli: Aptos, aptosCompileArgs: AptosCompileArgs ): RsExternalLinterResult? { ProgressManager.checkCanceled() val started = Instant.now() val output = aptosCli - .checkProject(aptosCompileArgs) + .checkProject(project, aptosCompileArgs) .unwrapOrElse { e -> LOG.error(e) return null diff --git a/src/main/kotlin/org/move/ide/refactoring/MvImportOptimizer.kt b/src/main/kotlin/org/move/ide/refactoring/MvImportOptimizer.kt index acba928fd..6f077de80 100644 --- a/src/main/kotlin/org/move/ide/refactoring/MvImportOptimizer.kt +++ b/src/main/kotlin/org/move/ide/refactoring/MvImportOptimizer.kt @@ -80,14 +80,16 @@ class MvImportOptimizer : ImportOptimizer { private fun removeCurlyBracesIfPossible(rootUseSpeck: MvUseSpeck, psiFactory: MvPsiFactory) { val itemUseSpeck = rootUseSpeck.useGroup?.asTrivial ?: return - val newUseSpeck = psiFactory.useSpeck("0x1::dummy::call") + val newUseSpeck = psiFactory.useSpeck("0x1::dummy::call as mycall") val newUseSpeckPath = newUseSpeck.path newUseSpeckPath.path?.replace(rootUseSpeck.path) itemUseSpeck.path.identifier?.let { newUseSpeckPath.identifier?.replace(it) } - val useAlias = itemUseSpeck.useAlias - if (useAlias != null) { - newUseSpeck.add(useAlias) + val oldUseAlias = itemUseSpeck.useAlias + if (oldUseAlias != null) { + newUseSpeck.useAlias?.replace(oldUseAlias) + } else { + newUseSpeck.useAlias?.delete() } rootUseSpeck.replace(newUseSpeck) diff --git a/src/main/kotlin/org/move/openapiext/utils.kt b/src/main/kotlin/org/move/openapiext/utils.kt index fcd12d210..85af5abf0 100644 --- a/src/main/kotlin/org/move/openapiext/utils.kt +++ b/src/main/kotlin/org/move/openapiext/utils.kt @@ -208,9 +208,7 @@ inline fun Project.nonBlocking(crossinline block: () -> R, crossinline uiCon } @Service(PROJECT) -class RootPluginDisposable: Disposable { - override fun dispose() {} -} +class RootPluginDisposable(val project: Project): Disposable.Default val Project.rootPluginDisposable get() = this.service() diff --git a/src/test/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatusTest.kt b/src/test/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatusTest.kt index 1da6c1a13..ad401c888 100644 --- a/src/test/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatusTest.kt +++ b/src/test/kotlin/org/move/cli/runConfigurations/aptos/AptosExitStatusTest.kt @@ -37,4 +37,23 @@ class AptosExitStatusTest: MvTestBase() { ) check(status is AptosExitStatus.Malformed) } + + fun `test parse array of items`() { + val status = AptosExitStatus.fromJson( + """ + { + "Result": [ + "0000000000000000000000000000000000000000000000000000000000000001::system_addresses", + "0000000000000000000000000000000000000000000000000000000000000001::guid" + ] + } + } + """ + ) + check(status is AptosExitStatus.Result) + check(status.message == + "[\"0000000000000000000000000000000000000000000000000000000000000001::system_addresses\"," + + "\"0000000000000000000000000000000000000000000000000000000000000001::guid\"]", + { status.message }) + } } \ No newline at end of file diff --git a/src/test/kotlin/org/move/ide/refactoring/optimizeImports/OptimizeImportsTest.kt b/src/test/kotlin/org/move/ide/refactoring/optimizeImports/OptimizeImportsTest.kt index 4a6f9fc81..ce6e75bfd 100644 --- a/src/test/kotlin/org/move/ide/refactoring/optimizeImports/OptimizeImportsTest.kt +++ b/src/test/kotlin/org/move/ide/refactoring/optimizeImports/OptimizeImportsTest.kt @@ -321,6 +321,32 @@ module 0x1::main { } """) + fun `test unused import with Self as`() = doTest(""" +module 0x1::pool { + struct X1 {} + public fun create_pool() {} +} +module 0x1::main { + use 0x1::pool::{Self as mypool, X1}; + + fun main() { + mypool::create_pool(); + } +} + """, """ +module 0x1::pool { + struct X1 {} + public fun create_pool() {} +} +module 0x1::main { + use 0x1::pool::Self as mypool; + + fun main() { + mypool::create_pool(); + } +} + """) + fun `test duplicate self import`() = doTest(""" module 0x1::pool { struct X1 {} @@ -377,5 +403,33 @@ module 0x1::main { // let _a = string::utf8(b"hello"); // } //} +// """) + + // todo +// fun `test vector import should be test_only if used only in tests`() = doTest(""" +//module 0x1::vector { +// public fun call() {} +//} +//module 0x1::main { +// use 0x1::vector; +// +// #[test] +// fun test_main() { +// vector::call(); +// } +//} +// """, """ +//module 0x1::vector { +// public fun call() {} +//} +//module 0x1::main { +// #[test_only] +// use 0x1::vector; +// +// #[test] +// fun test_main() { +// vector::call(); +// } +//} // """) }