Expand "Create expected..." also to a members if an expect class doesn't exist
#KT-31272 Fixed
This commit is contained in:
@@ -74,27 +74,39 @@ sealed class CreateExpectedFix<D : KtNamedDeclaration>(
|
|||||||
// For function we allow it, because overloads are possible
|
// For function we allow it, because overloads are possible
|
||||||
if (compatibility.isNotEmpty() && declaration !is KtFunction) return emptyList()
|
if (compatibility.isNotEmpty() && declaration !is KtFunction) return emptyList()
|
||||||
|
|
||||||
val containingClass = declaration.containingClassOrObject
|
val (actualDeclaration, expectedContainingClass) = findFirstActualWithExpectedClass(declaration)
|
||||||
val expectedContainingClass = containingClass?.liftToExpected() as? KtClassOrObject
|
if (compatibility.isNotEmpty() && actualDeclaration !is KtFunction) return emptyList()
|
||||||
if (containingClass != null && expectedContainingClass == null) {
|
|
||||||
// In this case fix should be invoked on containingClass
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
// If there is already an expected class, we suggest only for its module,
|
// If there is already an expected class, we suggest only for its module,
|
||||||
// otherwise we suggest for all relevant expected modules
|
// otherwise we suggest for all relevant expected modules
|
||||||
val expectedModules = expectedContainingClass?.module?.let { listOf(it) }
|
val expectedModules = expectedContainingClass?.module?.let { listOf(it) }
|
||||||
?: declaration.module?.implementedModules
|
?: actualDeclaration.module?.implementedModules
|
||||||
?: return emptyList()
|
?: return emptyList()
|
||||||
return when (declaration) {
|
return when (actualDeclaration) {
|
||||||
is KtClassOrObject -> expectedModules.map { CreateExpectedClassFix(declaration, expectedContainingClass, it) }
|
is KtClassOrObject -> expectedModules.map { CreateExpectedClassFix(actualDeclaration, expectedContainingClass, it) }
|
||||||
is KtFunction -> expectedModules.map { CreateExpectedFunctionFix(declaration, expectedContainingClass, it) }
|
is KtFunction -> expectedModules.map { CreateExpectedFunctionFix(actualDeclaration, expectedContainingClass, it) }
|
||||||
is KtProperty, is KtParameter -> expectedModules.map { CreateExpectedPropertyFix(declaration, expectedContainingClass, it) }
|
is KtProperty, is KtParameter -> expectedModules.map {
|
||||||
|
CreateExpectedPropertyFix(
|
||||||
|
actualDeclaration,
|
||||||
|
expectedContainingClass,
|
||||||
|
it
|
||||||
|
)
|
||||||
|
}
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private tailrec fun findFirstActualWithExpectedClass(declaration: KtNamedDeclaration): Pair<KtNamedDeclaration, KtClassOrObject?> {
|
||||||
|
val containingClass = declaration.containingClassOrObject
|
||||||
|
val expectedContainingClass = containingClass?.liftToExpected() as? KtClassOrObject
|
||||||
|
return if (containingClass != null && expectedContainingClass == null)
|
||||||
|
findFirstActualWithExpectedClass(containingClass)
|
||||||
|
else
|
||||||
|
declaration to expectedContainingClass
|
||||||
|
}
|
||||||
|
|
||||||
class CreateExpectedClassFix(
|
class CreateExpectedClassFix(
|
||||||
klass: KtClassOrObject,
|
klass: KtClassOrObject,
|
||||||
outerExpectedClass: KtClassOrObject?,
|
outerExpectedClass: KtClassOrObject?,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// "Create expected function in common module testModule_Common" "false"
|
// "Create expected function in common module testModule_Common" "false"
|
||||||
// ACTION: Convert member to extension
|
// ACTION: Convert member to extension
|
||||||
// ACTION: Convert to block body
|
// ACTION: Convert to block body
|
||||||
|
// ACTION: Create expected class in common module testModule_Common
|
||||||
// ACTION: Move to companion object
|
// ACTION: Move to companion object
|
||||||
// ACTION: Remove 'actual' modifier
|
// ACTION: Remove 'actual' modifier
|
||||||
// ACTION: Remove explicit type specification
|
// ACTION: Remove explicit type specification
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
expect class <caret>My {
|
||||||
|
fun foo(param: String): Int
|
||||||
|
fun String.bar(y: Double): Boolean
|
||||||
|
fun baz()
|
||||||
|
|
||||||
|
constructor(flag: Boolean)
|
||||||
|
|
||||||
|
val isGood: Boolean
|
||||||
|
var status: Int
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// "Create expected class in common module testModule_Common" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
|
||||||
|
actual class My {
|
||||||
|
actual fun <caret>foo(param: String): Int = 42
|
||||||
|
|
||||||
|
actual fun String.bar(y: Double): Boolean = true
|
||||||
|
|
||||||
|
actual fun baz() {}
|
||||||
|
|
||||||
|
actual constructor(flag: Boolean) {}
|
||||||
|
|
||||||
|
actual val isGood: Boolean
|
||||||
|
get() = true
|
||||||
|
actual var status: Int
|
||||||
|
get() = 0
|
||||||
|
set(value) {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// "Create expected class in common module testModule_Common" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
|
||||||
|
actual class My {
|
||||||
|
actual fun <caret>foo(param: String): Int = 42
|
||||||
|
|
||||||
|
actual fun String.bar(y: Double): Boolean = true
|
||||||
|
|
||||||
|
actual fun baz() {}
|
||||||
|
|
||||||
|
actual constructor(flag: Boolean) {}
|
||||||
|
|
||||||
|
actual val isGood: Boolean
|
||||||
|
get() = true
|
||||||
|
actual var status: Int
|
||||||
|
get() = 0
|
||||||
|
set(value) {}
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -299,6 +299,11 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul
|
|||||||
runTest("idea/testData/multiModuleQuickFix/expectClassNoAccessOnMember/");
|
runTest("idea/testData/multiModuleQuickFix/expectClassNoAccessOnMember/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("expectClassOnMember")
|
||||||
|
public void testExpectClassOnMember() throws Exception {
|
||||||
|
runTest("idea/testData/multiModuleQuickFix/expectClassOnMember/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("expectClassProperty")
|
@TestMetadata("expectClassProperty")
|
||||||
public void testExpectClassProperty() throws Exception {
|
public void testExpectClassProperty() throws Exception {
|
||||||
runTest("idea/testData/multiModuleQuickFix/expectClassProperty/");
|
runTest("idea/testData/multiModuleQuickFix/expectClassProperty/");
|
||||||
|
|||||||
Reference in New Issue
Block a user