JS: when possible, treat WebIDL interfaces as abstract classes, not interfaces

This commit is contained in:
Alexey Andreev
2016-09-30 19:31:21 +03:00
committed by Sergey Mashkov
parent f415050913
commit 9c8b58b8bf
3 changed files with 50 additions and 20 deletions
+14 -6
View File
@@ -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>)
+34 -13
View File
@@ -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
}