JvmCommonIntentionActionsFactory in Kotlin
This commit is contained in:
committed by
Nikolay Krasko
parent
548e86285c
commit
0694f2d0c5
@@ -2480,6 +2480,7 @@
|
|||||||
<projectOpenProcessor implementation="org.jetbrains.kotlin.gradle.GradleKotlinDSLProjectOpenProcessor"/>
|
<projectOpenProcessor implementation="org.jetbrains.kotlin.gradle.GradleKotlinDSLProjectOpenProcessor"/>
|
||||||
<projectImportProvider implementation="org.jetbrains.kotlin.gradle.GradleKotlinDSLProjectImportProvider"/>
|
<projectImportProvider implementation="org.jetbrains.kotlin.gradle.GradleKotlinDSLProjectImportProvider"/>
|
||||||
|
|
||||||
|
<codeInsight.intention.jvmCommonIntentionActionsFactory language="kotlin" implementationClass="org.jetbrains.kotlin.idea.intentions.KotlinCommonModifications"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.uast">
|
<extensions defaultExtensionNs="org.jetbrains.uast">
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.intentions
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.intention.*
|
||||||
|
import com.intellij.psi.PsiModifier
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
|
import org.jetbrains.uast.UDeclaration
|
||||||
|
|
||||||
|
|
||||||
|
class KotlinCommonModifications : JvmCommonIntentionActionsFactory() {
|
||||||
|
override fun createChangeModifierAction(declaration: UDeclaration, modifier: String, shouldPresent: Boolean): IntentionAction? {
|
||||||
|
val kModifierOwner = (declaration.psi as? KtLightElement<*, *>?)?.kotlinOrigin as? KtModifierListOwner?
|
||||||
|
?: throw IllegalArgumentException("$declaration is expected to contain KtLightElement with KtModifierListOwner")
|
||||||
|
|
||||||
|
val (kToken, shouldPresentMapped) = if (PsiModifier.FINAL == modifier)
|
||||||
|
KtTokens.OPEN_KEYWORD to !shouldPresent
|
||||||
|
else
|
||||||
|
javaPsiModifiersMapping[modifier] to shouldPresent
|
||||||
|
|
||||||
|
if (kToken == null) return null
|
||||||
|
return if (shouldPresentMapped)
|
||||||
|
AddModifierFix.createIfApplicable(kModifierOwner, kToken)
|
||||||
|
else
|
||||||
|
RemoveModifierFix(kModifierOwner, kToken, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val javaPsiModifiersMapping = mapOf(
|
||||||
|
PsiModifier.PRIVATE to KtTokens.PRIVATE_KEYWORD,
|
||||||
|
PsiModifier.PUBLIC to KtTokens.PUBLIC_KEYWORD,
|
||||||
|
PsiModifier.PROTECTED to KtTokens.PUBLIC_KEYWORD,
|
||||||
|
PsiModifier.ABSTRACT to KtTokens.ABSTRACT_KEYWORD
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -100,21 +100,24 @@ open class AddModifierFix(
|
|||||||
return object : KotlinSingleIntentionActionFactory() {
|
return object : KotlinSingleIntentionActionFactory() {
|
||||||
public override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
public override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val modifierListOwner = QuickFixUtil.getParentElementOfType(diagnostic, modifierOwnerClass) ?: return null
|
val modifierListOwner = QuickFixUtil.getParentElementOfType(diagnostic, modifierOwnerClass) ?: return null
|
||||||
|
return createIfApplicable(modifierListOwner, modifier)
|
||||||
if (modifier == KtTokens.ABSTRACT_KEYWORD) {
|
|
||||||
if (modifierListOwner is KtObjectDeclaration) return null
|
|
||||||
if (modifierListOwner is KtEnumEntry) return null
|
|
||||||
if (modifierListOwner is KtDeclaration && modifierListOwner !is KtClass) {
|
|
||||||
val parentClassOrObject = modifierListOwner.containingClassOrObject ?: return null
|
|
||||||
if (parentClassOrObject is KtObjectDeclaration) return null
|
|
||||||
if (parentClassOrObject is KtEnumEntry) return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return AddModifierFix(modifierListOwner, modifier)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createIfApplicable(modifierListOwner: KtModifierListOwner, modifier: KtModifierKeywordToken): AddModifierFix? {
|
||||||
|
if (modifier == ABSTRACT_KEYWORD || modifier == OPEN_KEYWORD) {
|
||||||
|
if (modifierListOwner is KtObjectDeclaration) return null
|
||||||
|
if (modifierListOwner is KtEnumEntry) return null
|
||||||
|
if (modifierListOwner is KtDeclaration && modifierListOwner !is KtClass) {
|
||||||
|
val parentClassOrObject = modifierListOwner.containingClassOrObject ?: return null
|
||||||
|
if (parentClassOrObject is KtObjectDeclaration) return null
|
||||||
|
if (parentClassOrObject is KtEnumEntry) return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AddModifierFix(modifierListOwner, modifier)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object MakeClassOpenFactory : KotlinSingleIntentionActionFactory() {
|
object MakeClassOpenFactory : KotlinSingleIntentionActionFactory() {
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.intention.JvmCommonIntentionActionsFactory
|
||||||
|
import com.intellij.lang.Language
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.psi.PsiModifier
|
||||||
|
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
|
||||||
|
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||||
|
import org.jetbrains.uast.UDeclaration
|
||||||
|
import org.jetbrains.uast.UastContext
|
||||||
|
import org.jetbrains.uast.convert
|
||||||
|
import org.junit.Assert
|
||||||
|
|
||||||
|
|
||||||
|
class CommonModificationsTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||||
|
|
||||||
|
fun testMakeNotFinal() {
|
||||||
|
myFixture.configureByText("foo.kt", """
|
||||||
|
class Foo {
|
||||||
|
fun bar<caret>(){}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
myFixture.launchAction(codeModifications.createChangeModifierAction(uastElementAtCaret(myFixture), PsiModifier.FINAL, false )!!)
|
||||||
|
myFixture.checkResult("""
|
||||||
|
class Foo {
|
||||||
|
open fun bar(){}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testMakePrivate() {
|
||||||
|
myFixture.configureByText("foo.kt", """
|
||||||
|
class Foo<caret> {
|
||||||
|
fun bar(){}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
myFixture.launchAction(codeModifications.createChangeModifierAction(uastElementAtCaret(myFixture), PsiModifier.PRIVATE, true )!!)
|
||||||
|
myFixture.checkResult("""
|
||||||
|
private class Foo {
|
||||||
|
fun bar(){}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testMakeNotPrivate() {
|
||||||
|
myFixture.configureByText("foo.kt", """
|
||||||
|
private class Foo<caret> {
|
||||||
|
fun bar(){}
|
||||||
|
}
|
||||||
|
""".trim())
|
||||||
|
|
||||||
|
myFixture.launchAction(codeModifications.createChangeModifierAction(uastElementAtCaret(myFixture), PsiModifier.PRIVATE, false )!!)
|
||||||
|
myFixture.checkResult("""
|
||||||
|
class Foo {
|
||||||
|
fun bar(){}
|
||||||
|
}
|
||||||
|
""".trim(), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testDontMakeFunInObjectsOpen() {
|
||||||
|
myFixture.configureByText("foo.kt", """
|
||||||
|
object Foo {
|
||||||
|
fun bar<caret>(){}
|
||||||
|
}
|
||||||
|
""".trim())
|
||||||
|
Assert.assertNull(codeModifications.createChangeModifierAction(uastElementAtCaret(myFixture), PsiModifier.FINAL, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun uastElementAtCaret(myFixture: CodeInsightTestFixture): UDeclaration {
|
||||||
|
val elementAtCaret = myFixture.elementAtCaret
|
||||||
|
val uastContext = ServiceManager.getService(elementAtCaret.project, UastContext::class.java) ?: error("UastContext not found")
|
||||||
|
val uastLanguagePlugin = uastContext.findPlugin(elementAtCaret) ?: error("Language plugin was not found for $this (${this.javaClass.name})")
|
||||||
|
return uastLanguagePlugin.convert<UDeclaration>(elementAtCaret, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val codeModifications: JvmCommonIntentionActionsFactory
|
||||||
|
get() = JvmCommonIntentionActionsFactory.forLanguage(Language.findLanguageByID("kotlin")!!)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user