Create actual fix: use target module instead of target platform
This commit is contained in:
@@ -18,11 +18,13 @@ package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||
import org.jetbrains.kotlin.idea.facet.implementingDescriptors
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
@@ -90,10 +92,10 @@ private fun DeclarationDescriptor.actualsForExpected(): Collection<DeclarationDe
|
||||
}
|
||||
|
||||
// null means "any platform" here
|
||||
internal fun KtDeclaration.actualsForExpected(platform: MultiTargetPlatform? = null): Set<KtDeclaration> =
|
||||
internal fun KtDeclaration.actualsForExpected(module: Module? = null): Set<KtDeclaration> =
|
||||
resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
||||
?.actualsForExpected()
|
||||
?.filter { platform == null || it.module.getMultiTargetPlatform() == platform }
|
||||
?.filter { module == null || (it.module.getCapability(ModuleInfo.Capability) as? ModuleSourceInfo)?.module == module }
|
||||
?.mapNotNullTo(LinkedHashSet()) {
|
||||
DescriptorToSourceUtils.descriptorToDeclaration(it) as? KtDeclaration
|
||||
} ?: emptySet()
|
||||
@@ -21,19 +21,18 @@ import com.intellij.ide.util.EditorHelper
|
||||
import com.intellij.ide.util.PackageUtil
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaDirectoryService
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.core.*
|
||||
import org.jetbrains.kotlin.idea.facet.implementingModules
|
||||
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||
import org.jetbrains.kotlin.idea.refactoring.createKotlinFile
|
||||
@@ -47,6 +46,7 @@ import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
|
||||
|
||||
sealed class CreateActualFix<out D : KtNamedDeclaration>(
|
||||
declaration: D,
|
||||
private val actualModule: Module,
|
||||
private val actualPlatform: MultiTargetPlatform.Specific,
|
||||
private val generateIt: KtPsiFactory.(Project, D) -> D?
|
||||
) : KotlinQuickFixAction<D>(declaration) {
|
||||
@@ -55,7 +55,7 @@ sealed class CreateActualFix<out D : KtNamedDeclaration>(
|
||||
|
||||
protected abstract val elementType: String
|
||||
|
||||
override fun getText() = "Create actual $elementType for platform ${actualPlatform.platform}"
|
||||
override fun getText() = "Create actual $elementType for module ${actualModule.name} (${actualPlatform.platform})"
|
||||
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
@@ -88,12 +88,6 @@ sealed class CreateActualFix<out D : KtNamedDeclaration>(
|
||||
}
|
||||
}
|
||||
|
||||
private fun implementationModuleOf(expectedModule: Module) =
|
||||
expectedModule.implementingModules.firstOrNull {
|
||||
PackageUtil.checkSourceRootsConfigured(it, false) &&
|
||||
TargetPlatformDetector.getPlatform(it).multiTargetPlatform == actualPlatform
|
||||
}
|
||||
|
||||
private fun getOrCreateImplementationFile(): KtFile? {
|
||||
val declaration = element as? KtNamedDeclaration ?: return null
|
||||
val parent = declaration.parent
|
||||
@@ -101,7 +95,7 @@ sealed class CreateActualFix<out D : KtNamedDeclaration>(
|
||||
for (otherDeclaration in parent.declarations) {
|
||||
if (otherDeclaration === declaration) continue
|
||||
if (!otherDeclaration.hasExpectModifier()) continue
|
||||
val actualDeclaration = otherDeclaration.actualsForExpected(actualPlatform).singleOrNull() ?: continue
|
||||
val actualDeclaration = otherDeclaration.actualsForExpected(actualModule).singleOrNull() ?: continue
|
||||
return actualDeclaration.containingKtFile
|
||||
}
|
||||
}
|
||||
@@ -110,8 +104,6 @@ sealed class CreateActualFix<out D : KtNamedDeclaration>(
|
||||
val expectedDir = declaration.containingFile.containingDirectory
|
||||
val expectedPackage = JavaDirectoryService.getInstance().getPackage(expectedDir)
|
||||
|
||||
val expectedModule = ModuleUtilCore.findModuleForPsiElement(declaration) ?: return null
|
||||
val actualModule = implementationModuleOf(expectedModule) ?: return null
|
||||
val actualDirectory = PackageUtil.findOrCreateDirectoryForPackage(
|
||||
actualModule, expectedPackage?.qualifiedName ?: "", null, false
|
||||
) ?: return null
|
||||
@@ -147,11 +139,13 @@ sealed class CreateActualFix<out D : KtNamedDeclaration>(
|
||||
val compatibility = d.c
|
||||
// For function we allow it, because overloads are possible
|
||||
if (compatibility.isNotEmpty() && declaration !is KtFunction) return null
|
||||
val actualPlatform = d.b.getMultiTargetPlatform() as? MultiTargetPlatform.Specific ?: return null
|
||||
val actualModuleDescriptor = d.b
|
||||
val actualModule = (actualModuleDescriptor.getCapability(ModuleInfo.Capability) as? ModuleSourceInfo)?.module ?: return null
|
||||
val actualPlatform = actualModuleDescriptor.getMultiTargetPlatform() as? MultiTargetPlatform.Specific ?: return null
|
||||
return when (declaration) {
|
||||
is KtClassOrObject -> CreateActualClassFix(declaration, actualPlatform)
|
||||
is KtFunction -> CreateActualFunctionFix(declaration, actualPlatform)
|
||||
is KtProperty -> CreateActualPropertyFix(declaration, actualPlatform)
|
||||
is KtClassOrObject -> CreateActualClassFix(declaration, actualModule, actualPlatform)
|
||||
is KtFunction -> CreateActualFunctionFix(declaration, actualModule, actualPlatform)
|
||||
is KtProperty -> CreateActualPropertyFix(declaration, actualModule, actualPlatform)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -160,8 +154,9 @@ sealed class CreateActualFix<out D : KtNamedDeclaration>(
|
||||
|
||||
class CreateActualClassFix(
|
||||
klass: KtClassOrObject,
|
||||
actualModule: Module,
|
||||
actualPlatform: MultiTargetPlatform.Specific
|
||||
) : CreateActualFix<KtClassOrObject>(klass, actualPlatform, { project, element ->
|
||||
) : CreateActualFix<KtClassOrObject>(klass, actualModule, actualPlatform, { project, element ->
|
||||
generateClassOrObjectByExpectedClass(project, element, actualNeeded = true)
|
||||
}) {
|
||||
|
||||
@@ -182,8 +177,9 @@ class CreateActualClassFix(
|
||||
|
||||
class CreateActualPropertyFix(
|
||||
property: KtProperty,
|
||||
actualModule: Module,
|
||||
actualPlatform: MultiTargetPlatform.Specific
|
||||
) : CreateActualFix<KtProperty>(property, actualPlatform, { project, element ->
|
||||
) : CreateActualFix<KtProperty>(property, actualModule, actualPlatform, { project, element ->
|
||||
val descriptor = element.toDescriptor() as? PropertyDescriptor
|
||||
descriptor?.let { generateProperty(project, element, descriptor, actualNeeded = true) }
|
||||
}) {
|
||||
@@ -193,8 +189,9 @@ class CreateActualPropertyFix(
|
||||
|
||||
class CreateActualFunctionFix(
|
||||
function: KtFunction,
|
||||
actualModule: Module,
|
||||
actualPlatform: MultiTargetPlatform.Specific
|
||||
) : CreateActualFix<KtFunction>(function, actualPlatform, { project, element ->
|
||||
) : CreateActualFix<KtFunction>(function, actualModule, actualPlatform, { project, element ->
|
||||
val descriptor = element.toDescriptor() as? FunctionDescriptor
|
||||
descriptor?.let { generateFunction(project, element, descriptor, actualNeeded = true) }
|
||||
}) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JS" "true"
|
||||
// "Create actual class for module js (JS)" "true"
|
||||
|
||||
expect abstract class <caret>Abstract {
|
||||
fun foo(param: String): Int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JS" "true"
|
||||
// "Create actual class for module js (JS)" "true"
|
||||
|
||||
expect abstract class Abstract {
|
||||
fun foo(param: String): Int
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual annotation class for platform JVM" "true"
|
||||
// "Create actual annotation class for module jvm (JVM)" "true"
|
||||
|
||||
expect annotation class <caret>Ann(val x: Int, val y: String)
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual annotation class for platform JVM" "true"
|
||||
// "Create actual annotation class for module jvm (JVM)" "true"
|
||||
|
||||
expect annotation class Ann(val x: Int, val y: String)
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
|
||||
expect class <caret>My {
|
||||
fun foo(param: String): Int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
|
||||
expect class My {
|
||||
fun foo(param: String): Int
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create actual enum class for platform JS" "true"
|
||||
// "Create actual enum class for module js (JS)" "true"
|
||||
|
||||
expect enum class <caret>MyEnum {
|
||||
FIRST,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual enum class for platform JS" "true"
|
||||
// "Create actual enum class for module js (JS)" "true"
|
||||
|
||||
expect enum class MyEnum {
|
||||
FIRST,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun <caret>foo(arg: Int): String
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun foo(arg: Int): String
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun bar()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun bar()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual interface for platform JVM" "true"
|
||||
// "Create actual interface for module jvm (JVM)" "true"
|
||||
|
||||
expect interface <caret>Interface {
|
||||
fun foo(param: String): Int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual interface for platform JVM" "true"
|
||||
// "Create actual interface for module jvm (JVM)" "true"
|
||||
|
||||
expect interface Interface {
|
||||
fun foo(param: String): Int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
|
||||
expect class <caret>WithNested {
|
||||
fun foo(): Int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
|
||||
expect class WithNested {
|
||||
fun foo(): Int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual object for platform JVM" "true"
|
||||
// "Create actual object for module jvm (JVM)" "true"
|
||||
|
||||
expect object <caret>Object {
|
||||
fun foo(): String
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual object for platform JVM" "true"
|
||||
// "Create actual object for module jvm (JVM)" "true"
|
||||
|
||||
expect object Object {
|
||||
fun foo(): String
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
|
||||
package test.inner
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
|
||||
package test.inner
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
|
||||
package test.inner
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
|
||||
package test.inner
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
|
||||
package test.inner
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
|
||||
package test.inner
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
|
||||
expect class <caret>WithPrimaryConstructor(x: Int, s: String)
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
// "Create actual class for platform JVM" "true"
|
||||
// "Create actual class for module jvm (JVM)" "true"
|
||||
|
||||
expect class WithPrimaryConstructor(x: Int, s: String)
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual property for platform JVM" "true"
|
||||
// "Create actual property for module jvm (JVM)" "true"
|
||||
|
||||
expect var <caret>x: Int
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual property for platform JVM" "true"
|
||||
// "Create actual property for module jvm (JVM)" "true"
|
||||
|
||||
expect var x: Int
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JS" "true"
|
||||
// "Create actual class for module js (JS)" "true"
|
||||
|
||||
expect sealed class <caret>Sealed {
|
||||
object Obj : Sealed
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JS" "true"
|
||||
// "Create actual class for module js (JS)" "true"
|
||||
|
||||
expect sealed class Sealed {
|
||||
object Obj : Sealed
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JS" "true"
|
||||
// "Create actual class for module js (JS)" "true"
|
||||
|
||||
expect sealed class Sealed
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual class for platform JS" "true"
|
||||
// "Create actual class for module js (JS)" "true"
|
||||
|
||||
expect sealed class Sealed
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun <caret>foo(arg: Int): String
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun foo(arg: Int): String
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
// TEST
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
// TEST
|
||||
|
||||
package test
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun <caret>testHelper()
|
||||
@@ -1,3 +1,3 @@
|
||||
// "Create actual function for platform JVM" "true"
|
||||
// "Create actual function for module jvm (JVM)" "true"
|
||||
|
||||
expect fun testHelper()
|
||||
Reference in New Issue
Block a user