Introduce "Add missing 'class' keyword" intention
#KT-14884 Fixed
This commit is contained in:
committed by
Vladimir Dolzhenko
parent
9634e6fba3
commit
b4c62cdb52
@@ -1644,6 +1644,11 @@
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddMissingClassKeywordIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<lang.inspectionSuppressor language="kotlin" implementationClass="org.jetbrains.kotlin.idea.inspections.KotlinInspectionSuppressor"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
enum <spot>class</spot> E
|
||||
+1
@@ -0,0 +1 @@
|
||||
enum E
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention adds a missing <b>class</b> keyword.
|
||||
</body>
|
||||
</html>
|
||||
@@ -2195,5 +2195,5 @@ move.refactoring.error.text.cannot.perform.refactoring.since.the.following.files
|
||||
kotlin.script.definitions.model.name.is.enabled=Is Enabled
|
||||
kotlin.script.definitions.model.name.pattern.extension=Pattern/Extension
|
||||
kotlin.script.definitions.model.name.name=Name
|
||||
codestyle.name.kotlin=Kotlin
|
||||
add.missing.class.keyword=Add missing 'class' keyword
|
||||
fix.move.typealias.to.top.level=Move typealias to top level
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiErrorElement
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class AddMissingClassKeywordIntention : SelfTargetingIntention<PsiElement>(
|
||||
PsiElement::class.java,
|
||||
KotlinBundle.message("add.missing.class.keyword")
|
||||
) {
|
||||
companion object {
|
||||
private val targetKeywords = listOf(
|
||||
KtTokens.ANNOTATION_KEYWORD,
|
||||
KtTokens.DATA_KEYWORD,
|
||||
KtTokens.SEALED_KEYWORD,
|
||||
KtTokens.INNER_KEYWORD
|
||||
)
|
||||
}
|
||||
|
||||
override fun isApplicableTo(element: PsiElement, caretOffset: Int): Boolean {
|
||||
if (element.node?.elementType != KtTokens.IDENTIFIER) return false
|
||||
val ktClass = element.parent as? KtClass
|
||||
if (ktClass == null) {
|
||||
val errorElement = element.parent as? PsiErrorElement ?: return false
|
||||
val modifierList = errorElement.getPrevSiblingIgnoringWhitespaceAndComments() as? KtModifierList ?: return false
|
||||
return targetKeywords.any { modifierList.hasModifier(it) }
|
||||
} else {
|
||||
return ktClass.isEnum() && ktClass.getClassKeyword() == null
|
||||
}
|
||||
}
|
||||
|
||||
override fun applyTo(element: PsiElement, editor: Editor?) {
|
||||
val document = editor?.document ?: return
|
||||
val targetElement = (element.parent as? PsiErrorElement) ?: element
|
||||
document.insertString(targetElement.startOffset, "class ")
|
||||
PsiDocumentManager.getInstance(element.project).commitDocument(document)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.intentions.AddMissingClassKeywordIntention
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
// DISABLE-ERRORS
|
||||
abstract <caret>Foo {
|
||||
abstract fun foo()
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
annotation <caret>Foo
|
||||
@@ -0,0 +1 @@
|
||||
annotation class Foo
|
||||
@@ -0,0 +1,7 @@
|
||||
// DISABLE-ERRORS
|
||||
annotation class Ann
|
||||
|
||||
@Ann
|
||||
private data <caret>Foo(val s: String) {
|
||||
fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// DISABLE-ERRORS
|
||||
annotation class Ann
|
||||
|
||||
@Ann
|
||||
private data class Foo(val s: String) {
|
||||
fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// IS_APPLICABLE: false
|
||||
private data class <caret>Foo(val s: String)
|
||||
@@ -0,0 +1,3 @@
|
||||
enum Foo<caret>(val s: String) {
|
||||
A("a"), B("b")
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
enum class Foo(val s: String) {
|
||||
A("a"), B("b")
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
enum class <caret>Foo(val s: String) {
|
||||
A("a"), B("b")
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
inner <caret>Foo
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
inner class Foo
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// DISABLE-ERRORS
|
||||
sealed <caret>Foo {
|
||||
abstract fun foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// DISABLE-ERRORS
|
||||
sealed class Foo {
|
||||
abstract fun foo()
|
||||
}
|
||||
@@ -1130,6 +1130,59 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/addMissingClassKeyword")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddMissingClassKeyword extends AbstractIntentionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("abstract.kt")
|
||||
public void testAbstract() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/abstract.kt");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddMissingClassKeyword() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/addMissingClassKeyword"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("annottion.kt")
|
||||
public void testAnnottion() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/annottion.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("data.kt")
|
||||
public void testData() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/data.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("dataHasClassKeyword.kt")
|
||||
public void testDataHasClassKeyword() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/dataHasClassKeyword.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enum.kt")
|
||||
public void testEnum() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/enum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumHasClassKeyword.kt")
|
||||
public void testEnumHasClassKeyword() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/enumHasClassKeyword.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inner.kt")
|
||||
public void testInner() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/inner.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sealed.kt")
|
||||
public void testSealed() throws Exception {
|
||||
runTest("idea/testData/intentions/addMissingClassKeyword/sealed.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/addMissingDestructuring")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user