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

INT: Implement simplify dependency specification intention #7559

Merged
merged 1 commit into from Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,44 @@
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/

package org.rust.toml.intentions

import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.parentsOfType
import org.rust.lang.core.psi.ext.endOffset
import org.rust.toml.isCargoToml
import org.rust.toml.isDependencyListHeader
import org.toml.lang.psi.TomlInlineTable
import org.toml.lang.psi.TomlKeyValue
import org.toml.lang.psi.TomlTable
import org.toml.lang.psi.TomlValue

class SimplifyDependencySpecificationIntention : TomlElementBaseIntentionAction<SimplifyDependencySpecificationIntention.Context>() {
override fun getText() = "Simplify dependency specification"
override fun getFamilyName(): String = text

override fun findApplicableContextInternal(project: Project, editor: Editor, element: PsiElement): Context? {
if (!element.containingFile.isCargoToml) return null

val dependency = element.parentsOfType<TomlKeyValue>()
.firstOrNull { (it.parent as? TomlTable)?.header?.isDependencyListHeader == true } ?: return null

val dependencyValue = dependency.value as? TomlInlineTable ?: return null
val version = dependencyValue.entries.singleOrNull().takeIf {
it?.key?.segments?.singleOrNull()?.text == "version"
}?.value ?: return null

return Context(dependencyValue, version)
}

override fun invoke(project: Project, editor: Editor, ctx: Context) {
val offset = ctx.value.replace(ctx.version.copy())?.endOffset ?: return
editor.caretModel.moveToOffset(offset)
}

class Context(val value: TomlInlineTable, val version: TomlValue)
}
5 changes: 5 additions & 0 deletions toml/src/main/resources/META-INF/toml-only.xml
Expand Up @@ -62,6 +62,11 @@
<category>Rust/Cargo.toml</category>
</intentionAction>

<intentionAction>
<className>org.rust.toml.intentions.SimplifyDependencySpecificationIntention</className>
<category>Rust/Cargo.toml</category>
</intentionAction>

<applicationService serviceInterface="org.rust.toml.crates.local.CratesLocalIndexService"
serviceImplementation="org.rust.toml.crates.local.CratesLocalIndexServiceImpl"
testServiceImplementation="org.rust.toml.crates.local.TestCratesLocalIndexServiceImpl"/>
Expand Down
@@ -0,0 +1,2 @@
[dependencies]
foo = "1.0.0"
@@ -0,0 +1,2 @@
[dependencies]
foo = { version = "1.0.0" }
@@ -0,0 +1,5 @@
<html>
<body>
Simplifies inline table dependency specification.
</body>
</html>
@@ -0,0 +1,49 @@
/*
* Use of this source code is governed by the MIT license that can be
* found in the LICENSE file.
*/

package org.rust.toml.intentions

class SimplifyDependencySpecificationIntentionTest : CargoTomlIntentionTestBase(SimplifyDependencySpecificationIntention::class) {
fun `test availability range`() = checkAvailableInSelectionOnly("""
[dependencies]
<selection>foo = { version = "0.1.0" }</selection>
""")

fun `test unavailable for deps with string value`() = doUnavailableTest("""
[dependencies]
foo = "0.1.0"<caret>
""")

fun `test unavailable with multiple properties`() = doUnavailableTest("""
[dependencies]
foo = { version = "0.1.0", features = [] }<caret>
""")

fun `test unavailable without version property`() = doUnavailableTest("""
[dependencies]
foo = { features = [] }<caret>
""")

fun `test unavailable in other tables`() = doUnavailableTest("""
[foo]
bar = { version = "0.1.0" }<caret>
""")

fun `test replace from key`() = doAvailableTest("""
[dependencies]
<caret>foo = { version = "0.1.0" }
""", """
[dependencies]
foo = "0.1.0"<caret>
""")

fun `test replace from inside value`() = doAvailableTest("""
[dependencies]
foo = { version<caret> = "0.1.0" }
""", """
[dependencies]
foo = "0.1.0"<caret>
""")
}