diff --git a/libraries/tools/idl2k/src/main/kotlin/config.kt b/libraries/tools/idl2k/src/main/kotlin/config.kt index 0ad9df73c73..b49b7fa2c39 100644 --- a/libraries/tools/idl2k/src/main/kotlin/config.kt +++ b/libraries/tools/idl2k/src/main/kotlin/config.kt @@ -73,3 +73,7 @@ val requiredArguments = setOf( "DOMPoint.constructor.point", "DOMQuad.constructor.rect" ) + +val inheritanceExclude = mapOf( + "SVGAElement" to setOf("HTMLHyperlinkElementUtils") +) \ No newline at end of file diff --git a/libraries/tools/idl2k/src/main/kotlin/gen.kt b/libraries/tools/idl2k/src/main/kotlin/gen.kt index bf3f91e12eb..0237205ca97 100644 --- a/libraries/tools/idl2k/src/main/kotlin/gen.kt +++ b/libraries/tools/idl2k/src/main/kotlin/gen.kt @@ -95,8 +95,7 @@ private val EMPTY_CONSTRUCTOR = ExtendedAttribute(null, "Constructor", emptyList fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateTraitOrClass { val superClasses = iface.superTypes - .map { repository.interfaces[it] } - .filterNotNull() + .mapNotNull { repository.interfaces[it] } .filter { when (resolveDefinitionKind(repository, it)) { GenerateDefinitionKind.CLASS, @@ -111,7 +110,7 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT val declaredConstructors = iface.findConstructors() val entityKind = resolveDefinitionKind(repository, iface, declaredConstructors) - val extensions = repository.externals[iface.name]?.map { repository.interfaces[it] }?.filterNotNull() ?: emptyList() + val extensions = repository.externals[iface.name]?.mapNotNull { repository.interfaces[it] } ?: emptyList() val primaryConstructor = when { declaredConstructors.size == 1 -> declaredConstructors.single() @@ -141,9 +140,9 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT 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(), + return GenerateTraitOrClass(iface.name, iface.namespace, entityKind, (iface.superTypes + extensions.map { it.name }).distinct(), + memberAttributes = iface.mapAttributes(repository), + memberFunctions = iface.mapOperations(repository), constants = (iface.constants.map { it.mapConstant(repository) } + extensions.flatMap { it.constants.map { it.mapConstant(repository) } }.distinct().toList()), primaryConstructor = primaryConstructorWithCall, secondaryConstructors = secondaryConstructorsWithCall, diff --git a/libraries/tools/idl2k/src/main/kotlin/render.kt b/libraries/tools/idl2k/src/main/kotlin/render.kt index f3cd1cd5b6f..93d4a9ed707 100644 --- a/libraries/tools/idl2k/src/main/kotlin/render.kt +++ b/libraries/tools/idl2k/src/main/kotlin/render.kt @@ -131,10 +131,11 @@ fun Appendable.render(allTypes: Map, typeNamesToUn renderArgumentsDeclaration(primary.constructor.fixRequiredArguments(iface.name).arguments.dynamicIfUnknownType(allTypes.keys), false) } + val superTypesExclude = inheritanceExclude[iface.name] ?: emptySet() val superCallName = primary?.initTypeCall?.name val superTypesWithCalls = (primary?.initTypeCall?.let { listOf(renderCall(it)) } ?: emptyList()) + - iface.superTypes.filter { it != superCallName && it in allSuperTypesNames } + + iface.superTypes.filter { it != superCallName && it in allSuperTypesNames }.filter { it !in superTypesExclude } + (typeNamesToUnions[iface.name] ?: emptyList()) if (superTypesWithCalls.isNotEmpty()) { @@ -164,22 +165,33 @@ fun Appendable.render(allTypes: Map, typeNamesToUn iface.memberAttributes .filter { it !in superAttributes && !it.static && (it.isVar || (it.isVal && superAttributesByName[it.name]?.hasNoVars() ?: true)) } .map { it.dynamicIfUnknownType(allTypes.keys) } - .groupBy { it.name }.reduceValues(::merge).values.forEach { arg -> + .groupBy { it.name } + .reduceValues(::merge).values.forEach { attribute -> val modality = when { - arg.signature in superSignatures -> MemberModality.OVERRIDE - iface.kind == GenerateDefinitionKind.CLASS && arg.isVal -> MemberModality.OPEN + attribute.signature in superSignatures -> MemberModality.OVERRIDE + iface.kind == GenerateDefinitionKind.CLASS && attribute.isVal -> MemberModality.OPEN iface.kind == GenerateDefinitionKind.ABSTRACT_CLASS -> when { - arg.initializer != null || arg.getterSetterNoImpl -> MemberModality.OPEN + attribute.initializer != null || attribute.getterSetterNoImpl -> MemberModality.OPEN else -> MemberModality.ABSTRACT } else -> MemberModality.FINAL } - renderAttributeDeclarationAsProperty(arg, - modality = modality, - commented = arg.isCommented(iface.name), - omitDefaults = iface.kind == GenerateDefinitionKind.INTERFACE, - level = 1 - ) + + if (attribute.name in superAttributesByName && attribute.signature !in superSignatures) { + System.err.println("Property ${iface.name}.${attribute.name} has different type in super type(s) so will not be generated: ") + for ((superTypeName, attributes) in allSuperTypes.map { it.name to it.memberAttributes.filter { it.name == attribute.name }.distinct() }) { + for (superAttribute in attributes) { + System.err.println(" $superTypeName.${attribute.name}: ${superAttribute.type.render()}") + } + } + } else { + renderAttributeDeclarationAsProperty(attribute, + modality = modality, + commented = attribute.isCommented(iface.name), + omitDefaults = iface.kind == GenerateDefinitionKind.INTERFACE, + level = 1 + ) + } } iface.memberFunctions.filter { it !in superFunctions && !it.static }.map { it.dynamicIfUnknownType(allTypes.keys) }.groupBy { it.signature }.reduceValues(::betterFunction).values.forEach { renderFunctionDeclaration(it.fixRequiredArguments(iface.name), it.signature in superSignatures, commented = it.isCommented(iface.name))