[kotlin] k2: port ConvertMemberToExtensionIntention

^KTIJ-29625 fixed

GitOrigin-RevId: 0cfacaeb45fe6ceb95b5b6b9216fbe740a81ea4c
This commit is contained in:
Anna Kozlova
2024-09-21 15:19:49 +00:00
committed by intellij-monorepo-bot
parent 6a7123a158
commit d3bf2e0e20
20 changed files with 747 additions and 3 deletions
@@ -57,5 +57,6 @@
<orderEntry type="module" module-name="kotlin.refactorings.move.k2" />
<orderEntry type="module" module-name="kotlin.code-insight.override-implement.shared" />
<orderEntry type="module" module-name="kotlin.code-insight.override-implement.k2" />
<orderEntry type="module" module-name="kotlin.fir.frontend-independent" />
</component>
</module>
@@ -86,6 +86,13 @@
<categoryKey>group.names.kotlin</categoryKey>
</intentionAction>
<intentionAction>
<language>kotlin</language>
<className>org.jetbrains.kotlin.idea.k2.codeinsight.intentions.ConvertMemberToExtensionIntention</className>
<bundleName>messages.KotlinBundle</bundleName>
<categoryKey>group.names.kotlin</categoryKey>
</intentionAction>
<intentionAction>
<language>kotlin</language>
<className>org.jetbrains.kotlin.idea.k2.codeinsight.intentions.ConvertStringTemplateToBuildStringIntention</className>
@@ -0,0 +1,350 @@
// 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.codeInsight.FileModificationService
import com.intellij.codeInsight.intention.LowPriorityAction
import com.intellij.openapi.application.readAction
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.TextRange
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiReferenceExpression
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.util.SmartList
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.idea.base.analysis.api.utils.shortenReferences
import org.jetbrains.kotlin.idea.base.psi.getReturnTypeReference
import org.jetbrains.kotlin.idea.base.psi.imports.addImport
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.codeinsight.utils.isFunInterface
import org.jetbrains.kotlin.idea.core.TemplateKind
import org.jetbrains.kotlin.idea.core.getFunctionBodyTextFromTemplate
import org.jetbrains.kotlin.idea.core.moveCaret
import org.jetbrains.kotlin.idea.core.unblockDocument
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.search.ExpectActualUtils.actualsForExpected
import org.jetbrains.kotlin.idea.search.ExpectActualUtils.liftToExpected
import org.jetbrains.kotlin.idea.search.ExpectActualUtils.withExpectedActuals
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.util.match
import org.jetbrains.kotlin.utils.addIfNotNull
private val LOG = Logger.getInstance(ConvertMemberToExtensionIntention::class.java)
class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallableDeclaration>(
KtCallableDeclaration::class.java, KotlinBundle.lazyMessage("convert.member.to.extension")
), LowPriorityAction {
private fun isApplicable(element: KtCallableDeclaration): Boolean {
val classBody = element.parent as? KtClassBody ?: return false
val parentClass = classBody.parent as? KtClassOrObject ?: return false
if (parentClass.isLocal) return false
if (parentClass is KtObjectDeclaration && parentClass.isCompanion()) return false
if ((parentClass as? KtClass)?.isFunInterface() == true && !element.hasBody()) return false
if (element.receiverTypeReference != null) return false
if (element.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false
when (element) {
is KtProperty -> if (element.hasInitializer() || element.hasDelegate()) return false
is KtSecondaryConstructor -> return false
}
return true
}
override fun applicabilityRange(element: KtCallableDeclaration): TextRange? {
val nameIdentifier = element.nameIdentifier ?: return null
if (!isApplicable(element)) return null
return nameIdentifier.textRange
}
override fun startInWriteAction() = false
override fun applyTo(element: KtCallableDeclaration, editor: Editor?) {
if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return
var allowExpected = true
liftToExpected(element)?.actualsForExpected()?.let {
if (it.isEmpty()) {
allowExpected = askIfExpectedIsAllowed()
}
}
val (extension, bodyTypeToSelect) = createExtensionCallableAndPrepareBodyToSelect(element, allowExpected)
runWriteAction {
editor?.apply {
unblockDocument()
if (extension.isValid) {
if (bodyTypeToSelect != GeneratedBodyType.NOTHING) {
val bodyToSelect = getBodyForSelection(extension, bodyTypeToSelect)
if (bodyToSelect != null) {
val range = bodyToSelect.textRange
moveCaret(range.startOffset, ScrollType.CENTER)
val parent = bodyToSelect.parent
val lastSibling = if (parent is KtBlockExpression) parent.rBrace?.siblings(forward = false, withItself = false)
?.first { it !is PsiWhiteSpace }
else bodyToSelect.siblings(forward = true, withItself = false).lastOrNull()
val endOffset = lastSibling?.endOffset ?: range.endOffset
selectionModel.setSelection(range.startOffset, endOffset)
} else {
LOG.error(
"Extension created with new method body but this body was not found after document commit. Extension text: \"${extension.text}\""
)
moveCaret(extension.textOffset, ScrollType.CENTER)
}
} else {
moveCaret(extension.textOffset, ScrollType.CENTER)
}
} else {
LOG.error("Extension invalidated during document commit. Extension text \"${extension.text}\"")
}
}
}
}
private fun getBodyForSelection(extension: KtCallableDeclaration, bodyTypeToSelect: GeneratedBodyType): KtExpression? {
fun selectBody(declaration: KtDeclarationWithBody): KtExpression? {
if (!declaration.hasBody()) return extension
return declaration.bodyExpression?.let {
(it as? KtBlockExpression)?.statements?.singleOrNull() ?: it
}
}
return when (bodyTypeToSelect) {
GeneratedBodyType.FUNCTION -> (extension as? KtFunction)?.let { selectBody(it) }
GeneratedBodyType.GETTER -> (extension as? KtProperty)?.getter?.let { selectBody(it) }
GeneratedBodyType.SETTER -> (extension as? KtProperty)?.setter?.let { selectBody(it) }
else -> null
}
}
private enum class GeneratedBodyType {
NOTHING, FUNCTION, SETTER, GETTER
}
private fun processSingleDeclaration(
element: KtCallableDeclaration, allowExpected: Boolean
): Pair<KtCallableDeclaration, GeneratedBodyType> {
val containingClass = element.containingClassOrObject
val isEffectivelyExpected = allowExpected && element.isExpectDeclaration()
val file = element.containingKtFile
val project = file.project
val outermostParent = KtPsiUtil.getOutermostParent(element, file, false)
val ktFilesToAddImports = LinkedHashSet<KtFile>()
val javaCallsToFix = SmartList<PsiMethodCallExpression>()
runWithModalProgressBlocking(project, KotlinBundle.message("searching.for.0", element.name!!)) {
readAction {
for (ref in ReferencesSearch.search(element)) {
when (ref) {
is KtReference -> {
val refFile = ref.element.containingKtFile
if (refFile != file) {
ktFilesToAddImports.add(refFile)
}
}
is PsiReferenceExpression -> javaCallsToFix.addIfNotNull(ref.parent as? PsiMethodCallExpression)
}
}
}
}
val typeParameterList = newTypeParameterList(element)
val psiFactory = KtPsiFactory(project)
val (extension, bodyTypeToSelect) = runWriteAction {
val extension = file.addAfter(element, outermostParent) as KtCallableDeclaration
file.addAfter(psiFactory.createNewLine(), outermostParent)
file.addAfter(psiFactory.createNewLine(), outermostParent)
element.delete()
extension.setReceiverType(containingClass!!)
if (typeParameterList != null) {
if (extension.typeParameterList != null) {
extension.typeParameterList!!.replace(typeParameterList)
}
else {
extension.addBefore(typeParameterList, extension.receiverTypeReference)
extension.addBefore(psiFactory.createWhiteSpace(), extension.receiverTypeReference)
}
}
extension.modifierList?.getModifier(KtTokens.PROTECTED_KEYWORD)?.delete()
extension.modifierList?.getModifier(KtTokens.ABSTRACT_KEYWORD)?.delete()
extension.modifierList?.getModifier(KtTokens.OPEN_KEYWORD)?.delete()
extension.modifierList?.getModifier(KtTokens.FINAL_KEYWORD)?.delete()
if (isEffectivelyExpected && !extension.hasExpectModifier()) {
extension.addModifier(KtTokens.EXPECT_KEYWORD)
}
var bodyTypeToSelect = GeneratedBodyType.NOTHING
val bodyText = getFunctionBodyTextFromTemplate(
project,
if (extension is KtFunction) TemplateKind.FUNCTION else TemplateKind.PROPERTY_INITIALIZER,
extension.name,
extension.getReturnTypeReference()?.text ?: "Unit",
extension.containingClassOrObject?.fqName
)
when (extension) {
is KtFunction -> {
if (!extension.hasBody() && !isEffectivelyExpected) { //TODO: methods in PSI for setBody
extension.add(psiFactory.createBlock(bodyText))
bodyTypeToSelect = GeneratedBodyType.FUNCTION
}
}
is KtProperty -> {
val templateProperty =
psiFactory.createDeclaration<KtProperty>("var v: Any\nget()=$bodyText\nset(value){\n$bodyText\n}")
if (!isEffectivelyExpected) {
val templateGetter = templateProperty.getter!!
val templateSetter = templateProperty.setter!!
var getter = extension.getter
if (getter == null) {
getter = extension.addAfter(templateGetter, extension.typeReference) as KtPropertyAccessor
extension.addBefore(psiFactory.createNewLine(), getter)
bodyTypeToSelect = GeneratedBodyType.GETTER
}
else if (!getter.hasBody()) {
getter = getter.replace(templateGetter) as KtPropertyAccessor
bodyTypeToSelect = GeneratedBodyType.GETTER
}
if (extension.isVar) {
var setter = extension.setter
if (setter == null) {
setter = extension.addAfter(templateSetter, getter) as KtPropertyAccessor
extension.addBefore(psiFactory.createNewLine(), setter)
if (bodyTypeToSelect == GeneratedBodyType.NOTHING) {
bodyTypeToSelect = GeneratedBodyType.SETTER
}
}
else if (!setter.hasBody()) {
setter.replace(templateSetter) as KtPropertyAccessor
if (bodyTypeToSelect == GeneratedBodyType.NOTHING) {
bodyTypeToSelect = GeneratedBodyType.SETTER
}
}
}
}
}
}
extension to bodyTypeToSelect
}
if (ktFilesToAddImports.isNotEmpty()) {
extension.fqName?.let { fqName ->
runWriteAction {
for (ktFile in ktFilesToAddImports) {
ktFile.addImport(fqName)
}
}
}
}
if (javaCallsToFix.isNotEmpty()) {
val lightMethod = extension.toLightMethods().first()
for (javaCallToFix in javaCallsToFix) {
runWriteAction {
javaCallToFix.methodExpression.qualifierExpression?.let {
val argumentList = javaCallToFix.argumentList
argumentList.addBefore(it, argumentList.expressions.firstOrNull())
}
val newRef = javaCallToFix.methodExpression.bindToElement(lightMethod)
JavaCodeStyleManager.getInstance(project).shortenClassReferences(newRef)
}
}
}
return extension to bodyTypeToSelect
}
private fun askIfExpectedIsAllowed(): Boolean {
return Messages.showYesNoDialog(
KotlinBundle.message("do.you.want.to.make.new.extension.an.expected.declaration"), text, Messages.getQuestionIcon()
) == Messages.YES
}
private fun createExtensionCallableAndPrepareBodyToSelect(
element: KtCallableDeclaration, allowExpected: Boolean = true
): Pair<KtCallableDeclaration, GeneratedBodyType> {
val expectedDeclaration = liftToExpected(element) as? KtCallableDeclaration
if (expectedDeclaration != null) {
withExpectedActuals(element).filterIsInstance<KtCallableDeclaration>().forEach {
if (it != element) {
processSingleDeclaration(it, allowExpected)
}
}
}
val classVisibility = element.containingClass()?.visibilityModifierType()
val (extension, bodyTypeToSelect) = processSingleDeclaration(element, allowExpected)
if (classVisibility != null && extension.visibilityModifier() == null) {
runWriteAction {
extension.addModifier(classVisibility)
}
}
return extension to bodyTypeToSelect
}
private fun newTypeParameterList(member: KtCallableDeclaration): KtTypeParameterList? {
val classElement =
member.parents.match(KtClassBody::class, last = KtClassOrObject::class) ?: error("Can't typeMatch ${member.parent.parent}")
val classParams = classElement.typeParameters
if (classParams.isEmpty()) return null
val allTypeParameters = classParams + member.typeParameters
val text = allTypeParameters.joinToString(",", "<", ">") { it.textWithoutVariance() }
return org.jetbrains.kotlin.psi.KtPsiFactory(member.project).createDeclaration<KtFunction>("fun $text foo()").typeParameterList
}
private fun KtTypeParameter.textWithoutVariance(): String {
if (variance == Variance.INVARIANT) return text
val copied = this.copy() as KtTypeParameter
copied.modifierList?.getModifier(KtTokens.OUT_KEYWORD)?.delete()
copied.modifierList?.getModifier(KtTokens.IN_KEYWORD)?.delete()
return copied.text
}
private fun KtCallableDeclaration.setReceiverType(klass: KtClassOrObject) {
val className = buildString {
append(klass.name)
if (klass.typeParameters.isNotEmpty()) {
append(klass.typeParameters.joinToString(", ", "<", ">") {
it.name ?: ""
})
}
}
val typeReference = KtPsiFactory.contextual(this@setReceiverType).createType(className)
val receiverReference = setReceiverTypeReference(typeReference) ?: return
shortenReferences(receiverReference)
}
}
@@ -7469,7 +7469,284 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest {
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension")
public static class ConvertMemberToExtension 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("abstract.kt")
public void testAbstract() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/abstract.kt");
}
@TestMetadata("abstractProperty.kt")
public void testAbstractProperty() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/abstractProperty.kt");
}
@TestMetadata("delegatedProperty.kt")
public void testDelegatedProperty() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/delegatedProperty.kt");
}
@TestMetadata("explicitUnit.kt")
public void testExplicitUnit() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/explicitUnit.kt");
}
@TestMetadata("extension.kt")
public void testExtension() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/extension.kt");
}
@TestMetadata("final.kt")
public void testFinal() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/final.kt");
}
@TestMetadata("funInterface.kt")
public void testFunInterface() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/funInterface.kt");
}
@TestMetadata("funInterface2.kt")
public void testFunInterface2() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/funInterface2.kt");
}
@TestMetadata("funcitonNoName.kt")
public void testFuncitonNoName() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/funcitonNoName.kt");
}
@TestMetadata("functionType.kt")
public void testFunctionType() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/functionType.kt");
}
@TestMetadata("genericClass.kt")
public void testGenericClass() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericClass.kt");
}
@TestMetadata("genericClassWithInVariance.kt")
public void testGenericClassWithInVariance() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericClassWithInVariance.kt");
}
@TestMetadata("genericClassWithOutVariance.kt")
public void testGenericClassWithOutVariance() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericClassWithOutVariance.kt");
}
@TestMetadata("genericClassWithVarianceAndReified.kt")
public void testGenericClassWithVarianceAndReified() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericClassWithVarianceAndReified.kt");
}
@TestMetadata("genericFun.kt")
public void testGenericFun() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericFun.kt");
}
@TestMetadata("genericFunInGenericClass.kt")
public void testGenericFunInGenericClass() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericFunInGenericClass.kt");
}
@TestMetadata("genericFunInGenericClassWithUpperBounds.kt")
public void testGenericFunInGenericClassWithUpperBounds() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericFunInGenericClassWithUpperBounds.kt");
}
@TestMetadata("genericFunParamAfterName.kt")
public void testGenericFunParamAfterName() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/genericFunParamAfterName.kt");
}
@TestMetadata("inCompanionObject.kt")
public void testInCompanionObject() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/inCompanionObject.kt");
}
@TestMetadata("inFunctionBody.kt")
public void testInFunctionBody() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/inFunctionBody.kt");
}
@TestMetadata("inLocalClass.kt")
public void testInLocalClass() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/inLocalClass.kt");
}
@TestMetadata("inObject.kt")
public void testInObject() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/inObject.kt");
}
@TestMetadata("inObjectLiteral.kt")
public void testInObjectLiteral() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/inObjectLiteral.kt");
}
@TestMetadata("internal.kt")
public void testInternal() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/internal.kt");
}
@TestMetadata("KDoc.kt")
public void testKDoc() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/KDoc.kt");
}
@TestMetadata("localFunction.kt")
public void testLocalFunction() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/localFunction.kt");
}
@TestMetadata("nonBlockBodyNoType.kt")
public void testNonBlockBodyNoType() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/nonBlockBodyNoType.kt");
}
@TestMetadata("nonBlockBodyWithType.kt")
public void testNonBlockBodyWithType() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/nonBlockBodyWithType.kt");
}
@TestMetadata("open.kt")
public void testOpen() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/open.kt");
}
@TestMetadata("outsideFunction.kt")
public void testOutsideFunction() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/outsideFunction.kt");
}
@TestMetadata("override.kt")
public void testOverride() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/override.kt");
}
@TestMetadata("private.kt")
public void testPrivate() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/private.kt");
}
@TestMetadata("privateInInternalClass.kt")
public void testPrivateInInternalClass() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/privateInInternalClass.kt");
}
@TestMetadata("protected.kt")
public void testProtected() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/protected.kt");
}
@TestMetadata("public.kt")
public void testPublic() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/public.kt");
}
@TestMetadata("publicInInternalClass.kt")
public void testPublicInInternalClass() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/publicInInternalClass.kt");
}
@TestMetadata("publicInPrivateClass.kt")
public void testPublicInPrivateClass() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/publicInPrivateClass.kt");
}
@TestMetadata("secondaryConstructor.kt")
public void testSecondaryConstructor() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/secondaryConstructor.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/simple.kt");
}
@TestMetadata("topLevelFunction.kt")
public void testTopLevelFunction() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/topLevelFunction.kt");
}
@TestMetadata("typeFqName.kt")
public void testTypeFqName() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/typeFqName.kt");
}
@TestMetadata("unknownType.kt")
public void testUnknownType() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/unknownType.kt");
}
@TestMetadata("valWithDefaultGetter.kt")
public void testValWithDefaultGetter() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/valWithDefaultGetter.kt");
}
@TestMetadata("valWithGetter.kt")
public void testValWithGetter() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/valWithGetter.kt");
}
@TestMetadata("valWithGetterBlockBody.kt")
public void testValWithGetterBlockBody() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/valWithGetterBlockBody.kt");
}
@TestMetadata("varWithDefaultGetterAndSetter.kt")
public void testVarWithDefaultGetterAndSetter() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/varWithDefaultGetterAndSetter.kt");
}
@TestMetadata("varWithDefaultSetter.kt")
public void testVarWithDefaultSetter() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/varWithDefaultSetter.kt");
}
@TestMetadata("varWithGetter.kt")
public void testVarWithGetter() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/varWithGetter.kt");
}
@TestMetadata("varWithGetterAndSetter.kt")
public void testVarWithGetterAndSetter() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/varWithGetterAndSetter.kt");
}
@TestMetadata("varWithSetter.kt")
public void testVarWithSetter() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/varWithSetter.kt");
}
@TestMetadata("withImport.kt")
public void testWithImport() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/withImport.kt");
}
@TestMetadata("withJavaUsage.kt")
public void testWithJavaUsage() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/withJavaUsage.kt");
}
@TestMetadata("withType.kt")
public void testWithType() throws Exception {
runTest("../../../idea/tests/testData/intentions/declarations/convertMemberToExtension/withType.kt");
}
}
@@ -10965,16 +10965,31 @@ public abstract class K1IntentionTestGenerated extends AbstractK1IntentionTest {
runTest("testData/intentions/declarations/convertMemberToExtension/genericFunParamAfterName.kt");
}
@TestMetadata("inCompanionObject.kt")
public void testInCompanionObject() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/inCompanionObject.kt");
}
@TestMetadata("inFunctionBody.kt")
public void testInFunctionBody() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/inFunctionBody.kt");
}
@TestMetadata("inLocalClass.kt")
public void testInLocalClass() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/inLocalClass.kt");
}
@TestMetadata("inObject.kt")
public void testInObject() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/inObject.kt");
}
@TestMetadata("inObjectLiteral.kt")
public void testInObjectLiteral() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/inObjectLiteral.kt");
}
@TestMetadata("internal.kt")
public void testInternal() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/internal.kt");
@@ -11110,6 +11125,16 @@ public abstract class K1IntentionTestGenerated extends AbstractK1IntentionTest {
runTest("testData/intentions/declarations/convertMemberToExtension/varWithSetter.kt");
}
@TestMetadata("withImport.kt")
public void testWithImport() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/withImport.kt");
}
@TestMetadata("withJavaUsage.kt")
public void testWithJavaUsage() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/withJavaUsage.kt");
}
@TestMetadata("withType.kt")
public void testWithType() throws Exception {
runTest("testData/intentions/declarations/convertMemberToExtension/withType.kt");
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.k2.codeinsight.intentions.ConvertMemberToExtensionIntention
@@ -0,0 +1,6 @@
// IS_APPLICABLE: false
class Owner {
companion object {
fun <caret>f() {}
}
}
@@ -0,0 +1,9 @@
// IS_APPLICABLE: false
class Owner {
fun m() {
class Local {
fun <caret>f() {}
}
}
}
// IGNORE_K1
@@ -1,4 +1,4 @@
// IS_APPLICABLE: false
object Owner {
fun <caret>f() {}
}
}
// IGNORE_K1
@@ -0,0 +1,5 @@
object Owner {
}
fun Owner.f() {}
// IGNORE_K1
@@ -0,0 +1,7 @@
// IS_APPLICABLE: false
interface A
fun m() {
object: A {
fun <caret>f() {}
}
}
@@ -0,0 +1,7 @@
package b
import a.A
fun m(a: A) {
a.f()
}
@@ -0,0 +1,8 @@
package b
import a.A
import a.f
fun m(a: A) {
a.f()
}
@@ -0,0 +1,5 @@
package a
class A {
fun <caret>f() {}
}
@@ -0,0 +1,6 @@
package a
class A {
}
fun A.f() {}
@@ -0,0 +1,9 @@
package b;
import a.A;
class B {
void m(A a) {
a.f();
}
}
@@ -0,0 +1,10 @@
package b;
import a.A;
import a.WithJavaUsageKt;
class B {
void m(A a) {
WithJavaUsageKt.f(a);
}
}
@@ -0,0 +1,5 @@
package a
class A {
fun <caret>f() {}
}
@@ -0,0 +1,6 @@
package a
class A {
}
fun A.f() {}
@@ -107,7 +107,7 @@ internal fun MutableTWorkspace.generateK2IntentionTests() {
model("${idea}intentions/convertObjectLiteralToClass", pattern = pattern, isIgnored = true)
model("${idea}intentions/toOrdinaryStringLiteral", pattern = pattern, isIgnored = true)
model("${idea}intentions/convertLineCommentToBlockComment", pattern = pattern, isIgnored = true)
model("${idea}intentions/declarations", pattern = pattern, isIgnored = true)
model("${idea}intentions/declarations/convertMemberToExtension", pattern = pattern)
model("${idea}intentions/removeEmptyPrimaryConstructor", pattern = pattern, isIgnored = true)
model("${idea}intentions/useWithIndex", pattern = pattern, isIgnored = true)
model("${idea}intentions/joinDeclarationAndAssignment", pattern = pattern, isIgnored = true)