mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] Port SpecifyTypeExplicitlyInDestructuringAssignmentIntention to K2 as shared
Caret is not in desired places in lambdas KTIJ-32017 GitOrigin-RevId: 21f50626545ddb3470b461068e02c1a87bd471e2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3e72f3b334
commit
fcda28fd46
+7
@@ -413,6 +413,13 @@
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.codeInsight.intentions.shared.SpecifyTypeExplicitlyInDestructuringAssignmentIntention</className>
|
||||
<bundleName>messages.KotlinBundle</bundleName>
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.codeInsight.intentions.shared.ConvertLazyPropertyToOrdinaryIntention</className>
|
||||
|
||||
+69
-23
@@ -1,44 +1,90 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
package org.jetbrains.kotlin.idea.codeInsight.intentions.shared
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.codeInspection.util.IntentionFamilyName
|
||||
import com.intellij.modcommand.ActionContext
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import com.intellij.psi.createSmartPointer
|
||||
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
|
||||
import org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KaTypeRendererForSource
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaErrorType
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingRangeIntention
|
||||
import org.jetbrains.kotlin.idea.core.setType
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.KotlinApplicableModCommandAction
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
import org.jetbrains.kotlin.psi.KtParameterList
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class SpecifyTypeExplicitlyInDestructuringAssignmentIntention : SelfTargetingRangeIntention<KtDestructuringDeclaration>(
|
||||
KtDestructuringDeclaration::class.java, KotlinBundle.lazyMessage("specify.all.types.explicitly.in.destructuring.declaration")
|
||||
) {
|
||||
override fun applicabilityRange(element: KtDestructuringDeclaration): TextRange? {
|
||||
if (element.containingFile is KtCodeFragment) return null
|
||||
internal class SpecifyTypeExplicitlyInDestructuringAssignmentIntention :
|
||||
KotlinApplicableModCommandAction<KtDestructuringDeclaration, SpecifyTypeExplicitlyInDestructuringAssignmentIntention.Context>(
|
||||
KtDestructuringDeclaration::class
|
||||
) {
|
||||
|
||||
internal class Context(val entries: List<SmartPsiElementPointer<KtDestructuringDeclarationEntry>>)
|
||||
|
||||
override fun getFamilyName(): @IntentionFamilyName String =
|
||||
KotlinBundle.message("specify.all.types.explicitly.in.destructuring.declaration")
|
||||
|
||||
override fun isApplicableByPsi(element: KtDestructuringDeclaration): Boolean {
|
||||
if (element.containingFile is KtCodeFragment) return false
|
||||
val entries = element.entriesWithoutExplicitTypes()
|
||||
if (entries.isEmpty()) return null
|
||||
if (entries.any { SpecifyTypeExplicitlyIntention.getTypeForDeclaration(it).isError }) return null
|
||||
val endOffset = element.initializer?.let { it.startOffset - 1 } ?: element.endOffset
|
||||
return TextRange(element.startOffset, endOffset)
|
||||
return entries.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtDestructuringDeclaration, editor: Editor?) {
|
||||
override fun getApplicableRanges(element: KtDestructuringDeclaration): List<TextRange> {
|
||||
val endOffset = element.initializer?.let { it.startOffset - 1 } ?: element.endOffset
|
||||
return listOf(TextRange(0, endOffset - element.startOffset))
|
||||
}
|
||||
|
||||
@OptIn(KaExperimentalApi::class)
|
||||
override fun KaSession.prepareContext(element: KtDestructuringDeclaration): Context? {
|
||||
val entries = element.entriesWithoutExplicitTypes()
|
||||
if (editor != null && element.getParentOfType<KtParameterList>(strict = false) == null) {
|
||||
SpecifyTypeExplicitlyIntention.addTypeAnnotationWithTemplate(editor, entries.iterator())
|
||||
} else {
|
||||
for (entry in entries) {
|
||||
entry.setType(SpecifyTypeExplicitlyIntention.getTypeForDeclaration(entry))
|
||||
if (entries.any { entry ->
|
||||
val symbol = entry.symbol
|
||||
symbol.returnType is KaErrorType
|
||||
}) return null
|
||||
return Context(entries.map { it.createSmartPointer() }.toList())
|
||||
}
|
||||
|
||||
override fun invoke(
|
||||
actionContext: ActionContext,
|
||||
element: KtDestructuringDeclaration,
|
||||
elementContext: Context,
|
||||
updater: ModPsiUpdater,
|
||||
) {
|
||||
val entries = elementContext.entries
|
||||
for (entry in entries) {
|
||||
val element = entry.element ?: continue
|
||||
setTypeForDeclaration(element)
|
||||
if (entries.last() == entry) {
|
||||
updater.moveCaretTo(element.endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setTypeForDeclaration(entry: KtDestructuringDeclarationEntry) {
|
||||
val factory = KtPsiFactory(entry.project)
|
||||
val typeReference = factory.createType(entry.getKotlinType())
|
||||
entry.typeReference = typeReference
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtDestructuringDeclaration.entriesWithoutExplicitTypes(): List<KtDestructuringDeclarationEntry> =
|
||||
entries.filter { it.typeReference == null }
|
||||
|
||||
@OptIn(KaExperimentalApi::class)
|
||||
private fun KtDestructuringDeclarationEntry.getKotlinType(): String {
|
||||
val entry = this
|
||||
return analyze(entry) {
|
||||
val symbol = entry.symbol
|
||||
symbol.returnType.render(renderer = KaTypeRendererForSource.WITH_SHORT_NAMES, position = Variance.OUT_VARIANCE)
|
||||
}
|
||||
}
|
||||
+49
@@ -3035,6 +3035,55 @@ public abstract class SharedK1IntentionTestGenerated extends AbstractSharedK1Int
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment")
|
||||
public static class SpecifyTypeExplicitlyInDestructuringAssignment extends AbstractSharedK1IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K1;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("in.kt")
|
||||
public void testIn() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/in.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambda.kt")
|
||||
public void testLambda() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/lambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaHasSignature.kt")
|
||||
public void testLambdaHasSignature() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/lambdaHasSignature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasAllTypes.kt")
|
||||
public void testVariableHasAllTypes() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasAllTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasNoTypes.kt")
|
||||
public void testVariableHasNoTypes() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasNoTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasTypes.kt")
|
||||
public void testVariableHasTypes() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasUnderscore.kt")
|
||||
public void testVariableHasUnderscore() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasUnderscore.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/intentions/splitIf")
|
||||
public abstract static class SplitIf extends AbstractSharedK1IntentionTest {
|
||||
|
||||
+49
@@ -3035,6 +3035,55 @@ public abstract class SharedK2IntentionTestGenerated extends AbstractSharedK2Int
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment")
|
||||
public static class SpecifyTypeExplicitlyInDestructuringAssignment extends AbstractSharedK2IntentionTest {
|
||||
@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("in.kt")
|
||||
public void testIn() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/in.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambda.kt")
|
||||
public void testLambda() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/lambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaHasSignature.kt")
|
||||
public void testLambdaHasSignature() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/lambdaHasSignature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasAllTypes.kt")
|
||||
public void testVariableHasAllTypes() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasAllTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasNoTypes.kt")
|
||||
public void testVariableHasNoTypes() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasNoTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasTypes.kt")
|
||||
public void testVariableHasTypes() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasUnderscore.kt")
|
||||
public void testVariableHasUnderscore() throws Exception {
|
||||
runTest("../testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasUnderscore.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/intentions/splitIf")
|
||||
public abstract static class SplitIf extends AbstractSharedK2IntentionTest {
|
||||
|
||||
-49
@@ -17846,55 +17846,6 @@ public abstract class K1IntentionTestGenerated extends AbstractK1IntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment")
|
||||
public static class SpecifyTypeExplicitlyInDestructuringAssignment extends AbstractK1IntentionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K1;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("in.kt")
|
||||
public void testIn() throws Exception {
|
||||
runTest("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/in.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambda.kt")
|
||||
public void testLambda() throws Exception {
|
||||
runTest("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/lambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaHasSignature.kt")
|
||||
public void testLambdaHasSignature() throws Exception {
|
||||
runTest("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/lambdaHasSignature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasAllTypes.kt")
|
||||
public void testVariableHasAllTypes() throws Exception {
|
||||
runTest("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasAllTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasNoTypes.kt")
|
||||
public void testVariableHasNoTypes() throws Exception {
|
||||
runTest("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasNoTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasTypes.kt")
|
||||
public void testVariableHasTypes() throws Exception {
|
||||
runTest("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableHasUnderscore.kt")
|
||||
public void testVariableHasUnderscore() throws Exception {
|
||||
runTest("testData/intentions/specifyTypeExplicitlyInDestructuringAssignment/variableHasUnderscore.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("testData/intentions/swapStringEqualsIgnoreCase")
|
||||
public static class SwapStringEqualsIgnoreCase extends AbstractK1IntentionTest {
|
||||
|
||||
@@ -35,13 +35,6 @@
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.codeInsight.intentions.shared.SpecifyTypeExplicitlyInDestructuringAssignmentIntention</className>
|
||||
<bundleName>messages.KotlinBundle</bundleName>
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeIntention</className>
|
||||
|
||||
Reference in New Issue
Block a user