Enum implementing exported interface
[JS IR] Not export get instance enum function [JS IR] Enum corresponding class is not considered in export [JS IR] All enums are abstract and with private constructor [JS IR] Any methods is left in d.ts [JS IR] Make enum with declarations inside corresponding class [JS IR] Export of interface through fake override [JS IR] Include enum entry corresponding class members into export model Merge-request: KT-MR-5031 ^KT-49779 fixed ^KT-49773 fixed
This commit is contained in:
@@ -405,7 +405,7 @@ fun usefulDeclarations(
|
||||
// https://youtrack.jetbrains.com/issue/KT-46672
|
||||
// TODO: Possibly solution with origin is not so good
|
||||
// There is option with applying this hack to jsGetKClass
|
||||
if (expression.origin == JsLoweredDeclarationOrigin.CLASS_REFERENCE) {
|
||||
if (expression.origin == JsStatementOrigins.CLASS_REFERENCE) {
|
||||
// Maybe we need to filter primary constructor
|
||||
// Although at this time, we should have only primary constructor
|
||||
(ref as IrClass)
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
|
||||
|
||||
object JsLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object JS_INTRINSICS_STUB : IrDeclarationOriginImpl("JS_INTRINSICS_STUB")
|
||||
@@ -16,5 +15,5 @@ object JsLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object BRIDGE_WITHOUT_STABLE_NAME : IrDeclarationOriginImpl("BRIDGE_WITHOUT_STABLE_NAME")
|
||||
object OBJECT_GET_INSTANCE_FUNCTION : IrDeclarationOriginImpl("OBJECT_GET_INSTANCE_FUNCTION")
|
||||
object JS_SHADOWED_EXPORT : IrDeclarationOriginImpl("JS_SHADOWED_EXPORT")
|
||||
object CLASS_REFERENCE : IrStatementOriginImpl("CLASS_REFERENCE")
|
||||
object ENUM_GET_INSTANCE_FUNCTION : IrDeclarationOriginImpl("ENUM_GET_INSTANCE_FUNCTION")
|
||||
}
|
||||
|
||||
+10
-1
@@ -37,8 +37,11 @@ data class ExportedFunction(
|
||||
|
||||
data class ExportedConstructor(
|
||||
val parameters: List<ExportedParameter>,
|
||||
val visibility: ExportedVisibility
|
||||
) : ExportedDeclaration() {
|
||||
val isProtected: Boolean
|
||||
) : ExportedDeclaration()
|
||||
get() = visibility == ExportedVisibility.PROTECTED
|
||||
}
|
||||
|
||||
data class ExportedConstructSignature(
|
||||
val parameters: List<ExportedParameter>,
|
||||
@@ -131,3 +134,9 @@ sealed class ExportedType {
|
||||
fun withImplicitlyExported(implicitlyExportedType: Boolean) =
|
||||
if (implicitlyExportedType) ImplicitlyExportedType(this) else this
|
||||
}
|
||||
|
||||
enum class ExportedVisibility(val keyword: String) {
|
||||
DEFAULT(""),
|
||||
PRIVATE("private "),
|
||||
PROTECTED("protected ")
|
||||
}
|
||||
|
||||
+38
-14
@@ -10,12 +10,14 @@ import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.ES6AddInternalParametersToConstructorPhase.ES6_INIT_BOX_PARAMETER
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.ES6AddInternalParametersToConstructorPhase.ES6_RESULT_TYPE_PARAMETER
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isExportedInterface
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isJsExport
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -71,8 +73,12 @@ class ExportModelGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun exportFunction(function: IrSimpleFunction): ExportedDeclaration? =
|
||||
when (val exportability = functionExportability(function)) {
|
||||
private fun exportFunction(function: IrSimpleFunction): ExportedDeclaration? {
|
||||
if (function.origin == JsLoweredDeclarationOrigin.ENUM_GET_INSTANCE_FUNCTION) {
|
||||
return null
|
||||
}
|
||||
|
||||
return when (val exportability = functionExportability(function)) {
|
||||
is Exportability.NotNeeded -> null
|
||||
is Exportability.Prohibited -> ErrorDeclaration(exportability.reason)
|
||||
is Exportability.Allowed -> {
|
||||
@@ -90,6 +96,7 @@ class ExportModelGenerator(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun exportConstructor(constructor: IrConstructor): ExportedDeclaration? {
|
||||
if (!constructor.isPrimary) return null
|
||||
@@ -97,7 +104,7 @@ class ExportModelGenerator(
|
||||
constructor.valueParameters.filterNot { it.origin === ES6_RESULT_TYPE_PARAMETER || it.origin === ES6_INIT_BOX_PARAMETER }
|
||||
return ExportedConstructor(
|
||||
parameters = allValueParameters.map { exportParameter(it) },
|
||||
isProtected = constructor.visibility == DescriptorVisibilities.PROTECTED
|
||||
visibility = constructor.visibility.toExportedVisibility()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -115,7 +122,7 @@ class ExportModelGenerator(
|
||||
// TODO: Report a frontend error
|
||||
if (accessor.extensionReceiverParameter != null)
|
||||
return null
|
||||
if (accessor.isFakeOverride && !accessor.isEnumFakeOverriddenDeclaration(context)) {
|
||||
if (accessor.isFakeOverride && !accessor.isAllowedFakeOverriddenDeclaration(context)) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -254,11 +261,20 @@ class ExportModelGenerator(
|
||||
enumExportedMember
|
||||
}
|
||||
|
||||
val privateConstructor = ExportedConstructor(
|
||||
parameters = emptyList(),
|
||||
visibility = ExportedVisibility.PRIVATE
|
||||
)
|
||||
|
||||
return exportClass(
|
||||
klass,
|
||||
members,
|
||||
listOf(privateConstructor) + members,
|
||||
nestedClasses
|
||||
)
|
||||
).let {
|
||||
(it as ExportedClass).copy(
|
||||
isAbstract = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun exportClassDeclarations(
|
||||
@@ -382,7 +398,7 @@ class ExportModelGenerator(
|
||||
val enumEntries = enumEntriesToOrdinal.keys
|
||||
return when (candidate) {
|
||||
is IrProperty -> {
|
||||
if (candidate.isEnumFakeOverriddenDeclaration(context)) {
|
||||
if (candidate.isAllowedFakeOverriddenDeclaration(context)) {
|
||||
val type: ExportedType? = when (candidate.getExportedIdentifier()) {
|
||||
"name" -> enumEntries
|
||||
.map { it.getExportedIdentifier() }
|
||||
@@ -507,7 +523,7 @@ class ExportModelGenerator(
|
||||
return Exportability.Prohibited("Inline reified function")
|
||||
if (function.isSuspend)
|
||||
return Exportability.Prohibited("Suspend function")
|
||||
if (function.isFakeOverride)
|
||||
if (function.isFakeOverride && !function.isAllowedFakeOverriddenDeclaration(context))
|
||||
return Exportability.NotNeeded
|
||||
if (function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME ||
|
||||
function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME ||
|
||||
@@ -524,9 +540,6 @@ class ExportModelGenerator(
|
||||
return Exportability.NotNeeded
|
||||
}
|
||||
|
||||
if (function.isFakeOverriddenFromAny())
|
||||
return Exportability.NotNeeded
|
||||
|
||||
val nameString = function.name.asString()
|
||||
if (nameString.endsWith("-impl"))
|
||||
return Exportability.NotNeeded
|
||||
@@ -605,7 +618,7 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
||||
if (overriddenNonEmpty) {
|
||||
return declaration.isOverriddenExported(context) ||
|
||||
(declaration as? IrSimpleFunction)?.isMethodOfAny() == true // Handle names for special functions
|
||||
|| declaration.isEnumFakeOverriddenDeclaration(context)
|
||||
|| declaration.isAllowedFakeOverriddenDeclaration(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,12 +632,17 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
||||
}
|
||||
}
|
||||
|
||||
fun IrOverridableDeclaration<*>.isEnumFakeOverriddenDeclaration(context: JsIrBackendContext?): Boolean {
|
||||
fun IrOverridableDeclaration<*>.isAllowedFakeOverriddenDeclaration(context: JsIrBackendContext?): Boolean {
|
||||
if (this.resolveFakeOverride(allowAbstract = true)?.parentClassOrNull.isExportedInterface()) {
|
||||
return true
|
||||
}
|
||||
|
||||
return context?.irBuiltIns?.enumClass?.let { enumClass ->
|
||||
overriddenSymbols
|
||||
.asSequence()
|
||||
.map { it.owner }
|
||||
.filterIsInstance<IrDeclaration>()
|
||||
.filterIsInstance<IrOverridableDeclaration<*>>()
|
||||
.filter { it.overriddenSymbols.isEmpty() }
|
||||
.mapNotNull { it.parentClassOrNull }
|
||||
.map { it.symbol }
|
||||
.any { it == enumClass }
|
||||
@@ -640,6 +658,12 @@ fun IrDeclaration.isExported(context: JsIrBackendContext?): Boolean {
|
||||
return shouldDeclarationBeExported(candidate, context)
|
||||
}
|
||||
|
||||
private fun DescriptorVisibility.toExportedVisibility() =
|
||||
when (this) {
|
||||
DescriptorVisibilities.PROTECTED -> ExportedVisibility.PROTECTED
|
||||
else -> ExportedVisibility.DEFAULT
|
||||
}
|
||||
|
||||
private val reservedWords = setOf(
|
||||
"break",
|
||||
"case",
|
||||
|
||||
+2
-3
@@ -93,9 +93,8 @@ fun ExportedDeclaration.toTypeScript(indent: String, prefix: String = ""): Strin
|
||||
}
|
||||
|
||||
is ExportedConstructor -> {
|
||||
val visibility = if (isProtected) "protected " else ""
|
||||
val renderedParameters = parameters.joinToString(", ") { it.toTypeScript(indent) }
|
||||
"${visibility}constructor($renderedParameters);"
|
||||
"${visibility.keyword}constructor($renderedParameters);"
|
||||
}
|
||||
|
||||
is ExportedConstructSignature -> {
|
||||
@@ -220,7 +219,7 @@ fun ExportedClass.withProtectedConstructors(): ExportedClass {
|
||||
if (it !is ExportedConstructor || it.isProtected) {
|
||||
it
|
||||
} else {
|
||||
it.copy(isProtected = true)
|
||||
it.copy(visibility = ExportedVisibility.PROTECTED)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
JsIrBuilder.buildCall(
|
||||
reflectionSymbols.getClassData,
|
||||
typeArguments = listOf(type),
|
||||
origin = JsLoweredDeclarationOrigin.CLASS_REFERENCE
|
||||
origin = JsStatementOrigins.CLASS_REFERENCE
|
||||
)
|
||||
|
||||
private fun buildCall(name: IrSimpleFunctionSymbol, vararg args: IrExpression): IrExpression =
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PRIVATE
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
@@ -445,7 +446,7 @@ class EnumEntryCreateGetInstancesFunsLowering(val context: JsCommonBackendContex
|
||||
context.irFactory.buildFun {
|
||||
name = Name.identifier(createEntryAccessorName(irClass.name.identifier, enumEntry))
|
||||
returnType = enumEntry.getType(irClass)
|
||||
origin = JsIrBuilder.SYNTHESIZED_DECLARATION
|
||||
origin = JsLoweredDeclarationOrigin.ENUM_GET_INSTANCE_FUNCTION
|
||||
}.apply {
|
||||
parent = irClass
|
||||
}
|
||||
|
||||
+7
-5
@@ -6,9 +6,8 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isEnumFakeOverriddenDeclaration
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isAllowedFakeOverriddenDeclaration
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isOverriddenExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
@@ -102,7 +101,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
|
||||
classBlock.statements += generateClassMetadata()
|
||||
|
||||
if (!irClass.isInterface && !irClass.isEnumEntry) {
|
||||
if (!irClass.isInterface) {
|
||||
for (property in properties) {
|
||||
if (property.getter?.extensionReceiverParameter != null || property.setter?.extensionReceiverParameter != null)
|
||||
continue
|
||||
@@ -110,7 +109,10 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
if (!property.visibility.isPublicAPI)
|
||||
continue
|
||||
|
||||
if (property.isFakeOverride && !property.isEnumFakeOverriddenDeclaration(context.staticContext.backendContext))
|
||||
if (
|
||||
property.isFakeOverride &&
|
||||
!property.isAllowedFakeOverriddenDeclaration(context.staticContext.backendContext)
|
||||
)
|
||||
continue
|
||||
|
||||
fun IrSimpleFunction.propertyAccessorForwarder(
|
||||
@@ -145,7 +147,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
val noOverriddenExportedSetter = property.setter?.isOverriddenExported(context.staticContext.backendContext) == false
|
||||
|
||||
val needsOverride = (overriddenExportedGetter && noOverriddenExportedSetter) ||
|
||||
property.isEnumFakeOverriddenDeclaration(context.staticContext.backendContext)
|
||||
property.isAllowedFakeOverriddenDeclaration(context.staticContext.backendContext)
|
||||
|
||||
if (irClass.isExported(context.staticContext.backendContext) &&
|
||||
(overriddenSymbols.isEmpty() || needsOverride) ||
|
||||
|
||||
+1
@@ -18,4 +18,5 @@ interface JsStatementOrigins {
|
||||
object FACTORY_ORIGIN : IrDeclarationOriginImpl("FACTORY_ORIGIN")
|
||||
object COROUTINE_ROOT_LOOP : IrStatementOriginImpl("COROUTINE_ROOT_LOOP")
|
||||
object COROUTINE_SWITCH : IrStatementOriginImpl("COROUTINE_SWITCH")
|
||||
object CLASS_REFERENCE : IrStatementOriginImpl("CLASS_REFERENCE")
|
||||
}
|
||||
Reference in New Issue
Block a user