Skip to content

Commit

Permalink
Merge #4245 #4323 #4346
Browse files Browse the repository at this point in the history
4245: RUN: Add "Restart" and "Stop" buttons to Cargo build tool window r=ortem a=mchernyavsky

Relates to #3926.

<img width="315" alt="restart-stop" src="https://user-images.githubusercontent.com/6079006/62889650-77ffe780-bd4a-11e9-9b30-8e3ca5869f2c.png">



4323: INT: Handle trailing comma in ChopListIntention r=mchernyavsky a=ortem



4346: Fix switch to AST when resolving nested macro with the new engine r=vlad20012 a=vlad20012

The bug was introduced in #3750 (not released yet)

Co-authored-by: Mikhail Chernyavsky <mikhail.chernyavsky@jetbrains.com>
Co-authored-by: ortem <ortem00@gmail.com>
Co-authored-by: vlad20012 <beskvlad@gmail.com>
  • Loading branch information
4 people committed Sep 2, 2019
4 parents 07a0cab + 8599491 + c8e502a + 386ab71 commit 477a3ff
Show file tree
Hide file tree
Showing 19 changed files with 300 additions and 112 deletions.
Expand Up @@ -5,16 +5,11 @@

package org.rust.clion.cargo

import com.intellij.execution.ExecutorRegistry
import com.intellij.execution.RunManager
import com.intellij.execution.executors.DefaultRunExecutor
import com.intellij.execution.impl.RunManagerImpl
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.execution.runners.ProgramRunner
import com.intellij.openapi.project.Project
import com.jetbrains.cidr.cpp.execution.build.CLionBuildConfigurationProvider
import org.rust.cargo.runconfig.CargoCommandRunner
import org.rust.cargo.runconfig.buildtool.CargoBuildManager.createBuildEnvironment
import org.rust.cargo.runconfig.buildtool.CargoBuildManager.getBuildConfiguration
import org.rust.cargo.runconfig.command.CargoCommandConfiguration

Expand All @@ -24,10 +19,7 @@ class CargoBuildConfigurationProvider : CLionBuildConfigurationProvider {
val configuration = runManager.selectedConfiguration?.configuration as? CargoCommandConfiguration
?: return emptyList()
val buildConfiguration = getBuildConfiguration(configuration) ?: return emptyList()
val executor = ExecutorRegistry.getInstance().getExecutorById(DefaultRunExecutor.EXECUTOR_ID)
val runner = ProgramRunner.findRunnerById(CargoCommandRunner.RUNNER_ID) ?: return emptyList()
val settings = RunnerAndConfigurationSettingsImpl(runManager, buildConfiguration)
val environment = ExecutionEnvironment(executor, runner, settings, project)
val environment = createBuildEnvironment(buildConfiguration) ?: return emptyList()
return listOf(CLionCargoBuildConfiguration(buildConfiguration, environment))
}
}
Expand Up @@ -11,6 +11,9 @@ import com.intellij.build.BuildProgressListener
import com.intellij.build.events.BuildEvent
import com.intellij.build.output.BuildOutputInstantReaderImpl
import com.intellij.build.output.BuildOutputParser
import com.intellij.execution.ExecutionListener
import com.intellij.execution.ExecutionManager
import com.intellij.execution.process.ProcessHandler
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.openapi.progress.EmptyProgressIndicator
import com.intellij.openapi.util.Key
Expand All @@ -29,13 +32,6 @@ fun BuildOutputInstantReaderImpl.closeAndGetFuture(): CompletableFuture<Unit> =

fun BuildProgressListener.onEvent(parentEventId: Any, event: BuildEvent) = onEvent(event)

typealias CargoPatch = (CargoCommandLine) -> CargoCommandLine

val ExecutionEnvironment.cargoPatches: MutableList<CargoPatch>
get() = putUserDataIfAbsent(CARGO_PATCHES, mutableListOf())

private val CARGO_PATCHES: Key<MutableList<CargoPatch>> = Key.create("CARGO.PATCHES")

object EmptyBuildProgressListener : BuildProgressListener {
override fun onEvent(event: BuildEvent) = Unit
}
Expand All @@ -49,18 +45,3 @@ class MockBuildProgressListener : BuildProgressListener {
_eventHistory.add(event)
}
}

class MockProgressIndicator : EmptyProgressIndicator() {
private val _textHistory: MutableList<String?> = mutableListOf()
val textHistory: List<String?> get() = _textHistory

override fun setText(text: String?) {
super.setText(text)
_textHistory += text
}

override fun setText2(text: String?) {
super.setText2(text)
_textHistory += text
}
}
51 changes: 0 additions & 51 deletions src/192/main/kotlin/org/rust/cargo/runconfig/buildtool/Utils.kt

This file was deleted.

@@ -0,0 +1,25 @@
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/

@file:Suppress("UnstableApiUsage")

package org.rust.cargo.runconfig.buildtool

import com.intellij.build.BuildProgressListener
import com.intellij.build.events.BuildEvent

object EmptyBuildProgressListener : BuildProgressListener {
override fun onEvent(buildId: Any, event: BuildEvent) = Unit
}

@Suppress("UnstableApiUsage")
class MockBuildProgressListener : BuildProgressListener {
private val _eventHistory: MutableList<BuildEvent> = mutableListOf()
val eventHistory: List<BuildEvent> get() = _eventHistory

override fun onEvent(buildId: Any, event: BuildEvent) {
_eventHistory.add(event)
}
}
Expand Up @@ -9,12 +9,20 @@ import com.intellij.build.BuildProgressListener
import com.intellij.build.DefaultBuildDescriptor
import com.intellij.build.events.impl.*
import com.intellij.build.output.BuildOutputInstantReaderImpl
import com.intellij.execution.process.AnsiEscapeDecoder
import com.intellij.execution.process.ProcessAdapter
import com.intellij.execution.process.ProcessEvent
import com.intellij.execution.process.ProcessOutputTypes
import com.intellij.execution.ExecutorRegistry
import com.intellij.execution.actions.StopProcessAction
import com.intellij.execution.impl.ExecutionManagerImpl
import com.intellij.execution.process.*
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.execution.runners.ExecutionUtil
import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VfsUtil
import org.rust.cargo.CargoConstants
import org.rust.cargo.runconfig.RsAnsiEscapeDecoder
Expand All @@ -40,6 +48,7 @@ class CargoBuildAdapter(
private val textBuffer: MutableList<String> = mutableListOf()

init {
context.environment.notifyProcessStarted(context.processHandler)
val descriptor = DefaultBuildDescriptor(
context.buildId,
"Run Cargo command",
Expand All @@ -48,6 +57,8 @@ class CargoBuildAdapter(
)
val buildStarted = StartBuildEventImpl(descriptor, "${context.taskName} running...")
.withExecutionFilters(*createFilters(context.cargoProject).toTypedArray())
.withRestartAction(createRerunAction(context.processHandler, context.environment))
.withRestartAction(createStopAction(context.processHandler))
buildProgressListener.onEvent(context.buildId, buildStarted)
}

Expand All @@ -72,12 +83,18 @@ class CargoBuildAdapter(
buildProgressListener.onEvent(context.buildId, buildFinished)
context.finished(isSuccess)

context.environment.notifyProcessTerminated(event.processHandler, event.exitCode)

val targetPath = context.workingDirectory.resolve(CargoConstants.ProjectLayout.target)
val targetDir = VfsUtil.findFile(targetPath, true) ?: return@whenComplete
VfsUtil.markDirtyAndRefresh(true, true, true, targetDir)
}
}

override fun processWillTerminate(event: ProcessEvent, willBeDestroyed: Boolean) {
context.environment.notifyProcessTerminating(event.processHandler)
}

override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) {
var rawText = event.text
if (SystemInfo.isWindows && rawText.matches(BUILD_PROGRESS_INNER_RE)) {
Expand Down Expand Up @@ -112,5 +129,37 @@ class CargoBuildAdapter(
companion object {
private val BUILD_PROGRESS_INNER_RE: Regex = """ \[ *=*>? *] \d+/\d+: [\w\-(.)]+(, [\w\-(.)]+)*""".toRegex()
private val BUILD_PROGRESS_FULL_RE: Regex = """ *Building$BUILD_PROGRESS_INNER_RE( *[\r\n])*""".toRegex()

private fun createStopAction(processHandler: ProcessHandler): StopProcessAction =
StopProcessAction("Stop", "Stop", processHandler)

private fun createRerunAction(processHandler: ProcessHandler, environment: ExecutionEnvironment): RestartProcessAction =
RestartProcessAction(processHandler, environment)

private class RestartProcessAction(
private val processHandler: ProcessHandler,
private val environment: ExecutionEnvironment
) : DumbAwareAction(), AnAction.TransparentUpdate {
private val isEnabled: Boolean
get() {
val project = environment.project
val settings = environment.runnerAndConfigurationSettings
return (!DumbService.isDumb(project) || settings == null || settings.type.isDumbAware) &&
!ExecutorRegistry.getInstance().isStarting(environment) &&
!processHandler.isProcessTerminating
}

override fun update(event: AnActionEvent) {
val presentation = event.presentation
presentation.text = "Rerun '${StringUtil.escapeMnemonics(environment.runProfile.name)}'"
presentation.icon = if (processHandler.isProcessTerminated) AllIcons.Actions.Compile else AllIcons.Actions.Restart
presentation.isEnabled = isEnabled
}

override fun actionPerformed(event: AnActionEvent) {
ExecutionManagerImpl.stopProcess(processHandler)
ExecutionUtil.restart(environment)
}
}
}
}
Expand Up @@ -128,6 +128,8 @@ class CargoBuildContext(
warnings = warnings,
message = "$taskName canceled"
))

environment.notifyProcessNotStarted()
}

companion object {
Expand Down
Expand Up @@ -8,7 +8,14 @@ package org.rust.cargo.runconfig.buildtool
import com.intellij.build.BuildContentManager
import com.intellij.build.BuildViewManager
import com.intellij.execution.ExecutionException
import com.intellij.execution.ExecutorRegistry
import com.intellij.execution.RunManager
import com.intellij.execution.configuration.EnvironmentVariablesData
import com.intellij.execution.executors.DefaultRunExecutor
import com.intellij.execution.impl.RunManagerImpl
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.execution.runners.ProgramRunner
import com.intellij.notification.NotificationGroup
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.TransactionGuard
Expand All @@ -32,6 +39,7 @@ import com.intellij.util.text.SemVer
import com.intellij.util.ui.UIUtil
import org.jetbrains.annotations.TestOnly
import org.rust.cargo.project.model.cargoProjects
import org.rust.cargo.runconfig.CargoCommandRunner
import org.rust.cargo.runconfig.CargoRunState
import org.rust.cargo.runconfig.addFormatJsonOption
import org.rust.cargo.runconfig.command.CargoCommandConfiguration
Expand Down Expand Up @@ -113,6 +121,7 @@ object CargoBuildManager {
context: CargoBuildContext,
doExecute: CargoBuildContext.() -> Unit
): FutureResult<CargoBuildResult> {
context.environment.notifyProcessStartScheduled()
val processCreationLock = Any()

when {
Expand Down Expand Up @@ -160,6 +169,7 @@ object CargoBuildManager {

ApplicationManager.getApplication().executeOnPooledThread {
if (!context.waitAndStart()) return@executeOnPooledThread
context.environment.notifyProcessStarting()

if (isUnitTestMode) {
context.doExecute()
Expand Down Expand Up @@ -218,6 +228,16 @@ object CargoBuildManager {
return buildConfiguration
}

fun createBuildEnvironment(buildConfiguration: CargoCommandConfiguration): ExecutionEnvironment? {
require(isBuildConfiguration(buildConfiguration))
val project = buildConfiguration.project
val runManager = RunManager.getInstance(project) as? RunManagerImpl ?: return null
val executor = ExecutorRegistry.getInstance().getExecutorById(DefaultRunExecutor.EXECUTOR_ID) ?: return null
val runner = ProgramRunner.findRunnerById(CargoCommandRunner.RUNNER_ID) ?: return null
val settings = RunnerAndConfigurationSettingsImpl(runManager, buildConfiguration)
return ExecutionEnvironment(executor, runner, settings, project)
}

fun showBuildNotification(
project: Project,
messageType: MessageType,
Expand Down
Expand Up @@ -13,6 +13,7 @@ import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.util.Key
import com.intellij.task.ProjectTaskManager
import org.rust.cargo.runconfig.buildtool.CargoBuildManager.createBuildEnvironment
import org.rust.cargo.runconfig.buildtool.CargoBuildManager.getBuildConfiguration
import org.rust.cargo.runconfig.command.CargoCommandConfiguration
import java.util.concurrent.CompletableFuture
Expand All @@ -30,12 +31,17 @@ class CargoBuildTaskProvider : BeforeRunTaskProvider<CargoBuildTaskProvider.Buil
override fun executeTask(
context: DataContext,
configuration: RunConfiguration,
env: ExecutionEnvironment,
environment: ExecutionEnvironment,
task: BuildTask
): Boolean {
if (configuration !is CargoCommandConfiguration) return false

val buildConfiguration = getBuildConfiguration(configuration) ?: return true
val buildableElement = CargoBuildConfiguration(buildConfiguration, env)
val buildEnvironment = createBuildEnvironment(buildConfiguration)
?.also { environment.copyUserDataTo(it) }
?: return false
val buildableElement = CargoBuildConfiguration(buildConfiguration, buildEnvironment)

val result = CompletableFuture<Boolean>()
ProjectTaskManager.getInstance(configuration.project).build(arrayOf(buildableElement)) {
result.complete(it.errors == 0 && !it.isAborted)
Expand Down
Expand Up @@ -98,9 +98,9 @@ class CargoBuildTaskRunner : ProjectTaskRunner() {
return cargoProjects.mapNotNull { cargoProject ->
val commandLine = CargoCommandLine.forProject(cargoProject, "build", additionalArguments)
val settings = runManager.createCargoCommandRunConfiguration(commandLine)
val executionEnvironment = ExecutionEnvironment(executor, runner, settings, project)
val environment = ExecutionEnvironment(executor, runner, settings, project)
val configuration = settings.configuration as? CargoCommandConfiguration ?: return@mapNotNull null
val buildableElement = CargoBuildConfiguration(configuration, executionEnvironment)
val buildableElement = CargoBuildConfiguration(configuration, environment)
ProjectModelBuildTaskImpl(buildableElement, false)
}
}
Expand Down

0 comments on commit 477a3ff

Please sign in to comment.