From 5000fe8133c48cb75d281805bee523932211a852 Mon Sep 17 00:00:00 2001 From: Sergey Mashkov Date: Mon, 15 Jun 2015 20:15:17 +0300 Subject: [PATCH] IDL2K Multiple constructors (via secondary constructors when needed) --- .../src/generated/org.khronos.webgl.kt | 54 +++++++++-- js/js.libraries/src/generated/org.w3c.dom.kt | 27 ++++-- .../src/generated/org.w3c.files.kt | 3 +- libraries/tools/idl2k/src/main/kotlin/gen.kt | 97 ++++++++++++------- .../tools/idl2k/src/main/kotlin/model.kt | 19 ++-- .../tools/idl2k/src/main/kotlin/render.kt | 37 +++++-- .../idl2k/src/main/kotlin/typeMappings.kt | 7 +- 7 files changed, 171 insertions(+), 73 deletions(-) diff --git a/js/js.libraries/src/generated/org.khronos.webgl.kt b/js/js.libraries/src/generated/org.khronos.webgl.kt index f1d3e7315e1..a6d80b15473 100644 --- a/js/js.libraries/src/generated/org.khronos.webgl.kt +++ b/js/js.libraries/src/generated/org.khronos.webgl.kt @@ -562,7 +562,11 @@ native public open class ArrayBuffer(length: Int) : Transferable { fun slice(begin: Int, end: Int = noImpl): ArrayBuffer = noImpl } -native public open class Int8Array(length: Int) : ArrayBufferView { +native public open class Int8Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Int8Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -586,7 +590,11 @@ native public open class Int8Array(length: Int) : ArrayBufferView { } } -native public open class Uint8Array(length: Int) : ArrayBufferView { +native public open class Uint8Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Uint8Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -610,7 +618,11 @@ native public open class Uint8Array(length: Int) : ArrayBufferView { } } -native public open class Uint8ClampedArray(length: Int) : ArrayBufferView { +native public open class Uint8ClampedArray : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Uint8ClampedArray) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -634,7 +646,11 @@ native public open class Uint8ClampedArray(length: Int) : ArrayBufferView { } } -native public open class Int16Array(length: Int) : ArrayBufferView { +native public open class Int16Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Int16Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -658,7 +674,11 @@ native public open class Int16Array(length: Int) : ArrayBufferView { } } -native public open class Uint16Array(length: Int) : ArrayBufferView { +native public open class Uint16Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Uint16Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -682,7 +702,11 @@ native public open class Uint16Array(length: Int) : ArrayBufferView { } } -native public open class Int32Array(length: Int) : ArrayBufferView { +native public open class Int32Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Int32Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -706,7 +730,11 @@ native public open class Int32Array(length: Int) : ArrayBufferView { } } -native public open class Uint32Array(length: Int) : ArrayBufferView { +native public open class Uint32Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Uint32Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -730,7 +758,11 @@ native public open class Uint32Array(length: Int) : ArrayBufferView { } } -native public open class Float32Array(length: Int) : ArrayBufferView { +native public open class Float32Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Float32Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl @@ -754,7 +786,11 @@ native public open class Float32Array(length: Int) : ArrayBufferView { } } -native public open class Float64Array(length: Int) : ArrayBufferView { +native public open class Float64Array : ArrayBufferView { + constructor(length: Int) : super() + constructor(array: Float64Array) : super() + constructor(array: Array) : super() + constructor(buffer: ArrayBuffer, byteOffset: Int = noImpl, length: Int = noImpl) : super() var length: Int get() = noImpl set(value) = noImpl diff --git a/js/js.libraries/src/generated/org.w3c.dom.kt b/js/js.libraries/src/generated/org.w3c.dom.kt index a5dbd0c823a..d7d00ca7a7a 100644 --- a/js/js.libraries/src/generated/org.w3c.dom.kt +++ b/js/js.libraries/src/generated/org.w3c.dom.kt @@ -2810,7 +2810,8 @@ native public open class CanvasRenderingContext2DSettings { var alpha: Boolean = true } -native public open class CanvasRenderingContext2D : RenderingContext, CanvasImageSource, ImageBitmapSource { +native public open class CanvasRenderingContext2D() : RenderingContext, CanvasImageSource, ImageBitmapSource { + constructor(width: Int, height: Int) : this() var canvas: HTMLCanvasElement get() = noImpl set(value) = noImpl @@ -2994,7 +2995,9 @@ native public open class HitRegionOptions { var role: String? = null } -native public open class ImageData(sw: Int, sh: Int) : ImageBitmapSource { +native public open class ImageData : ImageBitmapSource { + constructor(sw: Int, sh: Int) : super() + constructor(data: Uint8ClampedArray, sw: Int, sh: Int = noImpl) : super() var width: Int get() = noImpl set(value) = noImpl @@ -3038,7 +3041,10 @@ native public open class DrawingStyle(scope: Element = noImpl) { fun getLineDash(): Array = noImpl } -native public open class Path2D { +native public open class Path2D() { + constructor(path: Path2D) : this() + constructor(paths: Array, fillRule: String = "nonzero") : this() + constructor(d: String) : this() fun addPath(path: Path2D, transformation: SVGMatrix? = null): Unit = noImpl fun addPathByStrokingPath(path: Path2D, styles: dynamic, transformation: SVGMatrix? = null): Unit = noImpl fun addText(text: String, styles: dynamic, transformation: SVGMatrix?, x: Double, y: Double, maxWidth: Double = noImpl): Unit = noImpl @@ -5030,7 +5036,9 @@ native public open class DOMPointReadOnly(x: Double, y: Double, z: Double, w: Do fun matrixTransform(matrix: DOMMatrixReadOnly): DOMPoint = noImpl } -native public open class DOMPoint(point: DOMPointInit = noImpl) : DOMPointReadOnly(noImpl, noImpl, noImpl, noImpl) { +native public open class DOMPoint : DOMPointReadOnly { + constructor(point: DOMPointInit = noImpl) : super(noImpl, noImpl, noImpl, noImpl) + constructor(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0, w: Double = 1.0) : super(x, y, z, w) } native public open class DOMPointInit { @@ -5077,7 +5085,9 @@ native public open class DOMRectInit { var height: Double = 0.0 } -native public open class DOMQuad(p1: DOMPointInit = noImpl, p2: DOMPointInit = noImpl, p3: DOMPointInit = noImpl, p4: DOMPointInit = noImpl) { +native public open class DOMQuad { + constructor(p1: DOMPointInit = noImpl, p2: DOMPointInit = noImpl, p3: DOMPointInit = noImpl, p4: DOMPointInit = noImpl) : super() + constructor(rect: DOMRectInit = noImpl) : super() var p1: DOMPoint get() = noImpl set(value) = noImpl @@ -5186,7 +5196,12 @@ native public open class DOMMatrixReadOnly(numberSequence: Array) { fun toFloat64Array(): Float64Array = noImpl } -native public open class DOMMatrix : DOMMatrixReadOnly(noImpl) { +native public open class DOMMatrix() : DOMMatrixReadOnly(noImpl) { + constructor(transformList: String) : this() + constructor(other: DOMMatrixReadOnly) : this() + constructor(array32: Float32Array) : this() + constructor(array64: Float64Array) : this() + constructor(numberSequence: Array) : this() fun multiplySelf(other: DOMMatrix): DOMMatrix = noImpl fun preMultiplySelf(other: DOMMatrix): DOMMatrix = noImpl fun translateSelf(tx: Double, ty: Double, tz: Double = 0.0): DOMMatrix = noImpl diff --git a/js/js.libraries/src/generated/org.w3c.files.kt b/js/js.libraries/src/generated/org.w3c.files.kt index 8516ed9363f..26002075743 100644 --- a/js/js.libraries/src/generated/org.w3c.files.kt +++ b/js/js.libraries/src/generated/org.w3c.files.kt @@ -20,7 +20,8 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -native public open class Blob : ImageBitmapSource { +native public open class Blob() : ImageBitmapSource { + constructor(blobParts: Array, options: BlobPropertyBag = noImpl) : this() var size: Long get() = noImpl set(value) = noImpl diff --git a/libraries/tools/idl2k/src/main/kotlin/gen.kt b/libraries/tools/idl2k/src/main/kotlin/gen.kt index c49fb619af3..267c052c507 100644 --- a/libraries/tools/idl2k/src/main/kotlin/gen.kt +++ b/libraries/tools/idl2k/src/main/kotlin/gen.kt @@ -26,7 +26,7 @@ fun String.dropNullable() = when { else -> this } -fun String.copyNullabilityFrom(type : String) = when { +fun String.copyNullabilityFrom(type: String) = when { type.isNullable() -> ensureNullable() else -> this } @@ -94,54 +94,85 @@ fun generateAttribute(putNoImpl: Boolean, repository: Repository, attribute: Att ) private fun InterfaceDefinition.superTypes(repository: Repository) = superTypes.map { repository.interfaces[it] }.filterNotNull() -private fun resolveDefinitionKind(repository: Repository, iface: InterfaceDefinition, constructor: ExtendedAttribute? = iface.findConstructor()): GenerateDefinitionKind = - if (iface.dictionary || constructor != null || iface.superTypes(repository).any { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS }) { +private fun resolveDefinitionKind(repository: Repository, iface: InterfaceDefinition, constructors: List = iface.findConstructors()): GenerateDefinitionKind = + if (iface.dictionary || constructors.isNotEmpty() || iface.superTypes(repository).any { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS }) { GenerateDefinitionKind.CLASS - } - else { + } else { GenerateDefinitionKind.TRAIT } private fun InterfaceDefinition.mapAttributes(repository: Repository) = attributes.map { generateAttribute(!dictionary, repository, it) } private fun InterfaceDefinition.mapOperations(repository: Repository) = operations.flatMap { generateFunctions(repository, it) } -private fun Constant.mapConstant(repository : Repository) = GenerateAttribute(name, mapType(repository, type), value, false, true, false, false) +private fun Constant.mapConstant(repository: Repository) = GenerateAttribute(name, mapType(repository, type), value, false, true, false, false) +private fun emptyConstructor() = ExtendedAttribute(null, "Constructor", emptyList()) fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateTraitOrClass { - val constructor = iface.findConstructor() - val constructorFunction = generateFunction(repository, Operation("", "Unit", constructor?.arguments ?: emptyList(), emptyList()), functionName = "", nativeGetterOrSetter = NativeGetterOrSetter.NONE) - val constructorArgumentNames = constructorFunction.arguments.map { it.name }.toSet() - - val constructorSuperCalls = iface.superTypes + val superClasses = iface.superTypes .map { repository.interfaces[it] } .filterNotNull() .filter { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS } - .map { - val superConstructor = it.findConstructor() - GenerateFunctionCall( - name = it.name, - arguments = if (superConstructor == null) { - emptyList() - } else { - superConstructor.arguments.map { arg -> - if (arg.name in constructorArgumentNames) arg.name else "noImpl" - } - } - ) - } - val entityKind = resolveDefinitionKind(repository, iface, constructor) + assert(superClasses.size() <= 1) { "Type ${iface.name} should have one or zero super classes but found ${superClasses.map { it.name }}" } + val superClass = superClasses.singleOrNull() + val superConstructor = superClass?.findConstructors()?.firstOrNull() + + val declaredConstructors = iface.findConstructors() + val entityKind = resolveDefinitionKind(repository, iface, declaredConstructors) val extensions = repository.externals[iface.name]?.map { repository.interfaces[it] }?.filterNotNull() ?: emptyList() + val primaryConstructor = when { + declaredConstructors.size() == 1 -> declaredConstructors.single() + declaredConstructors.isEmpty() && entityKind == GenerateDefinitionKind.CLASS -> emptyConstructor() + else -> declaredConstructors.firstOrNull { it.arguments.isEmpty() } + } + val secondaryConstructors = declaredConstructors.filter { it != primaryConstructor } + + val primaryConstructorWithCall = if (primaryConstructor != null) { + val constructorAsFunction = generateConstructorAsFunction(repository, primaryConstructor) + val superCall = when { + superClass != null -> superOrPrimaryConstructorCall(constructorAsFunction, superClass.name, superConstructor ?: emptyConstructor()) + else -> null + } + + ConstructorWithSuperTypeCall(constructorAsFunction, primaryConstructor, superCall) + } else null + + val secondaryConstructorsWithCall = secondaryConstructors.map { secondaryConstructor -> + val constructorAsFunction = generateConstructorAsFunction(repository, secondaryConstructor) + val initCall = when { + primaryConstructorWithCall != null -> superOrPrimaryConstructorCall(constructorAsFunction, "this", primaryConstructorWithCall.constructorAttribute) + else -> superOrPrimaryConstructorCall(constructorAsFunction, "super", superConstructor ?: emptyConstructor()) + } + + ConstructorWithSuperTypeCall(constructorAsFunction, secondaryConstructor, initCall) + } + return GenerateTraitOrClass(iface.name, iface.namespace, entityKind, iface.superTypes, memberAttributes = (iface.mapAttributes(repository) + extensions.flatMap { it.mapAttributes(repository) }).distinct().toList(), memberFunctions = (iface.mapOperations(repository) + extensions.flatMap { it.mapOperations(repository) }).distinct().toList(), - constants = (iface.constants.map {it.mapConstant(repository)} + extensions.flatMap { it.constants.map {it.mapConstant(repository)} }.distinct().toList()), - constructor = constructorFunction, - superConstructorCalls = constructorSuperCalls + constants = (iface.constants.map { it.mapConstant(repository) } + extensions.flatMap { it.constants.map { it.mapConstant(repository) } }.distinct().toList()), + primaryConstructor = primaryConstructorWithCall, + secondaryConstructors = secondaryConstructorsWithCall ) } -fun mapUnionType(it : UnionType) = GenerateTraitOrClass( +fun generateConstructorAsFunction(repository: Repository, constructor: ExtendedAttribute) = generateFunction( + repository, + Operation("", "Unit", constructor.arguments, emptyList()), + functionName = "", + nativeGetterOrSetter = NativeGetterOrSetter.NONE) + +fun superOrPrimaryConstructorCall(constructorAsFunction: GenerateFunction, superClassName: String, superOrPrimaryConstructor: ExtendedAttribute): GenerateFunctionCall { + val constructorArgumentNames = constructorAsFunction.arguments.map { it.name }.toSet() + return GenerateFunctionCall( + name = superClassName, + arguments = superOrPrimaryConstructor.arguments.map { arg -> + if (arg.name in constructorArgumentNames) arg.name else "noImpl" + } + ) +} + +fun mapUnionType(it: UnionType) = GenerateTraitOrClass( name = it.name, namespace = it.namespace, kind = GenerateDefinitionKind.TRAIT, @@ -149,16 +180,16 @@ fun mapUnionType(it : UnionType) = GenerateTraitOrClass( memberAttributes = emptyList(), memberFunctions = emptyList(), constants = emptyList(), - constructor = null, - superConstructorCalls = emptyList() + primaryConstructor = null, + secondaryConstructors = emptyList() ) -fun generateUnionTypeTraits(allUnionTypes : Iterable): List = allUnionTypes.map(::mapUnionType) +fun generateUnionTypeTraits(allUnionTypes: Iterable): List = allUnionTypes.map(::mapUnionType) fun mapDefinitions(repository: Repository, definitions: Iterable) = definitions.filter { "NoInterfaceObject" !in it.extendedAttributes.map { it.call } }.map { generateTrait(repository, it) } -fun generateUnions(ifaces: List, typedefs: Iterable) : GenerateUnionTypes { +fun generateUnions(ifaces: List, typedefs: Iterable): GenerateUnionTypes { val declaredTypes = ifaces.toMap { it.name } val anonymousUnionTypes = collectUnionTypes(declaredTypes) diff --git a/libraries/tools/idl2k/src/main/kotlin/model.kt b/libraries/tools/idl2k/src/main/kotlin/model.kt index 854b1284e55..e1035a3eeec 100644 --- a/libraries/tools/idl2k/src/main/kotlin/model.kt +++ b/libraries/tools/idl2k/src/main/kotlin/model.kt @@ -41,6 +41,7 @@ val GenerateAttribute.signature: String get() = "$name:${type.typeSignature}" fun GenerateAttribute.dynamicIfUnknownType(allTypes : Set, standardTypes : Set = standardTypes()) = copy(type = type.dynamicIfUnknownType(allTypes, standardTypes)) +fun List.dynamicIfUnknownType(allTypes : Set, standardTypes : Set = standardTypes()) = map { it.dynamicIfUnknownType(allTypes, standardTypes) } enum class NativeGetterOrSetter { NONE, @@ -72,6 +73,7 @@ data class GenerateFunction( val nativeGetterOrSetter: NativeGetterOrSetter ) +data class ConstructorWithSuperTypeCall(val constructor: GenerateFunction, val constructorAttribute: ExtendedAttribute, val initTypeCall: GenerateFunctionCall?) data class GenerateTraitOrClass( val name: String, val namespace: String, @@ -80,14 +82,9 @@ data class GenerateTraitOrClass( val memberAttributes: List, val memberFunctions: List, val constants: List, - val constructor: GenerateFunction?, - val superConstructorCalls: List -) { - init { - assert(superConstructorCalls.size() <= 1, "It shoould be zero or one super constructors") - } -} - + val primaryConstructor: ConstructorWithSuperTypeCall?, + val secondaryConstructors: List +) val GenerateFunction.signature: String get() = arguments.map { it.type.typeSignature }.joinToString(", ", "$name(", ")") @@ -96,9 +93,9 @@ fun GenerateFunction.dynamicIfUnknownType(allTypes : Set) = standardType copy(returnType = returnType.dynamicIfUnknownType(allTypes, standardTypes), arguments = arguments.map { it.dynamicIfUnknownType(allTypes, standardTypes) }) } -fun InterfaceDefinition.findExtendedAttribute(name: String) = extendedAttributes.firstOrNull { it.call == name } -fun InterfaceDefinition?.hasExtendedAttribute(name: String) = this?.findExtendedAttribute(name) ?: null != null -fun InterfaceDefinition.findConstructor() = findExtendedAttribute("Constructor") +fun InterfaceDefinition.findExtendedAttributes(name: String) = extendedAttributes.filter { it.call == name } +fun InterfaceDefinition?.hasExtendedAttribute(name: String) = this?.findExtendedAttributes(name)?.isNotEmpty() ?: false +fun InterfaceDefinition.findConstructors() = findExtendedAttributes("Constructor") data class GenerateUnionTypes( val typeNamesToUnionsMap: Map>, diff --git a/libraries/tools/idl2k/src/main/kotlin/render.kt b/libraries/tools/idl2k/src/main/kotlin/render.kt index 70aff29fe80..29d8fb4b9db 100644 --- a/libraries/tools/idl2k/src/main/kotlin/render.kt +++ b/libraries/tools/idl2k/src/main/kotlin/render.kt @@ -94,20 +94,23 @@ fun Appendable.render(allTypes: Map, typeNamesToUn GenerateDefinitionKind.TRAIT -> append("interface ") } - append(iface.name) - if (iface.constructor != null && iface.constructor.arguments.isNotEmpty()) { - append("(") - renderArgumentsDeclaration(iface.constructor.arguments.map { it.dynamicIfUnknownType(allTypes.keySet()) }, false) - append(")") - } - val allSuperTypes = iface.allSuperTypes(allTypes) val allSuperTypesNames = allSuperTypes.map { it.name }.toSet() - val superCalls = iface.superConstructorCalls.map { it.name }.toSet() + append(iface.name) + val primary = iface.primaryConstructor + if (primary != null) { + if (primary.constructor.arguments.isNotEmpty() || iface.secondaryConstructors.isNotEmpty()) { + append("(") + renderArgumentsDeclaration(primary.constructor.arguments.dynamicIfUnknownType(allTypes.keySet()), false) + append(")") + } + } + + val superCallName = primary?.initTypeCall?.name val superTypesWithCalls = - iface.superConstructorCalls.map { renderCall(it) } + - iface.superTypes.filter { it !in superCalls && it in allSuperTypesNames } + + listOf(primary?.initTypeCall).filterNotNull().map { renderCall(it) } + + iface.superTypes.filter { it != superCallName && it in allSuperTypesNames } + (typeNamesToUnions[iface.name] ?: emptyList()) if (superTypesWithCalls.isNotEmpty()) { @@ -116,6 +119,20 @@ fun Appendable.render(allTypes: Map, typeNamesToUn appendln (" {") + iface.secondaryConstructors.forEach { secondary -> + indent(1) + append("constructor(") + renderArgumentsDeclaration(secondary.constructor.arguments.dynamicIfUnknownType(allTypes.keySet()), false) + append(")") + + if (secondary.initTypeCall != null) { + append(" : ") + append(renderCall(secondary.initTypeCall)) + } + + appendln() + } + val superAttributes = allSuperTypes.flatMap { it.memberAttributes }.distinct() val superFunctions = allSuperTypes.flatMap { it.memberFunctions }.distinct() val superSignatures = superAttributes.map { it.signature } merge superFunctions.map { it.signature } diff --git a/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt b/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt index b6f14a74586..7c311af93a3 100644 --- a/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt +++ b/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt @@ -60,7 +60,7 @@ data class FunctionType(val parameterTypes : List, val returnType : S val FunctionType.arity : Int get() = parameterTypes.size() val FunctionType.text : String - get() = "(${parameterTypes.map { it.formatFunctionTypePart() }.join(", ")}) -> ${returnType}" + get() = "(${parameterTypes.map { it.formatFunctionTypePart() }.join(", ")}) -> $returnType" fun FunctionType(text : String) : FunctionType { val (parameters, returnType) = text.split("->".toRegex()).map { it.trim() }.filter { it != "" } @@ -135,12 +135,13 @@ private fun mapTypedef(repository: Repository, type: String): String { private fun splitUnionType(unionType: String) = unionType.replace("Union<".toRegex(), "").replace("[>]+".toRegex(), "").split("\\s*,\\s*".toRegex()).distinct().map {it.replace("\\?$".toRegex(), "")} -private fun GenerateFunction?.allTypes() = if (this != null) sequenceOf(returnType) + arguments.asSequence().map { it.type } else emptySequence() +private fun GenerateFunction.allTypes() = sequenceOf(returnType) + arguments.asSequence().map { it.type } private fun collectUnionTypes(allTypes: Map) = allTypes.values().asSequence() .flatMap { - it.constructor.allTypes() + + it.secondaryConstructors.asSequence().flatMap { it.constructor.allTypes() } + + sequenceOf(it.primaryConstructor).filterNotNull().flatMap { it.constructor.allTypes() } + it.memberAttributes.asSequence().map { it.type } + it.memberFunctions.asSequence().flatMap { it.allTypes() } }