Enable "add () fix" for expect base class without constructors
Related to KT-24597
This commit is contained in:
@@ -27,17 +27,21 @@ class AddDefaultConstructorFix(expectClass: KtClass) : KotlinQuickFixAction<KtCl
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
fun superTypeEntryToClass(typeEntry: KtSuperTypeListEntry, context: BindingContext): KtClass? {
|
||||
val baseType = context[BindingContext.TYPE, typeEntry.typeReference] ?: return null
|
||||
val baseClassDescriptor = baseType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
if (!baseClassDescriptor.isExpect) return null
|
||||
if (baseClassDescriptor.kind != ClassKind.CLASS) return null
|
||||
return DescriptorToSourceUtils.descriptorToDeclaration(baseClassDescriptor) as? KtClass
|
||||
}
|
||||
|
||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtClass>? {
|
||||
val argumentList = diagnostic.psiElement as? KtValueArgumentList ?: return null
|
||||
if (argumentList.arguments.isNotEmpty()) return null
|
||||
val derivedClass = argumentList.getStrictParentOfType<KtClassOrObject>() ?: return null
|
||||
val context = derivedClass.analyze()
|
||||
val baseTypeCallEntry = derivedClass.superTypeListEntries.filterIsInstance<KtSuperTypeCallEntry>().firstOrNull() ?: return null
|
||||
val baseType = context[BindingContext.TYPE, baseTypeCallEntry.typeReference] ?: return null
|
||||
val baseClassDescriptor = baseType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
if (!baseClassDescriptor.isExpect) return null
|
||||
if (baseClassDescriptor.kind != ClassKind.CLASS) return null
|
||||
val baseClass = DescriptorToSourceUtils.descriptorToDeclaration(baseClassDescriptor) as? KtClass ?: return null
|
||||
val baseClass = superTypeEntryToClass(baseTypeCallEntry, context) ?: return null
|
||||
return AddDefaultConstructorFix(baseClass)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@ import org.jetbrains.kotlin.idea.core.isVisible
|
||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -64,7 +64,9 @@ object SuperClassNotInitialized : KotlinIntentionActionsFactory() {
|
||||
val constructors = superClass.constructors.filter {
|
||||
it.isVisible(classDescriptor) || (superClass.modality == Modality.SEALED && inSameFile)
|
||||
}
|
||||
if (constructors.isEmpty()) return emptyList() // no accessible constructor
|
||||
if (constructors.isEmpty() && (!superClass.isExpect || superClass.kind != ClassKind.CLASS)) {
|
||||
return emptyList() // no accessible constructor
|
||||
}
|
||||
|
||||
val fixes = ArrayList<IntentionAction>()
|
||||
|
||||
@@ -122,7 +124,13 @@ object SuperClassNotInitialized : KotlinIntentionActionsFactory() {
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val context = (element.getStrictParentOfType<KtClassOrObject>() ?: element).analyze()
|
||||
val baseClass = AddDefaultConstructorFix.superTypeEntryToClass(element, context)
|
||||
|
||||
val newSpecifier = element.replaced(KtPsiFactory(project).createSuperTypeCallEntry(element.text + "()"))
|
||||
if (baseClass != null && baseClass.hasExpectModifier() && baseClass.secondaryConstructors.isEmpty()) {
|
||||
baseClass.createPrimaryConstructorIfAbsent()
|
||||
}
|
||||
|
||||
if (putCaretIntoParenthesis) {
|
||||
if (editor != null) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Change to constructor invocation" "true"
|
||||
// ENABLE_MULTIPLATFORM
|
||||
// DISABLE-ERRORS
|
||||
|
||||
expect open class A
|
||||
|
||||
class B : A<caret>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Change to constructor invocation" "true"
|
||||
// ENABLE_MULTIPLATFORM
|
||||
// DISABLE-ERRORS
|
||||
|
||||
expect open class A()
|
||||
|
||||
class B : A(<caret>)
|
||||
@@ -10026,6 +10026,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
runTest("idea/testData/quickfix/supertypeInitialization/addParenthesisEmptyConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("addParenthesisExpectClass.kt")
|
||||
public void testAddParenthesisExpectClass() throws Exception {
|
||||
runTest("idea/testData/quickfix/supertypeInitialization/addParenthesisExpectClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("addParenthesisForInvalidSealedClass.kt")
|
||||
public void testAddParenthesisForInvalidSealedClass() throws Exception {
|
||||
runTest("idea/testData/quickfix/supertypeInitialization/addParenthesisForInvalidSealedClass.kt");
|
||||
|
||||
Reference in New Issue
Block a user