From f31428257db75bc8c8c7facd96976367e61197b1 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 20 Nov 2018 13:48:48 +0300 Subject: [PATCH] Add a set of new tests for KT-27075 (create expected class) + some fixes --- .../kotlin/renderer/DescriptorRenderer.kt | 4 +- .../kotlin/renderer/DescriptorRendererImpl.kt | 30 ++++++++------ .../renderer/DescriptorRendererOptionsImpl.kt | 2 + .../OverrideMemberChooserObject.kt | 28 ++++++------- .../quickfix/expectactual/CreateActualFix.kt | 4 +- .../expectactual/CreateExpectedFix.kt | 14 ++++++- .../expectClassCommented/header/My.kt | 2 + .../expectClassCommented/header/My.kt.after | 24 +++++++++++ .../expectClassCommented/jvm/My.kt | 35 ++++++++++++++++ .../expectClassCommented/jvm/My.kt.after | 35 ++++++++++++++++ .../jvm/My.kt.after | 2 +- .../expectClassWithAliases/common/My.kt.after | 5 +++ .../expectClassWithAliases/jvm/My.kt | 12 ++++++ .../expectClassWithAliases/jvm/My.kt.after | 12 ++++++ .../expectDataClass/common/My.kt.after | 4 ++ .../expectDataClass/jvm/My.kt | 4 ++ .../expectDataClass/jvm/My.kt.after | 4 ++ .../expectEnum/header/My.kt.after | 2 - .../expectEnumEmpty/header/My.kt | 2 + .../expectEnumEmpty/header/My.kt.after | 8 ++++ .../expectEnumEmpty/jvm/My.kt | 8 ++++ .../expectEnumEmpty/jvm/My.kt.after | 8 ++++ .../proj_common/createList.kt.after | 1 + .../proj_jvm_dep(fulljdk)/Utils.kt | 6 +++ .../proj_jvm_dep(fulljdk)/Utils.kt.after | 6 +++ .../expectNestedClass/common/My.kt.after | 3 ++ .../expectSealedClass/header/My.kt | 2 + .../expectSealedClass/header/My.kt.after | 21 ++++++++++ .../expectSealedClass/jvm/My.kt | 21 ++++++++++ .../expectSealedClass/jvm/My.kt.after | 21 ++++++++++ .../expectTypeAlias/common/My.kt | 1 + .../expectTypeAlias/jvm/My.kt | 9 +++++ .../expectWithAnnotations/header/My.kt | 4 ++ .../expectWithAnnotations/header/My.kt.after | 10 +++++ .../expectWithAnnotations/jvm/My.kt | 20 ++++++++++ .../expectWithAnnotations/jvm/My.kt.after | 20 ++++++++++ .../QuickFixMultiModuleTestGenerated.java | 40 +++++++++++++++++++ 37 files changed, 400 insertions(+), 34 deletions(-) create mode 100644 idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectClassWithAliases/common/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectDataClass/common/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_common/createList.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt create mode 100644 idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectTypeAlias/common/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectTypeAlias/jvm/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt.after create mode 100644 idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt create mode 100644 idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt.after diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt index 8bd592701d7..d666122fa81 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name @@ -219,6 +218,7 @@ interface DescriptorRendererOptions { var alwaysRenderModifiers: Boolean var renderConstructorKeyword: Boolean var renderUnabbreviatedType: Boolean + var renderTypeExpansions: Boolean var includeAdditionalModifiers: Boolean var parameterNamesInFunctionalTypes: Boolean var renderFunctionContracts: Boolean @@ -272,6 +272,8 @@ enum class DescriptorRendererModifier(val includeByDefault: Boolean) { INLINE(true), EXPECT(true), ACTUAL(true), + CONST(true), + LATEINIT(true), ; companion object { diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt index 4e72a071651..edf3e583ee8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt @@ -129,10 +129,14 @@ internal class DescriptorRendererImpl( private fun StringBuilder.renderNormalizedType(type: KotlinType) { val abbreviated = type.unwrap() as? AbbreviatedType if (abbreviated != null) { - // TODO nullability is lost for abbreviated type? - renderNormalizedTypeAsIs(abbreviated.abbreviation) - if (renderUnabbreviatedType) { - renderAbbreviatedTypeExpansion(abbreviated) + if (renderTypeExpansions) { + renderNormalizedTypeAsIs(abbreviated.expandedType) + } else { + // TODO nullability is lost for abbreviated type? + renderNormalizedTypeAsIs(abbreviated.abbreviation) + if (renderUnabbreviatedType) { + renderAbbreviatedTypeExpansion(abbreviated) + } } return } @@ -468,15 +472,16 @@ internal class DescriptorRendererImpl( } } - private fun renderVisibility(visibility: Visibility, builder: StringBuilder) { + private fun renderVisibility(visibility: Visibility, builder: StringBuilder): Boolean { @Suppress("NAME_SHADOWING") var visibility = visibility - if (DescriptorRendererModifier.VISIBILITY !in modifiers) return + if (DescriptorRendererModifier.VISIBILITY !in modifiers) return false if (normalizedVisibilities) { visibility = visibility.normalize() } - if (!renderDefaultVisibility && visibility == Visibilities.DEFAULT_VISIBILITY) return + if (!renderDefaultVisibility && visibility == Visibilities.DEFAULT_VISIBILITY) return false builder.append(renderKeyword(visibility.displayName)).append(" ") + return true } private fun renderModality(modality: Modality, builder: StringBuilder, defaultModality: Modality) { @@ -719,15 +724,16 @@ internal class DescriptorRendererImpl( private fun renderConstructor(constructor: ConstructorDescriptor, builder: StringBuilder) { builder.renderAnnotations(constructor) - renderVisibility(constructor.visibility, builder) + val visibilityRendered = renderVisibility(constructor.visibility, builder) renderMemberKind(constructor, builder) - if (renderConstructorKeyword) { + val constructorKeywordRendered = renderConstructorKeyword || !constructor.isPrimary || visibilityRendered + if (constructorKeywordRendered) { builder.append(renderKeyword("constructor")) } val classDescriptor = constructor.containingDeclaration if (secondaryConstructorsAsPrimary) { - if (renderConstructorKeyword) { + if (constructorKeywordRendered) { builder.append(" ") } renderName(classDescriptor, builder, true) @@ -861,11 +867,11 @@ internal class DescriptorRendererImpl( if (!startFromDeclarationKeyword) { renderPropertyAnnotations(property, builder) renderVisibility(property.visibility, builder) - renderModifier(builder, property.isConst, "const") + renderModifier(builder, DescriptorRendererModifier.CONST in modifiers && property.isConst, "const") renderMemberModifiers(property, builder) renderModalityForCallable(property, builder) renderOverride(property, builder) - renderModifier(builder, property.isLateInit, "lateinit") + renderModifier(builder, DescriptorRendererModifier.LATEINIT in modifiers && property.isLateInit, "lateinit") renderMemberKind(property, builder) } renderValVarPrefix(property, builder) diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt index c0e049f3cb7..65e9a6c8466 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt @@ -116,6 +116,8 @@ internal class DescriptorRendererOptionsImpl : DescriptorRendererOptions { override var renderUnabbreviatedType: Boolean by property(true) + override var renderTypeExpansions: Boolean by property(false) + override var includeAdditionalModifiers: Boolean by property(true) override var parameterNamesInFunctionalTypes: Boolean by property(true) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt index bff577a4e25..3df59d0f4e5 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt @@ -41,6 +41,8 @@ import org.jetbrains.kotlin.psi.findDocComment.findDocComment import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.renderer.* +import org.jetbrains.kotlin.renderer.DescriptorRenderer.Companion.withOptions +import org.jetbrains.kotlin.renderer.DescriptorRendererModifier.* import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden import org.jetbrains.kotlin.util.findCallableMemberBySignature @@ -118,8 +120,8 @@ interface OverrideMemberChooserObject : ClassMember { } fun OverrideMemberChooserObject.generateTopLevelActual( - copyDoc: Boolean, - project: Project + project: Project, + copyDoc: Boolean ) = generateMember(null, copyDoc, project, forceActual = true, forceExpect = false) fun OverrideMemberChooserObject.generateActualMember( @@ -128,8 +130,8 @@ fun OverrideMemberChooserObject.generateActualMember( ) = generateMember(targetClass, copyDoc, targetClass.project, forceActual = true, forceExpect = false) fun OverrideMemberChooserObject.generateTopLevelExpect( - copyDoc: Boolean, - project: Project + project: Project, + copyDoc: Boolean ) = generateMember(null, copyDoc, project, forceActual = false, forceExpect = true) fun OverrideMemberChooserObject.generateExpectMember( @@ -177,8 +179,6 @@ private fun OverrideMemberChooserObject.generateMember( forceActual -> newMember.addModifier(KtTokens.ACTUAL_KEYWORD) forceExpect -> if (targetClass == null) { newMember.addModifier(KtTokens.EXPECT_KEYWORD) - } else { - newMember.makeNotActual() } targetClass?.hasActualModifier() == true -> { val expectClassDescriptors = @@ -191,9 +191,6 @@ private fun OverrideMemberChooserObject.generateMember( newMember.addModifier(KtTokens.ACTUAL_KEYWORD) } } - else -> { - newMember.makeNotActual() - } } if (copyDoc) { @@ -215,9 +212,9 @@ private fun OverrideMemberChooserObject.generateMember( return newMember } -private val OVERRIDE_RENDERER = DescriptorRenderer.withOptions { +private val OVERRIDE_RENDERER = withOptions { defaultParameterValueRenderer = null - modifiers = setOf(DescriptorRendererModifier.OVERRIDE, DescriptorRendererModifier.ANNOTATIONS) + modifiers = setOf(OVERRIDE, ANNOTATIONS) withDefinedIn = false classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OVERRIDE @@ -232,17 +229,20 @@ private val OVERRIDE_RENDERER = DescriptorRenderer.withOptions { } private val EXPECT_RENDERER = OVERRIDE_RENDERER.withOptions { - modifiers = DescriptorRendererModifier.ALL - renderConstructorKeyword = true + modifiers = setOf(VISIBILITY, MODALITY, OVERRIDE, INNER, MEMBER_KIND) + renderConstructorKeyword = false secondaryConstructorsAsPrimary = false renderDefaultVisibility = false renderDefaultModality = false - renderConstructorDelegation = true renderAnnotationPropertiesInPrimaryConstructor = true + renderTypeExpansions = true } private val ACTUAL_RENDERER = EXPECT_RENDERER.withOptions { + modifiers += ACTUAL actualPropertiesInPrimaryConstructor = true + renderTypeExpansions = false + renderConstructorDelegation = true } private fun PropertyDescriptor.wrap(forceOverride: Boolean): PropertyDescriptor { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateActualFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateActualFix.kt index 505c5f77447..08bf5e9fb02 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateActualFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateActualFix.kt @@ -282,7 +282,7 @@ private fun generateFunction( return if (targetClass != null) { memberChooserObject.generateActualMember(targetClass = targetClass, copyDoc = true) } else { - memberChooserObject.generateTopLevelActual(copyDoc = true, project = project) + memberChooserObject.generateTopLevelActual(project = project, copyDoc = true) } as KtFunction } @@ -299,7 +299,7 @@ private fun generateProperty( return if (targetClass != null) { memberChooserObject.generateActualMember(targetClass = targetClass, copyDoc = true) } else { - memberChooserObject.generateTopLevelActual(copyDoc = true, project = project) + memberChooserObject.generateTopLevelActual(project = project, copyDoc = true) } as KtProperty } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateExpectedFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateExpectedFix.kt index 1b8d5476002..dc6a16fdfa4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateExpectedFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/CreateExpectedFix.kt @@ -188,6 +188,7 @@ private fun KtPsiFactory.generateClassOrObjectByActualClass( } else { expectedClass.makeNotActual() } + expectedClass.removeModifier(KtTokens.DATA_KEYWORD) declLoop@ for (actualDeclaration in actualClass.declarations) { val descriptor = actualDeclaration.toDescriptor() ?: continue @@ -199,6 +200,7 @@ private fun KtPsiFactory.generateClassOrObjectByActualClass( continue@declLoop } is KtCallableDeclaration -> { + if (!actualDeclaration.hasActualModifier()) continue@declLoop when (actualDeclaration) { is KtFunction -> generateFunction(project, actualDeclaration, descriptor as FunctionDescriptor, expectedClass) is KtProperty -> generateProperty(project, actualDeclaration, descriptor as PropertyDescriptor, expectedClass) @@ -209,6 +211,14 @@ private fun KtPsiFactory.generateClassOrObjectByActualClass( } expectedClass.addDeclaration(expectedDeclaration) } + if (!actualClass.isAnnotation()) { + for (actualProperty in actualClass.primaryConstructorParameters) { + if (!actualProperty.hasValOrVar() || !actualProperty.hasActualModifier()) continue + val descriptor = actualProperty.toDescriptor() as? PropertyDescriptor ?: continue + val expectedProperty = generateProperty(project, actualProperty, descriptor, expectedClass) + expectedClass.addDeclaration(expectedProperty) + } + } val actualPrimaryConstructor = actualClass.primaryConstructor if (expectedClass is KtClass && actualPrimaryConstructor != null) { val descriptor = actualPrimaryConstructor.toDescriptor() @@ -234,7 +244,7 @@ private fun generateFunction( return if (targetClass != null) { memberChooserObject.generateExpectMember(targetClass = targetClass, copyDoc = true) } else { - memberChooserObject.generateTopLevelExpect(copyDoc = true, project = project) + memberChooserObject.generateTopLevelExpect(project = project, copyDoc = true) } as KtFunction } @@ -251,7 +261,7 @@ private fun generateProperty( return if (targetClass != null) { memberChooserObject.generateExpectMember(targetClass = targetClass, copyDoc = true) } else { - memberChooserObject.generateTopLevelExpect(copyDoc = true, project = project) + memberChooserObject.generateTopLevelExpect(project = project, copyDoc = true) } as KtProperty } diff --git a/idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt b/idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt new file mode 100644 index 00000000000..e8182b18100 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt @@ -0,0 +1,2 @@ +// My: to be implemented +// DISABLE-ERRORS \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt.after b/idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt.after new file mode 100644 index 00000000000..c4c3a4b8c7b --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectClassCommented/header/My.kt.after @@ -0,0 +1,24 @@ +// My: to be implemented +// DISABLE-ERRORS +/** + * Dokka comment: class to be created as expect + */ +expect class My { + fun foo(param: String): Int + fun String.bar(y: Double): Boolean + /** + * Dokka comment: Just does nothing + */ + fun baz() + + /** + * Dokka comment: Just does nothing + * + * @flag this parameter is just ignored + */ + constructor(flag: Boolean) + + val isGood: Boolean + var status: Int + +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt b/idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt new file mode 100644 index 00000000000..6e5ef1560f2 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt @@ -0,0 +1,35 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +/** + * Dokka comment: class to be created as expect + */ +actual class My { + // Helpful function + actual fun foo(param: String): Int = 42 + + /* Very helpful extension */ + actual fun String.bar(y: Double): Boolean = true + + /** + * Dokka comment: Just does nothing + */ + actual fun baz() {} + + /** + * Dokka comment: Just does nothing + * + * @flag this parameter is just ignored + */ + actual constructor(flag: Boolean) {} + + // Some immutable property + actual val isGood: Boolean + get() = true + + /* Interesting mutable property */ + actual var status: Int + get() = 0 + set(value) {} + +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt.after b/idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt.after new file mode 100644 index 00000000000..6e5ef1560f2 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectClassCommented/jvm/My.kt.after @@ -0,0 +1,35 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +/** + * Dokka comment: class to be created as expect + */ +actual class My { + // Helpful function + actual fun foo(param: String): Int = 42 + + /* Very helpful extension */ + actual fun String.bar(y: Double): Boolean = true + + /** + * Dokka comment: Just does nothing + */ + actual fun baz() {} + + /** + * Dokka comment: Just does nothing + * + * @flag this parameter is just ignored + */ + actual constructor(flag: Boolean) {} + + // Some immutable property + actual val isGood: Boolean + get() = true + + /* Interesting mutable property */ + actual var status: Int + get() = 0 + set(value) {} + +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectClassPropertyInConstructor/jvm/My.kt.after b/idea/testData/multiModuleQuickFix/expectClassPropertyInConstructor/jvm/My.kt.after index 144c5eba8b3..425d90cd226 100644 --- a/idea/testData/multiModuleQuickFix/expectClassPropertyInConstructor/jvm/My.kt.after +++ b/idea/testData/multiModuleQuickFix/expectClassPropertyInConstructor/jvm/My.kt.after @@ -1,4 +1,4 @@ // "Create expected property in common module testModule_Common" "true" // DISABLE-ERRORS -actual class My(actual val s: String) \ No newline at end of file +actual class My(actual val s: String) \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectClassWithAliases/common/My.kt.after b/idea/testData/multiModuleQuickFix/expectClassWithAliases/common/My.kt.after new file mode 100644 index 00000000000..cc4210384da --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectClassWithAliases/common/My.kt.after @@ -0,0 +1,5 @@ +expect class My { + fun foo(): Int + val some: Double + +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt b/idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt new file mode 100644 index 00000000000..de902b2e2f5 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt @@ -0,0 +1,12 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +import kotlin.Double as MyDouble + +typealias MyInt = Int + +actual class My { + actual fun foo(): MyInt = 42 + + actual val some: MyDouble = 4.0 +} diff --git a/idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt.after b/idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt.after new file mode 100644 index 00000000000..de902b2e2f5 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectClassWithAliases/jvm/My.kt.after @@ -0,0 +1,12 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +import kotlin.Double as MyDouble + +typealias MyInt = Int + +actual class My { + actual fun foo(): MyInt = 42 + + actual val some: MyDouble = 4.0 +} diff --git a/idea/testData/multiModuleQuickFix/expectDataClass/common/My.kt.after b/idea/testData/multiModuleQuickFix/expectDataClass/common/My.kt.after new file mode 100644 index 00000000000..e1b59ff9dec --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectDataClass/common/My.kt.after @@ -0,0 +1,4 @@ +expect class My(x: Int, y: Int) { + val x: Int + val y: Int +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt b/idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt new file mode 100644 index 00000000000..a45058754a3 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt @@ -0,0 +1,4 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +actual data class My actual constructor(actual val x: Int, actual val y: Int) \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt.after b/idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt.after new file mode 100644 index 00000000000..60cdf66cf8b --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectDataClass/jvm/My.kt.after @@ -0,0 +1,4 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +actual data class My actual constructor(actual val x: Int, actual val y: Int) \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectEnum/header/My.kt.after b/idea/testData/multiModuleQuickFix/expectEnum/header/My.kt.after index ded555abea5..d301b9d4571 100644 --- a/idea/testData/multiModuleQuickFix/expectEnum/header/My.kt.after +++ b/idea/testData/multiModuleQuickFix/expectEnum/header/My.kt.after @@ -5,6 +5,4 @@ expect enum class My { SECOND, LAST; - val num: Int - } \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt b/idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt new file mode 100644 index 00000000000..e8182b18100 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt @@ -0,0 +1,2 @@ +// My: to be implemented +// DISABLE-ERRORS \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt.after b/idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt.after new file mode 100644 index 00000000000..417adacea32 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectEnumEmpty/header/My.kt.after @@ -0,0 +1,8 @@ +// My: to be implemented +// DISABLE-ERRORS +expect enum class My { + ; + + fun getHello(): String + +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt b/idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt new file mode 100644 index 00000000000..6f53589bbc9 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt @@ -0,0 +1,8 @@ +// "Create expected enum class in common module testModule_Common" "true" +// DISABLE-ERRORS + +actual enum class My { + ; + + actual fun getHello() = "Hello" +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt.after b/idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt.after new file mode 100644 index 00000000000..2d509859581 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectEnumEmpty/jvm/My.kt.after @@ -0,0 +1,8 @@ +// "Create expected enum class in common module testModule_Common" "true" +// DISABLE-ERRORS + +actual enum class My { + ; + + actual fun getHello() = "Hello" +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_common/createList.kt.after b/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_common/createList.kt.after new file mode 100644 index 00000000000..ba550298337 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_common/createList.kt.after @@ -0,0 +1 @@ +expect fun createList(): java.util.ArrayList \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt b/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt new file mode 100644 index 00000000000..ff1bf65c291 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt @@ -0,0 +1,6 @@ +// "Create expected function in common module proj_Common" "true" +// DISABLE-ERRORS + +import java.util.ArrayList + +actual fun createList(): ArrayList = ArrayList() \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt.after b/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt.after new file mode 100644 index 00000000000..bec2d9aafc8 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectFunWithJdk/proj_jvm_dep(fulljdk)/Utils.kt.after @@ -0,0 +1,6 @@ +// "Create expected function in common module proj_Common" "true" +// DISABLE-ERRORS + +import java.util.ArrayList + +actual fun createList(): ArrayList = ArrayList() \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectNestedClass/common/My.kt.after b/idea/testData/multiModuleQuickFix/expectNestedClass/common/My.kt.after index 588edd3b9bf..3d25ba65237 100644 --- a/idea/testData/multiModuleQuickFix/expectNestedClass/common/My.kt.after +++ b/idea/testData/multiModuleQuickFix/expectNestedClass/common/My.kt.after @@ -7,7 +7,10 @@ expect class My { class OtherNested(d: Double) { val dd: Double + var d: Double } + val s: String + } } \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt b/idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt new file mode 100644 index 00000000000..e8182b18100 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt @@ -0,0 +1,2 @@ +// My: to be implemented +// DISABLE-ERRORS \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt.after b/idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt.after new file mode 100644 index 00000000000..69ac0d8cd52 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectSealedClass/header/My.kt.after @@ -0,0 +1,21 @@ +// My: to be implemented +// DISABLE-ERRORS +expect sealed class My private constructor(x: Double) { + abstract val num: Int + open fun isGood(): Boolean + + object First : My { + override val num: Int + } + class Some(num: Int) : My { + override val num: Int + } + object Best : My { + override val num: Int + override fun isGood(): Boolean + + } + + val x: Double + +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt b/idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt new file mode 100644 index 00000000000..d7baac7e8bf --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt @@ -0,0 +1,21 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +actual sealed class My actual constructor(actual val x: Double) { + + actual abstract val num: Int + + actual open fun isGood() = false + + actual object First : My(1.0) { + actual override val num = 0 + } + + actual class Some actual constructor(actual override val num: Int) : My(num.toDouble()) + + actual object Best : My(999.0) { + actual override val num = 42 + + actual override fun isGood() = true + } +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt.after b/idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt.after new file mode 100644 index 00000000000..1d56847f17c --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectSealedClass/jvm/My.kt.after @@ -0,0 +1,21 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +actual sealed class My actual constructor(actual val x: Double) { + + actual abstract val num: Int + + actual open fun isGood() = false + + actual object First : My(1.0) { + actual override val num = 0 + } + + actual class Some actual constructor(actual override val num: Int) : My(num.toDouble()) + + actual object Best : My(999.0) { + actual override val num = 42 + + actual override fun isGood() = true + } +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectTypeAlias/common/My.kt b/idea/testData/multiModuleQuickFix/expectTypeAlias/common/My.kt new file mode 100644 index 00000000000..519c3cc8dac --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectTypeAlias/common/My.kt @@ -0,0 +1 @@ +// Not to be implemented \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectTypeAlias/jvm/My.kt b/idea/testData/multiModuleQuickFix/expectTypeAlias/jvm/My.kt new file mode 100644 index 00000000000..ea160c2477b --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectTypeAlias/jvm/My.kt @@ -0,0 +1,9 @@ +// "Create expected class in common module testModule_Common" "false" +// DISABLE-ERRORS +// ACTION: Remove 'actual' modifier + +class Some(val x: Int, val y: Int) { + fun processIt(z: Int) = x + y - z +} + +actual typealias My = Some \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt b/idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt new file mode 100644 index 00000000000..a3c3081792d --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt @@ -0,0 +1,4 @@ +// My: to be implemented +// DISABLE-ERRORS + +annotation class CommonAnnotation \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt.after b/idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt.after new file mode 100644 index 00000000000..bb4e4dce57a --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectWithAnnotations/header/My.kt.after @@ -0,0 +1,10 @@ +// My: to be implemented +// DISABLE-ERRORS + +annotation class CommonAnnotation +expect class My { + tailrec fun foo(arg: Int): Int + var some: Boolean + fun initialize() + +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt b/idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt new file mode 100644 index 00000000000..7b8cc8e5936 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt @@ -0,0 +1,20 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +annotation class PlatformAnnotation + +actual class My { + @PlatformAnnotation + actual tailrec fun foo(arg: Int): Int { + if (arg <= 1) return 1 + return foo(arg - 1) + } + + // Here we will have an error (lateinit is not supported on both sides) + actual lateinit var some: Boolean + + @CommonAnnotation + actual fun initialize() { + some = true + } +} \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt.after b/idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt.after new file mode 100644 index 00000000000..7b8cc8e5936 --- /dev/null +++ b/idea/testData/multiModuleQuickFix/expectWithAnnotations/jvm/My.kt.after @@ -0,0 +1,20 @@ +// "Create expected class in common module testModule_Common" "true" +// DISABLE-ERRORS + +annotation class PlatformAnnotation + +actual class My { + @PlatformAnnotation + actual tailrec fun foo(arg: Int): Int { + if (arg <= 1) return 1 + return foo(arg - 1) + } + + // Here we will have an error (lateinit is not supported on both sides) + actual lateinit var some: Boolean + + @CommonAnnotation + actual fun initialize() { + some = true + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java index ea77f6eeaa7..3180b735e42 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java @@ -264,6 +264,11 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul runTest("idea/testData/multiModuleQuickFix/expectClass/"); } + @TestMetadata("expectClassCommented") + public void testExpectClassCommented() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectClassCommented/"); + } + @TestMetadata("expectClassFunction") public void testExpectClassFunction() throws Exception { runTest("idea/testData/multiModuleQuickFix/expectClassFunction/"); @@ -279,16 +284,36 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul runTest("idea/testData/multiModuleQuickFix/expectClassPropertyInConstructor/"); } + @TestMetadata("expectClassWithAliases") + public void testExpectClassWithAliases() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectClassWithAliases/"); + } + @TestMetadata("expectClassWithSupertype") public void testExpectClassWithSupertype() throws Exception { runTest("idea/testData/multiModuleQuickFix/expectClassWithSupertype/"); } + @TestMetadata("expectDataClass") + public void testExpectDataClass() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectDataClass/"); + } + @TestMetadata("expectEnum") public void testExpectEnum() throws Exception { runTest("idea/testData/multiModuleQuickFix/expectEnum/"); } + @TestMetadata("expectEnumEmpty") + public void testExpectEnumEmpty() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectEnumEmpty/"); + } + + @TestMetadata("expectFunWithJdk") + public void testExpectFunWithJdk() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectFunWithJdk/"); + } + @TestMetadata("expectFunction") public void testExpectFunction() throws Exception { runTest("idea/testData/multiModuleQuickFix/expectFunction/"); @@ -304,6 +329,21 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul runTest("idea/testData/multiModuleQuickFix/expectProperty/"); } + @TestMetadata("expectSealedClass") + public void testExpectSealedClass() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectSealedClass/"); + } + + @TestMetadata("expectTypeAlias") + public void testExpectTypeAlias() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectTypeAlias/"); + } + + @TestMetadata("expectWithAnnotations") + public void testExpectWithAnnotations() throws Exception { + runTest("idea/testData/multiModuleQuickFix/expectWithAnnotations/"); + } + @TestMetadata("function") public void testFunction() throws Exception { runTest("idea/testData/multiModuleQuickFix/function/");