Add a quick fix for NO_CONSTRUCTOR error on 'expect' annotation entry
#KT-20718 Fixed
This commit is contained in:
committed by
Dmitry Gridin
parent
d846a22e33
commit
7be5410877
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypes
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
|
||||||
@@ -36,14 +36,25 @@ class AddDefaultConstructorFix(expectClass: KtClass) : KotlinQuickFixAction<KtCl
|
|||||||
return DescriptorToSourceUtils.descriptorToDeclaration(baseClassDescriptor) as? KtClass
|
return DescriptorToSourceUtils.descriptorToDeclaration(baseClassDescriptor) as? KtClass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun annotationEntryToClass(entry: KtAnnotationEntry, context: BindingContext): KtClass? {
|
||||||
|
val descriptor =
|
||||||
|
context[BindingContext.ANNOTATION, entry]?.type?.constructor?.declarationDescriptor as? ClassDescriptor ?: return null
|
||||||
|
if (!descriptor.isExpect) return null
|
||||||
|
return DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as? KtClass
|
||||||
|
}
|
||||||
|
|
||||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtClass>? {
|
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtClass>? {
|
||||||
val argumentList = diagnostic.psiElement as? KtValueArgumentList ?: return null
|
val element = diagnostic.psiElement
|
||||||
if (argumentList.arguments.isNotEmpty()) return null
|
if (element is KtValueArgumentList && element.arguments.isNotEmpty()) return null
|
||||||
val derivedClass = argumentList.getStrictParentOfType<KtClassOrObject>() ?: return null
|
val parent = element.getParentOfTypes(true, KtClassOrObject::class.java, KtAnnotationEntry::class.java) ?: return null
|
||||||
val context = derivedClass.analyze()
|
val context by lazy { parent.analyze() }
|
||||||
val baseTypeCallEntry = derivedClass.superTypeListEntries.asSequence().filterIsInstance<KtSuperTypeCallEntry>().firstOrNull()
|
val baseClass = when (parent) {
|
||||||
?: return null
|
is KtClassOrObject -> parent.superTypeListEntries.asSequence().filterIsInstance<KtSuperTypeCallEntry>().firstOrNull()?.let {
|
||||||
val baseClass = superTypeEntryToClass(baseTypeCallEntry, context) ?: return null
|
superTypeEntryToClass(it, context)
|
||||||
|
}
|
||||||
|
is KtAnnotationEntry -> annotationEntryToClass(parent, context)
|
||||||
|
else -> null
|
||||||
|
} ?: return null
|
||||||
return AddDefaultConstructorFix(baseClass)
|
return AddDefaultConstructorFix(baseClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Add default constructor to expect class" "true"
|
||||||
|
// ENABLE_MULTIPLATFORM
|
||||||
|
// ERROR: Expected annotation class 'Foo' has no actual declaration in module light_idea_test_case for JVM
|
||||||
|
|
||||||
|
expect annotation class Foo
|
||||||
|
|
||||||
|
@Foo<caret>
|
||||||
|
fun bar() {}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Add default constructor to expect class" "true"
|
||||||
|
// ENABLE_MULTIPLATFORM
|
||||||
|
// ERROR: Expected annotation class 'Foo' has no actual declaration in module light_idea_test_case for JVM
|
||||||
|
|
||||||
|
expect annotation class Foo()
|
||||||
|
|
||||||
|
@Foo
|
||||||
|
fun bar() {}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Add default constructor to expect class" "true"
|
||||||
|
// ENABLE_MULTIPLATFORM
|
||||||
|
// ERROR: Expected annotation class 'Foo' has no actual declaration in module light_idea_test_case for JVM
|
||||||
|
|
||||||
|
expect annotation class Foo
|
||||||
|
|
||||||
|
@Foo()<caret>
|
||||||
|
fun bar() {}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Add default constructor to expect class" "true"
|
||||||
|
// ENABLE_MULTIPLATFORM
|
||||||
|
// ERROR: Expected annotation class 'Foo' has no actual declaration in module light_idea_test_case for JVM
|
||||||
|
|
||||||
|
expect annotation class Foo()
|
||||||
|
|
||||||
|
@Foo()
|
||||||
|
fun bar() {}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// "Add default constructor to expect class" "false"
|
||||||
|
// ENABLE_MULTIPLATFORM
|
||||||
|
// ACTION: Make internal
|
||||||
|
// ACTION: Make private
|
||||||
|
// ACTION: Remove constructor call
|
||||||
|
// ERROR: Expected annotation class 'Foo' has no actual declaration in module light_idea_test_case for JVM
|
||||||
|
// ERROR: This class does not have a constructor
|
||||||
|
expect annotation class Foo
|
||||||
|
|
||||||
|
@Foo("")<caret>
|
||||||
|
fun bar() {}
|
||||||
@@ -550,6 +550,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/addDefaultConstructor/expect.kt");
|
runTest("idea/testData/quickfix/addDefaultConstructor/expect.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("expectAnnotation.kt")
|
||||||
|
public void testExpectAnnotation() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/addDefaultConstructor/expectAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("expectAnnotation2.kt")
|
||||||
|
public void testExpectAnnotation2() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/addDefaultConstructor/expectAnnotation2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("expectAnnotation3.kt")
|
||||||
|
public void testExpectAnnotation3() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/addDefaultConstructor/expectAnnotation3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("expectInterface.kt")
|
@TestMetadata("expectInterface.kt")
|
||||||
public void testExpectInterface() throws Exception {
|
public void testExpectInterface() throws Exception {
|
||||||
runTest("idea/testData/quickfix/addDefaultConstructor/expectInterface.kt");
|
runTest("idea/testData/quickfix/addDefaultConstructor/expectInterface.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user