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 InterfaceDefinition.superTypes(repository: Repository) = superTypes.map { repository.interfaces[it] }.filterNotNull()
|
||||||
private fun resolveDefinitionKind(repository: Repository, iface: InterfaceDefinition, constructors: List<ExtendedAttribute> = iface.findConstructors()): GenerateDefinitionKind =
|
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 }) {
|
when {
|
||||||
GenerateDefinitionKind.CLASS
|
constructors.isNotEmpty() || iface.superTypes(repository).any { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS } -> {
|
||||||
} else {
|
GenerateDefinitionKind.CLASS
|
||||||
GenerateDefinitionKind.TRAIT
|
}
|
||||||
|
iface.callback -> GenerateDefinitionKind.TRAIT
|
||||||
|
else -> GenerateDefinitionKind.ABSTRACT_CLASS
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InterfaceDefinition.mapAttributes(repository: Repository) = attributes.map { generateAttribute(!dictionary, repository, it) }
|
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
|
val superClasses = iface.superTypes
|
||||||
.map { repository.interfaces[it] }
|
.map { repository.interfaces[it] }
|
||||||
.filterNotNull()
|
.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 }}" }
|
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 superClass = superClasses.singleOrNull()
|
||||||
@@ -104,7 +112,7 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT
|
|||||||
|
|
||||||
val primaryConstructor = when {
|
val primaryConstructor = when {
|
||||||
declaredConstructors.size == 1 -> declaredConstructors.single()
|
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() }
|
else -> declaredConstructors.firstOrNull { it.arguments.isEmpty() }
|
||||||
}
|
}
|
||||||
val secondaryConstructors = declaredConstructors.filter { it != primaryConstructor }
|
val secondaryConstructors = declaredConstructors.filter { it != primaryConstructor }
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ enum class NativeGetterOrSetter {
|
|||||||
|
|
||||||
enum class GenerateDefinitionKind {
|
enum class GenerateDefinitionKind {
|
||||||
TRAIT,
|
TRAIT,
|
||||||
CLASS
|
CLASS,
|
||||||
|
ABSTRACT_CLASS
|
||||||
}
|
}
|
||||||
|
|
||||||
data class GenerateFunctionCall(val name: String, val arguments: List<String>)
|
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) {
|
private fun Appendable.renderAttributeDeclaration(arg: GenerateAttribute, modality: MemberModality, omitDefaults: Boolean = false) {
|
||||||
when {
|
if (arg.vararg) {
|
||||||
override -> append("override ")
|
append("vararg ")
|
||||||
open -> append("open ")
|
}
|
||||||
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) {
|
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)
|
indent(commented, level)
|
||||||
|
|
||||||
renderAttributeDeclaration(arg, override, open, omitDefaults)
|
renderAttributeDeclaration(arg, modality, omitDefaults)
|
||||||
|
|
||||||
appendln()
|
appendln()
|
||||||
if (arg.getterNoImpl) {
|
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) =
|
private fun Appendable.renderArgumentsDeclaration(args: List<GenerateAttribute>, omitDefaults: Boolean = false) =
|
||||||
args.joinTo(this, ", ", "(", ")") {
|
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)})"
|
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) {
|
when (iface.kind) {
|
||||||
GenerateDefinitionKind.CLASS -> append("open class ")
|
GenerateDefinitionKind.CLASS -> append("open class ")
|
||||||
|
GenerateDefinitionKind.ABSTRACT_CLASS -> append("abstract class ")
|
||||||
GenerateDefinitionKind.TRAIT -> append("interface ")
|
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)) }
|
.filter { it !in superAttributes && !it.static && (it.isVar || (it.isVal && superAttributesByName[it.name]?.hasNoVars() ?: true)) }
|
||||||
.map { it.dynamicIfUnknownType(allTypes.keys) }
|
.map { it.dynamicIfUnknownType(allTypes.keys) }
|
||||||
.groupBy { it.signature }.reduceValues().values.forEach { arg ->
|
.groupBy { it.signature }.reduceValues().values.forEach { arg ->
|
||||||
renderAttributeDeclarationAsProperty(arg,
|
val modality = when {
|
||||||
override = arg.signature in superSignatures,
|
arg.signature in superSignatures -> MemberModality.OVERRIDE
|
||||||
open = iface.kind == GenerateDefinitionKind.CLASS && arg.isVal,
|
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),
|
commented = arg.isCommented(iface.name),
|
||||||
omitDefaults = iface.kind == GenerateDefinitionKind.TRAIT,
|
omitDefaults = iface.kind == GenerateDefinitionKind.TRAIT,
|
||||||
level = 1
|
level = 1
|
||||||
@@ -174,10 +189,10 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, typeNamesToUn
|
|||||||
indent(false, 1)
|
indent(false, 1)
|
||||||
appendln("companion object {")
|
appendln("companion object {")
|
||||||
iface.constants.forEach {
|
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 {
|
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 {
|
staticFunctions.forEach {
|
||||||
renderFunctionDeclaration(it.fixRequiredArguments(iface.name), override = false, level = 2, commented = it.isCommented(iface.name))
|
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