ExpectActualUtils: should remove override
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.idea.core.ShortenReferences
|
|||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||||
|
import org.jetbrains.kotlin.idea.util.module
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
@@ -55,9 +56,10 @@ class AddActualFix(
|
|||||||
ShortenReferences.DEFAULT.process(codeStyleManager.reformat(this) as KtElement)
|
ShortenReferences.DEFAULT.process(codeStyleManager.reformat(this) as KtElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val module = element.module ?: return
|
||||||
for (missedDeclaration in missedDeclarationPointers.mapNotNull { it.element }) {
|
for (missedDeclaration in missedDeclarationPointers.mapNotNull { it.element }) {
|
||||||
val actualDeclaration = when (missedDeclaration) {
|
val actualDeclaration = when (missedDeclaration) {
|
||||||
is KtClassOrObject -> factory.generateClassOrObject(project, false, missedDeclaration, outerClasses = listOf(element))
|
is KtClassOrObject -> factory.generateClassOrObject(project, false, missedDeclaration, module, listOf(element))
|
||||||
is KtFunction -> missedDeclaration.toDescriptor()?.safeAs<FunctionDescriptor>()?.let {
|
is KtFunction -> missedDeclaration.toDescriptor()?.safeAs<FunctionDescriptor>()?.let {
|
||||||
generateFunction(project, false, missedDeclaration, it, element)
|
generateFunction(project, false, missedDeclaration, it, element)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
|||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||||
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
||||||
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
|
|
||||||
sealed class CreateActualFix<D : KtNamedDeclaration>(
|
sealed class CreateActualFix<D : KtNamedDeclaration>(
|
||||||
declaration: D,
|
declaration: D,
|
||||||
@@ -87,7 +87,7 @@ class CreateActualClassFix(
|
|||||||
actualModule: Module,
|
actualModule: Module,
|
||||||
actualPlatform: TargetPlatform
|
actualPlatform: TargetPlatform
|
||||||
) : CreateActualFix<KtClassOrObject>(klass, actualModule, actualPlatform, { project, element ->
|
) : CreateActualFix<KtClassOrObject>(klass, actualModule, actualPlatform, { project, element ->
|
||||||
generateClassOrObject(project, false, element)
|
generateClassOrObject(project, false, element, targetModule = actualModule)
|
||||||
})
|
})
|
||||||
|
|
||||||
class CreateActualPropertyFix(
|
class CreateActualPropertyFix(
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getSuperNames
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -286,7 +287,16 @@ class CreateExpectedPropertyFix(
|
|||||||
return@block null
|
return@block null
|
||||||
}
|
}
|
||||||
val descriptor = element.toDescriptor() as? PropertyDescriptor
|
val descriptor = element.toDescriptor() as? PropertyDescriptor
|
||||||
descriptor?.let { generateProperty(project, true, element, descriptor, targetExpectedClass) }
|
descriptor?.let {
|
||||||
|
generateProperty(
|
||||||
|
project,
|
||||||
|
true,
|
||||||
|
element,
|
||||||
|
descriptor,
|
||||||
|
targetExpectedClass,
|
||||||
|
existingFqNames = targetExpectedClass?.getSuperNames().orEmpty()
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class CreateExpectedFunctionFix(
|
class CreateExpectedFunctionFix(
|
||||||
@@ -299,6 +309,15 @@ class CreateExpectedFunctionFix(
|
|||||||
return@block null
|
return@block null
|
||||||
}
|
}
|
||||||
val descriptor = element.toDescriptor() as? FunctionDescriptor
|
val descriptor = element.toDescriptor() as? FunctionDescriptor
|
||||||
descriptor?.let { generateFunction(project, true, element, descriptor, targetExpectedClass) }
|
descriptor?.let {
|
||||||
|
generateFunction(
|
||||||
|
project,
|
||||||
|
true,
|
||||||
|
element,
|
||||||
|
descriptor,
|
||||||
|
targetExpectedClass,
|
||||||
|
existingFqNames = targetExpectedClass?.getSuperNames().orEmpty()
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -117,13 +117,13 @@ internal fun KtPsiFactory.generateClassOrObject(
|
|||||||
project: Project,
|
project: Project,
|
||||||
generateExpectClass: Boolean,
|
generateExpectClass: Boolean,
|
||||||
originalClass: KtClassOrObject,
|
originalClass: KtClassOrObject,
|
||||||
targetModule: Module? = null,
|
targetModule: Module,
|
||||||
outerClasses: List<KtClassOrObject> = emptyList(),
|
outerClasses: List<KtClassOrObject> = emptyList(),
|
||||||
existingFqNames: Set<String> = emptySet()
|
existingFqNames: Set<String> = emptySet()
|
||||||
): KtClassOrObject {
|
): KtClassOrObject {
|
||||||
val generatedClass = createClassHeaderCopyByText(originalClass)
|
val generatedClass = createClassHeaderCopyByText(originalClass)
|
||||||
val context = originalClass.analyzeWithContent()
|
val context = originalClass.analyzeWithContent()
|
||||||
repairSuperTypeList(
|
val superNames = repairSuperTypeList(
|
||||||
generatedClass,
|
generatedClass,
|
||||||
originalClass,
|
originalClass,
|
||||||
generateExpectClass,
|
generateExpectClass,
|
||||||
@@ -179,7 +179,7 @@ internal fun KtPsiFactory.generateClassOrObject(
|
|||||||
descriptor as FunctionDescriptor,
|
descriptor as FunctionDescriptor,
|
||||||
generatedClass,
|
generatedClass,
|
||||||
existingClasses,
|
existingClasses,
|
||||||
existingFqNames
|
existingFqNames + superNames
|
||||||
)
|
)
|
||||||
is KtProperty -> generateProperty(
|
is KtProperty -> generateProperty(
|
||||||
project,
|
project,
|
||||||
@@ -188,7 +188,7 @@ internal fun KtPsiFactory.generateClassOrObject(
|
|||||||
descriptor as PropertyDescriptor,
|
descriptor as PropertyDescriptor,
|
||||||
generatedClass,
|
generatedClass,
|
||||||
existingClasses,
|
existingClasses,
|
||||||
existingFqNames
|
existingFqNames + superNames
|
||||||
)
|
)
|
||||||
else -> continue@declLoop
|
else -> continue@declLoop
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ internal fun KtPsiFactory.generateClassOrObject(
|
|||||||
descriptor,
|
descriptor,
|
||||||
generatedClass,
|
generatedClass,
|
||||||
outerClasses,
|
outerClasses,
|
||||||
existingFqNames
|
existingFqNames + superNames
|
||||||
)
|
)
|
||||||
generatedClass.addDeclaration(generatedProperty)
|
generatedClass.addDeclaration(generatedProperty)
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@ internal fun KtPsiFactory.generateClassOrObject(
|
|||||||
descriptor,
|
descriptor,
|
||||||
generatedClass,
|
generatedClass,
|
||||||
outerClasses,
|
outerClasses,
|
||||||
existingFqNames
|
existingFqNames + superNames
|
||||||
)
|
)
|
||||||
generatedClass.createPrimaryConstructorIfAbsent().replace(expectedPrimaryConstructor)
|
generatedClass.createPrimaryConstructorIfAbsent().replace(expectedPrimaryConstructor)
|
||||||
}
|
}
|
||||||
@@ -245,7 +245,8 @@ private fun KtPsiFactory.repairSuperTypeList(
|
|||||||
targetModule: Module?,
|
targetModule: Module?,
|
||||||
existingFqNames: Set<String>,
|
existingFqNames: Set<String>,
|
||||||
context: BindingContext
|
context: BindingContext
|
||||||
) {
|
): Collection<String> {
|
||||||
|
val superNames = linkedSetOf<String>()
|
||||||
generated.superTypeListEntries.zip(original.superTypeListEntries).forEach { (generatedEntry, originalEntry) ->
|
generated.superTypeListEntries.zip(original.superTypeListEntries).forEach { (generatedEntry, originalEntry) ->
|
||||||
val superType = context[BindingContext.TYPE, originalEntry.typeReference]
|
val superType = context[BindingContext.TYPE, originalEntry.typeReference]
|
||||||
val superClassDescriptor = superType?.constructor?.declarationDescriptor as? ClassDescriptor ?: return@forEach
|
val superClassDescriptor = superType?.constructor?.declarationDescriptor as? ClassDescriptor ?: return@forEach
|
||||||
@@ -257,6 +258,7 @@ private fun KtPsiFactory.repairSuperTypeList(
|
|||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
|
superType.fqName?.shortName()?.asString()?.let { superNames += it }
|
||||||
if (generateExpectClass) {
|
if (generateExpectClass) {
|
||||||
if (generatedEntry !is KtSuperTypeCallEntry) return@forEach
|
if (generatedEntry !is KtSuperTypeCallEntry) return@forEach
|
||||||
} else {
|
} else {
|
||||||
@@ -275,6 +277,7 @@ private fun KtPsiFactory.repairSuperTypeList(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (generated.superTypeListEntries.isEmpty()) generated.getSuperTypeList()?.delete()
|
if (generated.superTypeListEntries.isEmpty()) generated.getSuperTypeList()?.delete()
|
||||||
|
return superNames
|
||||||
}
|
}
|
||||||
|
|
||||||
private val forbiddenAnnotationFqNames = setOf(
|
private val forbiddenAnnotationFqNames = setOf(
|
||||||
@@ -290,7 +293,7 @@ internal fun generateFunction(
|
|||||||
descriptor: FunctionDescriptor,
|
descriptor: FunctionDescriptor,
|
||||||
generatedClass: KtClassOrObject? = null,
|
generatedClass: KtClassOrObject? = null,
|
||||||
outerClasses: List<KtClassOrObject> = emptyList(),
|
outerClasses: List<KtClassOrObject> = emptyList(),
|
||||||
existingFqNames: Set<String> = emptySet()
|
existingFqNames: Collection<String> = emptySet()
|
||||||
): KtFunction {
|
): KtFunction {
|
||||||
if (generateExpect) {
|
if (generateExpect) {
|
||||||
val accessibleClasses = outerClasses + listOfNotNull(generatedClass)
|
val accessibleClasses = outerClasses + listOfNotNull(generatedClass)
|
||||||
@@ -309,7 +312,7 @@ internal fun generateFunction(
|
|||||||
copyDoc = true,
|
copyDoc = true,
|
||||||
project = project,
|
project = project,
|
||||||
mode = if (generateExpect) MemberGenerateMode.EXPECT else MemberGenerateMode.ACTUAL
|
mode = if (generateExpect) MemberGenerateMode.EXPECT else MemberGenerateMode.ACTUAL
|
||||||
) as KtFunction
|
).also { if (generatedClass != null) it.repairOverride(descriptor, existingFqNames) } as KtFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun generateProperty(
|
internal fun generateProperty(
|
||||||
@@ -319,7 +322,7 @@ internal fun generateProperty(
|
|||||||
descriptor: PropertyDescriptor,
|
descriptor: PropertyDescriptor,
|
||||||
generatedClass: KtClassOrObject? = null,
|
generatedClass: KtClassOrObject? = null,
|
||||||
outerClasses: List<KtClassOrObject> = emptyList(),
|
outerClasses: List<KtClassOrObject> = emptyList(),
|
||||||
existingFqNames: Set<String> = emptySet()
|
existingFqNames: Collection<String> = emptySet()
|
||||||
): KtProperty {
|
): KtProperty {
|
||||||
if (generateExpect) {
|
if (generateExpect) {
|
||||||
val accessibleClasses = outerClasses + listOfNotNull(generatedClass)
|
val accessibleClasses = outerClasses + listOfNotNull(generatedClass)
|
||||||
@@ -335,7 +338,16 @@ internal fun generateProperty(
|
|||||||
copyDoc = true,
|
copyDoc = true,
|
||||||
project = project,
|
project = project,
|
||||||
mode = if (generateExpect) MemberGenerateMode.EXPECT else MemberGenerateMode.ACTUAL
|
mode = if (generateExpect) MemberGenerateMode.EXPECT else MemberGenerateMode.ACTUAL
|
||||||
) as KtProperty
|
).also { if (generatedClass != null) it.repairOverride(descriptor, existingFqNames) } as KtProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KtCallableDeclaration.repairOverride(descriptor: CallableDescriptor, existingFqNames: Collection<String>) {
|
||||||
|
if (!hasModifier(KtTokens.OVERRIDE_KEYWORD)) return
|
||||||
|
|
||||||
|
val superDescriptor = descriptor.overriddenDescriptors.firstOrNull()?.containingDeclaration
|
||||||
|
if (superDescriptor?.fqNameOrNull()?.shortName()?.asString() !in existingFqNames) {
|
||||||
|
removeModifier(KtTokens.OVERRIDE_KEYWORD)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CallableMemberDescriptor.checkTypeParameterBoundsAccessibility(accessibleClasses: List<KtClassOrObject>) {
|
private fun CallableMemberDescriptor.checkTypeParameterBoundsAccessibility(accessibleClasses: List<KtClassOrObject>) {
|
||||||
@@ -427,11 +439,11 @@ private tailrec fun DeclarationDescriptor.additionalClasses(existingClasses: Set
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun DeclarationDescriptor.collectAllTypes(): Sequence<FqName?> {
|
private fun DeclarationDescriptor.collectAllTypes(): Sequence<FqName?> {
|
||||||
return sequenceOf(fqNameOrNull()) + when (this) {
|
return when (this) {
|
||||||
is ClassConstructorDescriptor -> valueParameters.asSequence().map(ValueParameterDescriptor::getType).flatMap(KotlinType::collectAllTypes)
|
is ClassConstructorDescriptor -> valueParameters.asSequence().map(ValueParameterDescriptor::getType).flatMap(KotlinType::collectAllTypes)
|
||||||
is ClassDescriptor -> if (isInline) unsubstitutedPrimaryConstructor?.collectAllTypes().orEmpty() else {
|
is ClassDescriptor -> if (isInline) unsubstitutedPrimaryConstructor?.collectAllTypes().orEmpty() else {
|
||||||
emptySequence()
|
emptySequence()
|
||||||
} + declaredTypeParameters.asSequence().flatMap(DeclarationDescriptor::collectAllTypes)
|
} + declaredTypeParameters.asSequence().flatMap(DeclarationDescriptor::collectAllTypes) + sequenceOf(fqNameOrNull())
|
||||||
is CallableDescriptor -> {
|
is CallableDescriptor -> {
|
||||||
val returnType = returnType ?: return sequenceOf(null)
|
val returnType = returnType ?: return sequenceOf(null)
|
||||||
returnType.collectAllTypes() + explicitParameters.asSequence().map(ParameterDescriptor::getType).flatMap(KotlinType::collectAllTypes)
|
returnType.collectAllTypes() + explicitParameters.asSequence().map(ParameterDescriptor::getType).flatMap(KotlinType::collectAllTypes)
|
||||||
|
|||||||
Reference in New Issue
Block a user