mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 11:50:54 +07:00
[kotlin] Port AddAnnotationUseSiteTargetIntention to K2
^KTIJ-31237 GitOrigin-RevId: 1eb82f05e36ee335650023880761bca01fd1440a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
71a3fd096f
commit
1caa8c6de1
@@ -0,0 +1,148 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions
|
||||
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.openapi.ui.popup.ListPopupStep
|
||||
import com.intellij.openapi.ui.popup.PopupStep
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.util.PlatformIcons
|
||||
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
|
||||
import org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.AddAnnotationUseSiteTargetUtils.addUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
|
||||
object AddAnnotationUseSiteTargetUtils {
|
||||
context(KaSession)
|
||||
@OptIn(KaExperimentalApi::class)
|
||||
fun KtAnnotationEntry.getApplicableUseSiteTargets(): List<AnnotationUseSiteTarget> {
|
||||
val symbol = typeReference?.type?.expandedSymbol
|
||||
val applicableTargets = symbol?.annotationApplicableTargets?.toSet().orEmpty()
|
||||
return applicableUseSiteTargets(applicableTargets)
|
||||
}
|
||||
|
||||
fun KtAnnotationEntry.applicableUseSiteTargets(applicableTargets: Set<KotlinTarget>): List<AnnotationUseSiteTarget> {
|
||||
if (useSiteTarget != null) return emptyList()
|
||||
val annotationShortName = this.shortName ?: return emptyList()
|
||||
val modifierList = getStrictParentOfType<KtModifierList>() ?: return emptyList()
|
||||
val annotated = modifierList.owner as? KtElement ?: return emptyList()
|
||||
|
||||
val candidateTargets = when (annotated) {
|
||||
is KtParameter -> if (annotated.getStrictParentOfType<KtPrimaryConstructor>() != null) when (annotated.valOrVarKeyword?.node?.elementType) {
|
||||
KtTokens.VAR_KEYWORD -> listOf(CONSTRUCTOR_PARAMETER, FIELD, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, SETTER_PARAMETER)
|
||||
|
||||
KtTokens.VAL_KEYWORD -> listOf(CONSTRUCTOR_PARAMETER, FIELD, PROPERTY, PROPERTY_GETTER)
|
||||
|
||||
else -> emptyList()
|
||||
}
|
||||
else emptyList()
|
||||
|
||||
is KtProperty -> when {
|
||||
annotated.delegate != null -> listOf(PROPERTY, PROPERTY_GETTER, PROPERTY_DELEGATE_FIELD)
|
||||
|
||||
!annotated.isLocal -> {
|
||||
val backingField = LightClassUtil.getLightClassPropertyMethods(annotated).backingField
|
||||
if (annotated.isVar) {
|
||||
if (backingField != null) listOf(FIELD, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, SETTER_PARAMETER)
|
||||
else listOf(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, SETTER_PARAMETER)
|
||||
} else {
|
||||
if (backingField != null) listOf(FIELD, PROPERTY, PROPERTY_GETTER)
|
||||
else listOf(PROPERTY, PROPERTY_GETTER)
|
||||
}
|
||||
}
|
||||
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
is KtTypeReference -> listOf(RECEIVER)
|
||||
else -> emptyList()
|
||||
}.toMutableList()
|
||||
if (candidateTargets.isEmpty()) return emptyList()
|
||||
|
||||
val existingTargets = modifierList.annotationEntries.mapNotNull {
|
||||
if (annotationShortName == it.shortName) it.useSiteTarget?.getAnnotationUseSiteTarget() else null
|
||||
}
|
||||
if (existingTargets.isNotEmpty()) {
|
||||
candidateTargets.removeIf { it in existingTargets }
|
||||
if (candidateTargets.isEmpty()) return emptyList()
|
||||
}
|
||||
|
||||
if (applicableTargets.isNotEmpty()) {
|
||||
candidateTargets.removeIf { KotlinTarget.USE_SITE_MAPPING[it] !in applicableTargets }
|
||||
if (candidateTargets.isEmpty()) return emptyList()
|
||||
}
|
||||
|
||||
return if (isUnitTestMode()) {
|
||||
val chosenTarget = containingKtFile.findDescendantOfType<PsiComment>()
|
||||
?.takeIf { it.text.startsWith("// CHOOSE_USE_SITE_TARGET:") }?.text?.split(":")?.getOrNull(1)?.trim()
|
||||
if (chosenTarget.isNullOrBlank()) candidateTargets.take(1)
|
||||
else candidateTargets.asSequence().filter { it.renderName == chosenTarget }.take(1).toList()
|
||||
} else {
|
||||
candidateTargets
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun KtAnnotationEntry.addUseSiteTarget(useSiteTargets: List<AnnotationUseSiteTarget>, editor: Editor?) {
|
||||
val project = this.project
|
||||
if (!isPhysical) { // For preview
|
||||
if (useSiteTargets.isNotEmpty()) {
|
||||
doAddUseSiteTarget(useSiteTargets.first())
|
||||
}
|
||||
return
|
||||
}
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
if (useSiteTargets.size == 1 || editor == null) addUseSiteTarget(useSiteTargets.first(), project)
|
||||
else JBPopupFactory.getInstance().createListPopup(createListPopupStep(this, useSiteTargets, project))
|
||||
.showInBestPositionFor(editor)
|
||||
}
|
||||
}
|
||||
|
||||
fun KtAnnotationEntry.addUseSiteTarget(
|
||||
useSiteTarget: AnnotationUseSiteTarget, project: Project
|
||||
) {
|
||||
project.executeWriteCommand(KotlinBundle.message("add.use.site.target")) {
|
||||
doAddUseSiteTarget(useSiteTarget)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtAnnotationEntry.doAddUseSiteTarget(useSiteTarget: AnnotationUseSiteTarget) {
|
||||
replace(KtPsiFactory(project).createAnnotationEntry("@${useSiteTarget.renderName}:${text.drop(1)}"))
|
||||
}
|
||||
|
||||
private fun createListPopupStep(
|
||||
annotationEntry: KtAnnotationEntry, useSiteTargets: List<AnnotationUseSiteTarget>, project: Project
|
||||
): ListPopupStep<*> {
|
||||
return object : BaseListPopupStep<AnnotationUseSiteTarget>(KotlinBundle.message("title.choose.use.site.target"), useSiteTargets) {
|
||||
override fun isAutoSelectionEnabled() = false
|
||||
|
||||
override fun onChosen(selectedValue: AnnotationUseSiteTarget, finalChoice: Boolean): PopupStep<*>? {
|
||||
if (finalChoice) {
|
||||
annotationEntry.addUseSiteTarget(selectedValue, project)
|
||||
}
|
||||
return PopupStep.FINAL_CHOICE
|
||||
}
|
||||
|
||||
override fun getIconFor(value: AnnotationUseSiteTarget) = PlatformIcons.ANNOTATION_TYPE_ICON
|
||||
|
||||
override fun getTextFor(value: AnnotationUseSiteTarget): String {
|
||||
@NlsSafe val renderName = value.renderName
|
||||
return renderName
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,6 +387,12 @@
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.k2.codeinsight.intentions.AddAnnotationUseSiteTargetIntention</className>
|
||||
<bundleName>messages.KotlinBundle</bundleName>
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.k2.codeinsight.intentions
|
||||
|
||||
import com.intellij.modcommand.ActionContext
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.KotlinApplicableModCommandAction
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.AddAnnotationUseSiteTargetUtils.addUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.AddAnnotationUseSiteTargetUtils.getApplicableUseSiteTargets
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
|
||||
internal class AddAnnotationUseSiteTargetIntention :
|
||||
KotlinApplicableModCommandAction<KtAnnotationEntry, List<AnnotationUseSiteTarget>>(KtAnnotationEntry::class) {
|
||||
|
||||
override fun getFamilyName(): String = KotlinBundle.message("add.use.site.target")
|
||||
|
||||
context(KaSession)
|
||||
override fun prepareContext(element: KtAnnotationEntry): List<AnnotationUseSiteTarget>? {
|
||||
val useSiteTargets = element.getApplicableUseSiteTargets()
|
||||
return useSiteTargets.takeIf { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
override fun invoke(
|
||||
actionContext: ActionContext,
|
||||
element: KtAnnotationEntry,
|
||||
elementContext: List<AnnotationUseSiteTarget>,
|
||||
updater: ModPsiUpdater,
|
||||
) {
|
||||
element.addUseSiteTarget(elementContext, null)
|
||||
}
|
||||
}
|
||||
@@ -7709,7 +7709,634 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest {
|
||||
|
||||
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget")
|
||||
public abstract static class AddAnnotationUseSiteTarget extends AbstractK2IntentionTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor")
|
||||
public abstract static class Constructor extends AbstractK2IntentionTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor")
|
||||
public static class Uncategorized extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("parameter.kt")
|
||||
public void testParameter() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/parameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondary.kt")
|
||||
public void testSecondary() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/secondary.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val")
|
||||
public static class Val extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/val/setparam.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var")
|
||||
public static class Var extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/constructor/var/setparam.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension")
|
||||
public abstract static class Extension extends AbstractK2IntentionTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function")
|
||||
public static class Function extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/function/setparam.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property")
|
||||
public static class Property extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/extension/property/setparam.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property")
|
||||
public abstract static class Property extends AbstractK2IntentionTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate")
|
||||
public static class Delegate extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/delegate/setparam.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property")
|
||||
public static class Uncategorized extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/local.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val")
|
||||
public static class Val extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/val/setparam.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking")
|
||||
public static class ValNoBacking extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/valNoBacking/setparam.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var")
|
||||
public static class Var extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/var/setparam.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking")
|
||||
public static class VarNoBacking extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/delegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/field.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("file.kt")
|
||||
public void testFile() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/file.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("get.kt")
|
||||
public void testGet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/get.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("param.kt")
|
||||
public void testParam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/param.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiver.kt")
|
||||
public void testReceiver() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/receiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/set.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setparam.kt")
|
||||
public void testSetparam() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/property/varNoBacking/setparam.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget")
|
||||
public static class Uncategorized extends AbstractK2IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("hasAnnotationArgs.kt")
|
||||
public void testHasAnnotationArgs() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/hasAnnotationArgs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("hasTarget1.kt")
|
||||
public void testHasTarget1() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/hasTarget1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("hasTarget2.kt")
|
||||
public void testHasTarget2() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/hasTarget2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("hasTarget3.kt")
|
||||
public void testHasTarget3() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/hasTarget3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("qualifiedAnnotationDoesNotLoseQualifier.kt")
|
||||
public void testQualifiedAnnotationDoesNotLoseQualifier() throws Exception {
|
||||
runTest("../../../idea/tests/testData/intentions/addAnnotationUseSiteTarget/qualifiedAnnotationDoesNotLoseQualifier.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,29 +2,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.openapi.ui.popup.ListPopupStep
|
||||
import com.intellij.openapi.ui.popup.PopupStep
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.util.PlatformIcons
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingIntention
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.AddAnnotationUseSiteTargetUtils.addUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.AddAnnotationUseSiteTargetUtils.applicableUseSiteTargets
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
@@ -35,7 +20,7 @@ class AddAnnotationUseSiteTargetIntention : SelfTargetingIntention<KtAnnotationE
|
||||
) {
|
||||
|
||||
override fun isApplicableTo(element: KtAnnotationEntry, caretOffset: Int): Boolean {
|
||||
val useSiteTargets = element.applicableUseSiteTargets()
|
||||
val useSiteTargets = element.getApplicableUseSiteTargets()
|
||||
if (useSiteTargets.isEmpty()) return false
|
||||
if (useSiteTargets.size == 1) {
|
||||
setTextGetter(KotlinBundle.lazyMessage("text.add.use.site.target.0", useSiteTargets.first().renderName))
|
||||
@@ -46,139 +31,14 @@ class AddAnnotationUseSiteTargetIntention : SelfTargetingIntention<KtAnnotationE
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtAnnotationEntry, editor: Editor?) {
|
||||
val useSiteTargets = element.applicableUseSiteTargets()
|
||||
val useSiteTargets = element.getApplicableUseSiteTargets()
|
||||
element.addUseSiteTarget(useSiteTargets, editor)
|
||||
}
|
||||
}
|
||||
|
||||
fun KtAnnotationEntry.addUseSiteTarget(useSiteTargets: List<AnnotationUseSiteTarget>, editor: Editor?) {
|
||||
val project = this.project
|
||||
if (!isPhysical) {
|
||||
// For preview
|
||||
if (useSiteTargets.isNotEmpty()) {
|
||||
doAddUseSiteTarget(useSiteTargets.first())
|
||||
}
|
||||
return
|
||||
}
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
if (useSiteTargets.size == 1 || editor == null)
|
||||
addUseSiteTarget(useSiteTargets.first(), project)
|
||||
else
|
||||
JBPopupFactory
|
||||
.getInstance()
|
||||
.createListPopup(createListPopupStep(this, useSiteTargets, project))
|
||||
.showInBestPositionFor(editor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createListPopupStep(
|
||||
annotationEntry: KtAnnotationEntry,
|
||||
useSiteTargets: List<AnnotationUseSiteTarget>,
|
||||
project: Project
|
||||
): ListPopupStep<*> {
|
||||
return object : BaseListPopupStep<AnnotationUseSiteTarget>(KotlinBundle.message("title.choose.use.site.target"), useSiteTargets) {
|
||||
override fun isAutoSelectionEnabled() = false
|
||||
|
||||
override fun onChosen(selectedValue: AnnotationUseSiteTarget, finalChoice: Boolean): PopupStep<*>? {
|
||||
if (finalChoice) {
|
||||
annotationEntry.addUseSiteTarget(selectedValue, project)
|
||||
}
|
||||
return PopupStep.FINAL_CHOICE
|
||||
}
|
||||
|
||||
override fun getIconFor(value: AnnotationUseSiteTarget) = PlatformIcons.ANNOTATION_TYPE_ICON
|
||||
|
||||
override fun getTextFor(value: AnnotationUseSiteTarget): String {
|
||||
@Suppress("UnnecessaryVariable")
|
||||
@NlsSafe val renderName = value.renderName
|
||||
return renderName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun KtAnnotationEntry.applicableUseSiteTargets(): List<AnnotationUseSiteTarget> {
|
||||
if (useSiteTarget != null) return emptyList()
|
||||
val annotationShortName = this.shortName ?: return emptyList()
|
||||
val modifierList = getStrictParentOfType<KtModifierList>() ?: return emptyList()
|
||||
val annotated = modifierList.owner as? KtElement ?: return emptyList()
|
||||
|
||||
val candidateTargets = when (annotated) {
|
||||
is KtParameter ->
|
||||
if (annotated.getStrictParentOfType<KtPrimaryConstructor>() != null)
|
||||
when (annotated.valOrVarKeyword?.node?.elementType) {
|
||||
KtTokens.VAR_KEYWORD ->
|
||||
listOf(CONSTRUCTOR_PARAMETER, FIELD, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, SETTER_PARAMETER)
|
||||
KtTokens.VAL_KEYWORD ->
|
||||
listOf(CONSTRUCTOR_PARAMETER, FIELD, PROPERTY, PROPERTY_GETTER)
|
||||
else ->
|
||||
emptyList()
|
||||
}
|
||||
else
|
||||
emptyList()
|
||||
is KtProperty ->
|
||||
when {
|
||||
annotated.delegate != null ->
|
||||
listOf(PROPERTY, PROPERTY_GETTER, PROPERTY_DELEGATE_FIELD)
|
||||
!annotated.isLocal -> {
|
||||
val backingField = LightClassUtil.getLightClassPropertyMethods(annotated).backingField
|
||||
if (annotated.isVar) {
|
||||
if (backingField != null)
|
||||
listOf(FIELD, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, SETTER_PARAMETER)
|
||||
else
|
||||
listOf(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, SETTER_PARAMETER)
|
||||
} else {
|
||||
if (backingField != null)
|
||||
listOf(FIELD, PROPERTY, PROPERTY_GETTER)
|
||||
else
|
||||
listOf(PROPERTY, PROPERTY_GETTER)
|
||||
}
|
||||
}
|
||||
else ->
|
||||
emptyList()
|
||||
}
|
||||
is KtTypeReference -> listOf(RECEIVER)
|
||||
else -> emptyList()
|
||||
}.toMutableList()
|
||||
if (candidateTargets.isEmpty()) return emptyList()
|
||||
|
||||
val existingTargets = modifierList.annotationEntries.mapNotNull {
|
||||
if (annotationShortName == it.shortName) it.useSiteTarget?.getAnnotationUseSiteTarget() else null
|
||||
}
|
||||
if (existingTargets.isNotEmpty()) {
|
||||
candidateTargets.removeIf { it in existingTargets }
|
||||
if (candidateTargets.isEmpty()) return emptyList()
|
||||
}
|
||||
|
||||
fun KtAnnotationEntry.getApplicableUseSiteTargets(): List<AnnotationUseSiteTarget> {
|
||||
val context = analyze(BodyResolveMode.PARTIAL)
|
||||
val descriptor = context[BindingContext.ANNOTATION, this]
|
||||
val applicableTargets = descriptor?.let { AnnotationChecker.applicableTargetSet(descriptor) }.orEmpty()
|
||||
if (applicableTargets.isNotEmpty()) {
|
||||
candidateTargets.removeIf { KotlinTarget.USE_SITE_MAPPING[it] !in applicableTargets }
|
||||
if (candidateTargets.isEmpty()) return emptyList()
|
||||
}
|
||||
|
||||
return if (isUnitTestMode()) {
|
||||
val chosenTarget = containingKtFile.findDescendantOfType<PsiComment>()
|
||||
?.takeIf { it.text.startsWith("// CHOOSE_USE_SITE_TARGET:") }
|
||||
?.text
|
||||
?.split(":")
|
||||
?.getOrNull(1)
|
||||
?.trim()
|
||||
if (chosenTarget.isNullOrBlank())
|
||||
candidateTargets.take(1)
|
||||
else
|
||||
candidateTargets.asSequence().filter { it.renderName == chosenTarget }.take(1).toList()
|
||||
} else {
|
||||
candidateTargets
|
||||
}
|
||||
}
|
||||
|
||||
fun KtAnnotationEntry.addUseSiteTarget(useSiteTarget: AnnotationUseSiteTarget, project: Project) {
|
||||
project.executeWriteCommand(KotlinBundle.message("add.use.site.target")) {
|
||||
doAddUseSiteTarget(useSiteTarget)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtAnnotationEntry.doAddUseSiteTarget(useSiteTarget: AnnotationUseSiteTarget) {
|
||||
replace(KtPsiFactory(project).createAnnotationEntry("@${useSiteTarget.renderName}:${text.drop(1)}"))
|
||||
return applicableUseSiteTargets(applicableTargets)
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.quickfixes.KotlinQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.intentions.addUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.intentions.applicableUseSiteTargets
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.AddAnnotationUseSiteTargetUtils.addUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.intentions.getApplicableUseSiteTargets
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@@ -36,7 +36,7 @@ class AddAnnotationUseSiteTargetFix(
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtAnnotationEntry>? {
|
||||
val entry = diagnostic.psiElement as? KtAnnotationEntry ?: return null
|
||||
val applicableUseSiteTargets = entry.applicableUseSiteTargets()
|
||||
val applicableUseSiteTargets = entry.getApplicableUseSiteTargets()
|
||||
if (applicableUseSiteTargets.isEmpty()) return null
|
||||
return AddAnnotationUseSiteTargetFix(entry, applicableUseSiteTargets)
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.k2.codeinsight.intentions.AddAnnotationUseSiteTargetIntention
|
||||
@@ -32,8 +32,8 @@ import org.jetbrains.kotlin.idea.codeinsight.utils.isRedundantGetter
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.isRedundantSetter
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.removeRedundantGetter
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.removeRedundantSetter
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.intentions.AddAnnotationUseSiteTargetUtils.addUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.core.setVisibility
|
||||
import org.jetbrains.kotlin.idea.intentions.addUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.quickfix.AddAnnotationTargetFix.Companion.getExistingAnnotationTargets
|
||||
import org.jetbrains.kotlin.idea.refactoring.isAbstract
|
||||
import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.jetbrains.kotlin.idea.k2.intentions.tests.AbstractK2GotoTestOrCodeAct
|
||||
import org.jetbrains.kotlin.idea.k2.intentions.tests.AbstractK2IntentionTest
|
||||
import org.jetbrains.kotlin.idea.k2.intentions.tests.AbstractK2MultiFileIntentionTest
|
||||
import org.jetbrains.kotlin.testGenerator.model.*
|
||||
import org.jetbrains.kotlin.testGenerator.model.GroupCategory.*
|
||||
import org.jetbrains.kotlin.testGenerator.model.GroupCategory.INTENTIONS
|
||||
import org.jetbrains.kotlin.testGenerator.model.Patterns.TEST
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ internal fun MutableTWorkspace.generateK2IntentionTests() {
|
||||
model("${idea}intentions/removeExplicitLambdaParameterTypes", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/convertPrimaryConstructorToSecondary", pattern = pattern)
|
||||
model("${idea}intentions/convertArgumentToSet", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/addAnnotationUseSiteTarget", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/addAnnotationUseSiteTarget", pattern = pattern)
|
||||
model("${idea}intentions/convertEnumToSealedClass", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/convertToIndexedFunctionCall", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/samConversionToAnonymousObject", pattern = pattern, isIgnored = true)
|
||||
|
||||
Reference in New Issue
Block a user