Skip to content

Commit

Permalink
Merge #4217 #4245
Browse files Browse the repository at this point in the history
4217: TYPE: New interactive inlay type hints support r=vlad20012 a=ortem

![type_hints](https://user-images.githubusercontent.com/4854600/62386077-7458ad80-b55f-11e9-8956-375670ffd342.gif)


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">



Co-authored-by: ortem <ortem00@gmail.com>
Co-authored-by: Mikhail Chernyavsky <mikhail.chernyavsky@jetbrains.com>
  • Loading branch information
3 people committed Sep 2, 2019
3 parents 034d042 + b25c78c + 8599491 commit 93904a3
Show file tree
Hide file tree
Showing 27 changed files with 1,458 additions and 502 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
}
}
88 changes: 88 additions & 0 deletions src/191/main/kotlin/org/rust/ide/hints/RsPlainTypeHint.kt
@@ -0,0 +1,88 @@
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/

package org.rust.ide.hints

import com.intellij.codeInsight.hints.InlayInfo
import com.intellij.codeInsight.hints.Option
import com.intellij.psi.PsiElement
import org.rust.ide.presentation.shortPresentableText
import org.rust.lang.core.psi.*
import org.rust.lang.core.psi.ext.descendantsOfType
import org.rust.lang.core.psi.ext.endOffset
import org.rust.lang.core.psi.ext.patList
import org.rust.lang.core.psi.ext.valueParameters
import org.rust.lang.core.types.declaration
import org.rust.lang.core.types.ty.TyUnknown
import org.rust.lang.core.types.type

enum class RsPlainTypeHint(desc: String, enabled: Boolean) : RsPlainHint {
LET_BINDING_HINT("Show local variable type hints", true) {
override fun provideHints(elem: PsiElement): List<InlayInfo> {
val (expr, pats) = when (elem) {
is RsLetDecl -> {
if (elem.typeReference != null) return emptyList()
elem.expr to listOfNotNull(elem.pat)
}
is RsCondition -> elem.expr to elem.patList
is RsMatchExpr -> elem.expr to elem.matchBody?.matchArmList?.flatMap { it.patList }
else -> return emptyList()
}

var finalPats = pats.orEmpty()
if (smart) {
val declaration = expr?.declaration
if (declaration is RsStructItem || declaration is RsEnumVariant) {
finalPats = finalPats.filter { it !is RsPatIdent }
}
}
return finalPats.flatMap { it.inlayInfo }
}

override fun isApplicable(elem: PsiElement): Boolean = elem is RsLetDecl || elem is RsCondition || elem is RsMatchExpr
},
LAMBDA_PARAMETER_HINT("Show lambda parameter type hints", true) {
override fun provideHints(elem: PsiElement): List<InlayInfo> {
val element = elem as? RsLambdaExpr ?: return emptyList()
return element.valueParameters
.filter { it.typeReference == null }
.mapNotNull { it.pat }
.flatMap { it.inlayInfo }
}

override fun isApplicable(elem: PsiElement): Boolean = elem is RsLambdaExpr
},
FOR_PARAMETER_HINT("Show type hints for for loops parameter", true) {
override fun provideHints(elem: PsiElement): List<InlayInfo> {
val element = elem as? RsForExpr ?: return emptyList()
return element.pat?.inlayInfo ?: emptyList()
}

override fun isApplicable(elem: PsiElement): Boolean = elem is RsForExpr
};

val smart get() = RsPlainHint.SMART_HINTING.get()
override val enabled get() = option.get()
override val option = Option("SHOW_${this.name}", desc, enabled)
}

private val RsPat.inlayInfo: List<InlayInfo>
get() = descendantsOfType<RsPatBinding>().asSequence()
.filter { patBinding ->
when {
// "ignored" bindings like `let _a = 123;`
patBinding.referenceName.startsWith("_") -> false
// match foo {
// None -> {} // None is enum variant, so we don't want to provide type hint for it
// _ -> {}
// }
patBinding.reference.resolve() is RsEnumVariant -> false
else -> true
}
}
.map { it to it.type }
.filterNot { (_, type) -> type is TyUnknown }
.map { (patBinding, type) -> InlayInfo(": " + type.shortPresentableText, patBinding.endOffset) }
.toList()

0 comments on commit 93904a3

Please sign in to comment.