IDL2K: generate declarations for partial interfaces

This commit is contained in:
Sergey Mashkov
2016-10-14 17:35:50 +03:00
parent 25461b42b9
commit 3285728391
3 changed files with 32 additions and 17 deletions
@@ -73,3 +73,7 @@ val requiredArguments = setOf(
"DOMPoint.constructor.point",
"DOMQuad.constructor.rect"
)
val inheritanceExclude = mapOf(
"SVGAElement" to setOf("HTMLHyperlinkElementUtils")
)
+5 -6
View File
@@ -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,
+23 -11
View File
@@ -131,10 +131,11 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, 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<String, GenerateTraitOrClass>, 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))