Introduce "add default constructor for expect class" fix
Related to KT-24597
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
|
||||
class AddDefaultConstructorFix(expectClass: KtClass) : KotlinQuickFixAction<KtClass>(expectClass) {
|
||||
|
||||
override fun getText() = "Add default constructor to expect class"
|
||||
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element?.createPrimaryConstructorIfAbsent()
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
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
|
||||
return AddDefaultConstructorFix(baseClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,6 +541,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET.registerFactory(MoveReceiverAnnotationFix, AddAnnotationTargetFix)
|
||||
|
||||
NO_CONSTRUCTOR.registerFactory(RemoveNoConstructorFix)
|
||||
NO_CONSTRUCTOR.registerFactory(AddDefaultConstructorFix)
|
||||
|
||||
ANNOTATION_USED_AS_ANNOTATION_ARGUMENT.registerFactory(RemoveAtFromAnnotationArgument)
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Add default constructor to expect class" "true"
|
||||
// ENABLE_MULTIPLATFORM
|
||||
// ERROR: Expected class 'A' has no actual declaration in module light_idea_test_case for JVM
|
||||
|
||||
expect open class A
|
||||
|
||||
open class C : A<caret>()
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Add default constructor to expect class" "true"
|
||||
// ENABLE_MULTIPLATFORM
|
||||
// ERROR: Expected class 'A' has no actual declaration in module light_idea_test_case for JVM
|
||||
|
||||
expect open class A()
|
||||
|
||||
open class C : A()
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Add default constructor to expect class" "false"
|
||||
// ENABLE_MULTIPLATFORM
|
||||
// ACTION: Create subclass
|
||||
// ACTION: Remove constructor call
|
||||
// ERROR: This class does not have a constructor
|
||||
|
||||
expect interface A
|
||||
|
||||
open class C : A<caret>()
|
||||
|
||||
actual interface A
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Add default constructor to expect class" "false"
|
||||
// ACTION: Create subclass
|
||||
// ACTION: Remove constructor call
|
||||
// ERROR: This class does not have a constructor
|
||||
|
||||
interface A
|
||||
|
||||
open class C : A<caret>()
|
||||
+13
@@ -86,6 +86,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/addDefaultConstructor")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddDefaultConstructor extends AbstractQuickFixMultiFileTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddDefaultConstructor() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/addDefaultConstructor"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/addExclExclCall")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -461,6 +461,34 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/addDefaultConstructor")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddDefaultConstructor extends AbstractQuickFixTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddDefaultConstructor() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/addDefaultConstructor"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("expect.kt")
|
||||
public void testExpect() throws Exception {
|
||||
runTest("idea/testData/quickfix/addDefaultConstructor/expect.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("expectInterface.kt")
|
||||
public void testExpectInterface() throws Exception {
|
||||
runTest("idea/testData/quickfix/addDefaultConstructor/expectInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("interface.kt")
|
||||
public void testInterface() throws Exception {
|
||||
runTest("idea/testData/quickfix/addDefaultConstructor/interface.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/addExclExclCall")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user