JS: when possible, treat WebIDL interfaces as abstract classes, not interfaces
This commit is contained in:
committed by
Sergey Mashkov
parent
f415050913
commit
9c8b58b8bf
@@ -77,10 +77,12 @@ 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, constructors: List<ExtendedAttribute> = iface.findConstructors()): GenerateDefinitionKind =
|
||||
if (constructors.isNotEmpty() || iface.superTypes(repository).any { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS }) {
|
||||
GenerateDefinitionKind.CLASS
|
||||
} else {
|
||||
GenerateDefinitionKind.TRAIT
|
||||
when {
|
||||
constructors.isNotEmpty() || iface.superTypes(repository).any { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS } -> {
|
||||
GenerateDefinitionKind.CLASS
|
||||
}
|
||||
iface.callback -> GenerateDefinitionKind.TRAIT
|
||||
else -> GenerateDefinitionKind.ABSTRACT_CLASS
|
||||
}
|
||||
|
||||
private fun InterfaceDefinition.mapAttributes(repository: Repository) = attributes.map { generateAttribute(!dictionary, repository, it) }
|
||||
@@ -92,7 +94,13 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT
|
||||
val superClasses = iface.superTypes
|
||||
.map { repository.interfaces[it] }
|
||||
.filterNotNull()
|
||||
.filter { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS }
|
||||
.filter {
|
||||
when (resolveDefinitionKind(repository, it)) {
|
||||
GenerateDefinitionKind.CLASS,
|
||||
GenerateDefinitionKind.ABSTRACT_CLASS -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
assert(superClasses.size <= 1) { "Type ${iface.name} should have one or zero super classes but found ${superClasses.map { it.name }}" }
|
||||
val superClass = superClasses.singleOrNull()
|
||||
@@ -104,7 +112,7 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT
|
||||
|
||||
val primaryConstructor = when {
|
||||
declaredConstructors.size == 1 -> declaredConstructors.single()
|
||||
declaredConstructors.isEmpty() && entityKind == GenerateDefinitionKind.CLASS -> EMPTY_CONSTRUCTOR
|
||||
declaredConstructors.isEmpty() && (entityKind == GenerateDefinitionKind.CLASS || entityKind == GenerateDefinitionKind.ABSTRACT_CLASS) -> EMPTY_CONSTRUCTOR
|
||||
else -> declaredConstructors.firstOrNull { it.arguments.isEmpty() }
|
||||
}
|
||||
val secondaryConstructors = declaredConstructors.filter { it != primaryConstructor }
|
||||
|
||||
@@ -59,7 +59,8 @@ enum class NativeGetterOrSetter {
|
||||
|
||||
enum class GenerateDefinitionKind {
|
||||
TRAIT,
|
||||
CLASS
|
||||
CLASS,
|
||||
ABSTRACT_CLASS
|
||||
}
|
||||
|
||||
data class GenerateFunctionCall(val name: String, val arguments: List<String>)
|
||||
|
||||
@@ -11,11 +11,17 @@ private fun <O : Appendable> O.indent(commented: Boolean = false, level: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun Appendable.renderAttributeDeclaration(arg: GenerateAttribute, override: Boolean, open: Boolean, omitDefaults: Boolean = false) {
|
||||
when {
|
||||
override -> append("override ")
|
||||
open -> append("open ")
|
||||
arg.vararg -> append("vararg ")
|
||||
private fun Appendable.renderAttributeDeclaration(arg: GenerateAttribute, modality: MemberModality, omitDefaults: Boolean = false) {
|
||||
if (arg.vararg) {
|
||||
append("vararg ")
|
||||
}
|
||||
else {
|
||||
when (modality) {
|
||||
MemberModality.OVERRIDE -> append("override ")
|
||||
MemberModality.ABSTRACT -> append("abstract ")
|
||||
MemberModality.OPEN -> append("open ")
|
||||
MemberModality.FINAL -> {}
|
||||
}
|
||||
}
|
||||
|
||||
append(when(arg.kind) {
|
||||
@@ -32,10 +38,10 @@ private fun Appendable.renderAttributeDeclaration(arg: GenerateAttribute, overri
|
||||
}
|
||||
}
|
||||
|
||||
private fun Appendable.renderAttributeDeclarationAsProperty(arg: GenerateAttribute, override: Boolean, open: Boolean, commented: Boolean, level: Int, omitDefaults: Boolean = false) {
|
||||
private fun Appendable.renderAttributeDeclarationAsProperty(arg: GenerateAttribute, modality: MemberModality, commented: Boolean, level: Int, omitDefaults: Boolean = false) {
|
||||
indent(commented, level)
|
||||
|
||||
renderAttributeDeclaration(arg, override, open, omitDefaults)
|
||||
renderAttributeDeclaration(arg, modality, omitDefaults)
|
||||
|
||||
appendln()
|
||||
if (arg.getterNoImpl) {
|
||||
@@ -60,7 +66,7 @@ private fun String.replaceKeywords() = if (this in keywords) this + "_" else thi
|
||||
|
||||
private fun Appendable.renderArgumentsDeclaration(args: List<GenerateAttribute>, omitDefaults: Boolean = false) =
|
||||
args.joinTo(this, ", ", "(", ")") {
|
||||
StringBuilder().apply { renderAttributeDeclaration(it, it.override, false, omitDefaults) }
|
||||
StringBuilder().apply { renderAttributeDeclaration(it, if (it.override) MemberModality.OVERRIDE else MemberModality.FINAL, omitDefaults) }
|
||||
}
|
||||
|
||||
private fun renderCall(call: GenerateFunctionCall) = "${call.name.replaceKeywords()}(${call.arguments.joinToString(separator = ", ", transform = String::replaceKeywords)})"
|
||||
@@ -108,6 +114,7 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, typeNamesToUn
|
||||
}
|
||||
when (iface.kind) {
|
||||
GenerateDefinitionKind.CLASS -> append("open class ")
|
||||
GenerateDefinitionKind.ABSTRACT_CLASS -> append("abstract class ")
|
||||
GenerateDefinitionKind.TRAIT -> append("interface ")
|
||||
}
|
||||
|
||||
@@ -154,9 +161,17 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, typeNamesToUn
|
||||
.filter { it !in superAttributes && !it.static && (it.isVar || (it.isVal && superAttributesByName[it.name]?.hasNoVars() ?: true)) }
|
||||
.map { it.dynamicIfUnknownType(allTypes.keys) }
|
||||
.groupBy { it.signature }.reduceValues().values.forEach { arg ->
|
||||
renderAttributeDeclarationAsProperty(arg,
|
||||
override = arg.signature in superSignatures,
|
||||
open = iface.kind == GenerateDefinitionKind.CLASS && arg.isVal,
|
||||
val modality = when {
|
||||
arg.signature in superSignatures -> MemberModality.OVERRIDE
|
||||
iface.kind == GenerateDefinitionKind.CLASS && arg.isVal -> MemberModality.OPEN
|
||||
iface.kind == GenerateDefinitionKind.ABSTRACT_CLASS -> when {
|
||||
arg.initializer != null || arg.getterSetterNoImpl -> MemberModality.OPEN
|
||||
else -> MemberModality.ABSTRACT
|
||||
}
|
||||
else -> MemberModality.FINAL
|
||||
}
|
||||
renderAttributeDeclarationAsProperty(arg,
|
||||
modality = modality,
|
||||
commented = arg.isCommented(iface.name),
|
||||
omitDefaults = iface.kind == GenerateDefinitionKind.TRAIT,
|
||||
level = 1
|
||||
@@ -174,10 +189,10 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, typeNamesToUn
|
||||
indent(false, 1)
|
||||
appendln("companion object {")
|
||||
iface.constants.forEach {
|
||||
renderAttributeDeclarationAsProperty(it, override = false, open = false, level = 2, commented = it.isCommented(iface.name))
|
||||
renderAttributeDeclarationAsProperty(it, MemberModality.FINAL, level = 2, commented = it.isCommented(iface.name))
|
||||
}
|
||||
staticAttributes.forEach {
|
||||
renderAttributeDeclarationAsProperty(it, override = false, open = false, level = 2, commented = it.isCommented(iface.name))
|
||||
renderAttributeDeclarationAsProperty(it, MemberModality.FINAL, level = 2, commented = it.isCommented(iface.name))
|
||||
}
|
||||
staticFunctions.forEach {
|
||||
renderFunctionDeclaration(it.fixRequiredArguments(iface.name), override = false, level = 2, commented = it.isCommented(iface.name))
|
||||
@@ -252,3 +267,9 @@ fun Appendable.render(namespace: String, ifaces: List<GenerateTraitOrClass>, uni
|
||||
}
|
||||
}
|
||||
|
||||
enum class MemberModality {
|
||||
OPEN,
|
||||
ABSTRACT,
|
||||
OVERRIDE,
|
||||
FINAL
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user