From a21375508d709532b8487421f2701ab771b1eae4 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Fri, 2 Aug 2019 16:04:33 +0300 Subject: [PATCH] ExpectActualUtils: drop `missedDeclarations` parameter from `generateClassOrObject` function --- .../quickfix/expectactual/AddActualFix.kt | 59 +++++++++---------- .../expectactual/ExpectActualUtils.kt | 24 +------- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/AddActualFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/AddActualFix.kt index d5535c5c60a..7f4d4c6d025 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/AddActualFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/AddActualFix.kt @@ -21,25 +21,24 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.codeStyle.CodeStyleManager -import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.DiagnosticFactory import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.core.ShortenReferences +import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class AddActualFix( actualClassOrObject: KtClassOrObject, - expectedClassOrObject: KtClassOrObject, missedDeclarations: List ) : KotlinQuickFixAction(actualClassOrObject) { - - private val expectedClassPointer = expectedClassOrObject.createSmartPointer() - private val missedDeclarationPointers = missedDeclarations.map { it.createSmartPointer() } override fun getFamilyName() = text @@ -48,45 +47,43 @@ class AddActualFix( override fun invoke(project: Project, editor: Editor?, file: KtFile) { val element = element ?: return - val expectedClass = expectedClassPointer.element ?: return - val missedDeclarations = missedDeclarationPointers.mapNotNull { it.element } - if (missedDeclarations.isEmpty()) return val factory = KtPsiFactory(element) - val pureActualClass = factory.generateClassOrObject( - project, false, expectedClass, - missedDeclarations = missedDeclarations - ) + + val codeStyleManager = CodeStyleManager.getInstance(project) fun PsiElement.clean() { - val reformatted = CodeStyleManager.getInstance(project).reformat(this) - ShortenReferences.DEFAULT.process(reformatted as KtElement) + ShortenReferences.DEFAULT.process(codeStyleManager.reformat(this) as KtElement) } - for (declaration in pureActualClass.declarations) { - element.addDeclaration(declaration).clean() - } - val primaryConstructor = pureActualClass.primaryConstructor - if (element.primaryConstructor == null && primaryConstructor != null) { - element.addAfter(primaryConstructor, element.nameIdentifier).clean() + for (missedDeclaration in missedDeclarationPointers.mapNotNull { it.element }) { + val actualDeclaration = when (missedDeclaration) { + is KtClassOrObject -> factory.generateClassOrObject(project, false, missedDeclaration, listOf(element)) + is KtFunction -> missedDeclaration.toDescriptor()?.safeAs()?.let { + generateFunction(project, false, missedDeclaration, it, element) + } + is KtProperty -> missedDeclaration.toDescriptor()?.safeAs()?.let { + generateProperty(project, false, missedDeclaration, it, element) + } + else -> null + } ?: continue + + if (actualDeclaration is KtPrimaryConstructor) { + if (element.primaryConstructor == null) + element.addAfter(actualDeclaration, element.nameIdentifier).clean() + } else { + element.addDeclaration(actualDeclaration).clean() + } } } companion object : KotlinSingleIntentionActionFactory() { override fun createAction(diagnostic: Diagnostic): IntentionAction? { - val incompatibleMap = DiagnosticFactory.cast(diagnostic, Errors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS).b - - val expectedClassDescriptor = incompatibleMap.firstOrNull()?.first?.containingDeclaration as? ClassDescriptor - ?: return null - val expectedClassOrObject = DescriptorToSourceUtils.descriptorToDeclaration(expectedClassDescriptor) as? KtClassOrObject - ?: return null - - val missedDeclarations = incompatibleMap.mapNotNull { + val missedDeclarations = DiagnosticFactory.cast(diagnostic, Errors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS).b.mapNotNull { DescriptorToSourceUtils.descriptorToDeclaration(it.first) as? KtDeclaration - } - if (missedDeclarations.isEmpty()) return null + }.ifEmpty { return null } return (diagnostic.psiElement as? KtClassOrObject)?.let { - AddActualFix(it, expectedClassOrObject, missedDeclarations) + AddActualFix(it, missedDeclarations) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt index 6303d55de33..2ce3bd7c475 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt @@ -109,26 +109,8 @@ internal fun KtPsiFactory.generateClassOrObject( project: Project, generateExpectClass: Boolean, originalClass: KtClassOrObject, - outerClasses: List = emptyList(), - // If null, all class declarations are missed (so none from them exists) - missedDeclarations: List? = null + outerClasses: List = emptyList() ): KtClassOrObject { - fun areCompatible(first: KtFunction, second: KtFunction) = - first.valueParameters.size == second.valueParameters.size && - first.valueParameters.zip(second.valueParameters).all { (firstParam, secondParam) -> - firstParam.name == secondParam.name && firstParam.typeReference?.text == secondParam.typeReference?.text - } - - fun KtDeclaration.exists() = - missedDeclarations != null && missedDeclarations.none { - name == it.name && when (this) { - is KtConstructor<*> -> it is KtConstructor<*> && areCompatible(this, it) - is KtNamedFunction -> it is KtNamedFunction && areCompatible(this, it) - is KtProperty -> it is KtProperty || it is KtParameter && it.hasValOrVar() - else -> this.javaClass == it.javaClass - } - } - val generatedClass = createClassHeaderCopyByText(originalClass) val context = originalClass.analyzeWithContent() @@ -169,7 +151,8 @@ internal fun KtPsiFactory.generateClassOrObject( generatedClass.addModifier(KtTokens.ACTUAL_KEYWORD) } } - declLoop@ for (originalDeclaration in originalClass.declarations.filter { !it.exists() }) { + + declLoop@ for (originalDeclaration in originalClass.declarations) { val descriptor = originalDeclaration.toDescriptor() ?: continue if (generateExpectClass && !originalDeclaration.isEffectivelyActual(false)) continue val generatedDeclaration: KtDeclaration = when (originalDeclaration) { @@ -206,7 +189,6 @@ internal fun KtPsiFactory.generateClassOrObject( generatedClass is KtClass && originalPrimaryConstructor != null && (!generateExpectClass || originalPrimaryConstructor.hasActualModifier()) - && !originalPrimaryConstructor.exists() ) { val descriptor = originalPrimaryConstructor.toDescriptor() if (descriptor is FunctionDescriptor) {