From 387291cbf7a14d4054df21b5d415bcd9b09a7ff1 Mon Sep 17 00:00:00 2001 From: Sergey Mashkov Date: Thu, 11 Jun 2015 13:44:34 +0300 Subject: [PATCH] IDL2K support static members --- libraries/tools/idl2k/src/main/kotlin/gen.kt | 13 +++-- libraries/tools/idl2k/src/main/kotlin/idl.kt | 53 +++++++++++++------ .../tools/idl2k/src/main/kotlin/model.kt | 5 +- .../tools/idl2k/src/main/kotlin/render.kt | 21 ++++++-- .../idl2k/src/main/kotlin/typeMappings.kt | 2 +- 5 files changed, 66 insertions(+), 28 deletions(-) diff --git a/libraries/tools/idl2k/src/main/kotlin/gen.kt b/libraries/tools/idl2k/src/main/kotlin/gen.kt index 267c052c507..9242c2af0cd 100644 --- a/libraries/tools/idl2k/src/main/kotlin/gen.kt +++ b/libraries/tools/idl2k/src/main/kotlin/gen.kt @@ -44,10 +44,12 @@ fun generateFunction(repository: Repository, function: Operation, functionName: getterSetterNoImpl = false, override = false, readOnly = true, - vararg = it.vararg + vararg = it.vararg, + static = it.static ) }, - nativeGetterOrSetter = nativeGetterOrSetter + nativeGetterOrSetter = nativeGetterOrSetter, + static = function.static ) } @@ -90,7 +92,8 @@ fun generateAttribute(putNoImpl: Boolean, repository: Repository, attribute: Att getterSetterNoImpl = putNoImpl, readOnly = attribute.readOnly, override = false, - vararg = attribute.vararg + vararg = attribute.vararg, + static = attribute.static ) private fun InterfaceDefinition.superTypes(repository: Repository) = superTypes.map { repository.interfaces[it] }.filterNotNull() @@ -103,7 +106,7 @@ private fun resolveDefinitionKind(repository: Repository, iface: InterfaceDefini private fun InterfaceDefinition.mapAttributes(repository: Repository) = attributes.map { generateAttribute(!dictionary, repository, it) } private fun InterfaceDefinition.mapOperations(repository: Repository) = operations.flatMap { generateFunctions(repository, it) } -private fun Constant.mapConstant(repository: Repository) = GenerateAttribute(name, mapType(repository, type), value, false, true, false, false) +private fun Constant.mapConstant(repository : Repository) = GenerateAttribute(name, mapType(repository, type), value, false, true, false, false, true) private fun emptyConstructor() = ExtendedAttribute(null, "Constructor", emptyList()) fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateTraitOrClass { @@ -158,7 +161,7 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT fun generateConstructorAsFunction(repository: Repository, constructor: ExtendedAttribute) = generateFunction( repository, - Operation("", "Unit", constructor.arguments, emptyList()), + Operation("", "Unit", constructor.arguments, emptyList(), false), functionName = "", nativeGetterOrSetter = NativeGetterOrSetter.NONE) diff --git a/libraries/tools/idl2k/src/main/kotlin/idl.kt b/libraries/tools/idl2k/src/main/kotlin/idl.kt index e14b373e322..227ab43b5a0 100644 --- a/libraries/tools/idl2k/src/main/kotlin/idl.kt +++ b/libraries/tools/idl2k/src/main/kotlin/idl.kt @@ -28,8 +28,8 @@ import org.antlr.webidl.WebIDLParser.* import java.util.ArrayList data class ExtendedAttribute(val name: String?, val call: String, val arguments: List) -data class Operation(val name: String, val returnType: String, val parameters: List, val attributes: List) -data class Attribute(val name: String, val type: String, val readOnly: Boolean = true, val defaultValue: String? = null, val vararg: Boolean) +data class Operation(val name: String, val returnType: String, val parameters: List, val attributes: List, val static: Boolean) +data class Attribute(val name: String, val type: String, val readOnly: Boolean = true, val defaultValue: String? = null, val vararg: Boolean, val static: Boolean) data class Constant(val name: String, val type: String, val value: String?) fun Attribute.formatFunctionTypePart() = if (vararg) "vararg $type" else type @@ -42,7 +42,7 @@ enum class DefinitionKind { DICTIONARY } -trait Definition +interface Definition data class TypedefDefinition(val types: String, val namespace: String, val name: String) : Definition data class InterfaceDefinition( val name: String, @@ -66,7 +66,7 @@ class ExtendedAttributeArgumentsParser : WebIDLBaseVisitor>() { override fun defaultResult(): List = arguments override fun visitOptionalOrRequiredArgument(ctx: WebIDLParser.OptionalOrRequiredArgumentContext): List { - val attributeVisitor = AttributeVisitor(false) + val attributeVisitor = AttributeVisitor() attributeVisitor.visit(ctx) val parameter = attributeVisitor.visitChildren(ctx) @@ -104,7 +104,7 @@ class ExtendedAttributeParser : WebIDLBaseVisitor() { object : WebIDLBaseVisitor() { override fun visitTerminal(node: TerminalNode) { if (node.getSymbol().getType() == WebIDLLexer.IDENTIFIER_WEBIDL) { - arguments.add(Attribute(node.getText(), "any", true, vararg = false)) + arguments.add(Attribute(node.getText(), "any", true, vararg = false, static = false)) } } }.visitChildren(ctx) @@ -156,13 +156,13 @@ class TypeVisitor : WebIDLBaseVisitor() { } } -class OperationVisitor(private val attributes: List) : WebIDLBaseVisitor() { +class OperationVisitor(private val attributes: List, private val static: Boolean) : WebIDLBaseVisitor() { private var name: String = "" private var returnType: String = "" private val parameters = ArrayList() private val exts = ArrayList() - override fun defaultResult() = Operation(name, returnType, parameters, attributes + exts) + override fun defaultResult() = Operation(name, returnType, parameters, attributes + exts, static) override fun visitOptionalIdentifier(ctx: OptionalIdentifierContext): Operation { name = ctx.getText() @@ -183,7 +183,7 @@ class OperationVisitor(private val attributes: List) : WebIDL } override fun visitOptionalOrRequiredArgument(ctx: WebIDLParser.OptionalOrRequiredArgumentContext): Operation { - val attributeVisitor = AttributeVisitor() + val attributeVisitor = AttributeVisitor(static = false) attributeVisitor.visit(ctx) val parameter = attributeVisitor.visitChildren(ctx) @@ -193,13 +193,13 @@ class OperationVisitor(private val attributes: List) : WebIDL } } -class AttributeVisitor(private val readOnly: Boolean = false) : WebIDLBaseVisitor() { +class AttributeVisitor(private val readOnly: Boolean = false, private val static: Boolean = false) : WebIDLBaseVisitor() { private var type: String = "" private var name: String = "" private var defaultValue: String? = null private var vararg: Boolean = false - override fun defaultResult(): Attribute = Attribute(name, type, readOnly, defaultValue, vararg) + override fun defaultResult(): Attribute = Attribute(name, type, readOnly, defaultValue, vararg, static) override fun visitType(ctx: WebIDLParser.TypeContext): Attribute { type = TypeVisitor().visit(ctx) @@ -265,6 +265,7 @@ class DefinitionVisitor(val extendedAttributes: List, val nam private val operations = ArrayList() private val attributes = ArrayList() private var readOnly: Boolean = false + private var static: Boolean = false private val inherited = ArrayList() private var typedefType: String? = null private var implements: String? = null @@ -289,7 +290,7 @@ class DefinitionVisitor(val extendedAttributes: List, val nam kind = DefinitionKind.TYPEDEF name = getName(ctx) - val function = OperationVisitor(memberAttributes.toList()).visit(ctx) + val function = OperationVisitor(memberAttributes.toList(), static).visit(ctx) typedefType = "(${function.parameters.map { it.formatFunctionTypePart() }.join(", ")}) -> ${function.returnType}" memberAttributes.clear() @@ -373,7 +374,7 @@ class DefinitionVisitor(val extendedAttributes: List, val nam } }.visit(ctx) - attributes.add(Attribute(name ?: "", type, false, defaultValue, false)) + attributes.add(Attribute(name ?: "", type, false, defaultValue, false, static)) return defaultResult() } @@ -392,11 +393,15 @@ class DefinitionVisitor(val extendedAttributes: List, val nam } override fun visitOperation(ctx: OperationContext): Definition { - operations.add(OperationVisitor(memberAttributes.toList()).visit(ctx)) - memberAttributes.clear() + visitOperationImpl(ctx) return defaultResult() } + private fun visitOperationImpl(ctx: ParserRuleContext) { + operations.add(OperationVisitor(memberAttributes.toList(), static).visit(ctx)) + memberAttributes.clear() + } + override fun visitInheritance(ctx: WebIDLParser.InheritanceContext): Definition { if (ctx.children != null) { inherited.addAll(ctx.children.filterIdentifiers().map { it.getText().trim() }.filter { it != "" }) @@ -412,8 +417,26 @@ class DefinitionVisitor(val extendedAttributes: List, val nam return defaultResult() } + override fun visitStaticMember(ctx: WebIDLParser.StaticMemberContext): Definition { + static = true + visitChildren(ctx) + static = false + + return defaultResult() + } + + override fun visitStaticMemberRest(ctx: WebIDLParser.StaticMemberRestContext): Definition { + if (ctx.children?.any { it is OperationRestContext } ?: false) { + visitOperationImpl(ctx) + } else { + visitChildren(ctx) + } + + return defaultResult() + } + override fun visitAttributeRest(ctx: WebIDLParser.AttributeRestContext): Definition { - with(AttributeVisitor(readOnly)) { + with(AttributeVisitor(readOnly, static)) { visit(ctx) this@DefinitionVisitor.attributes.add(visitChildren(ctx)) } diff --git a/libraries/tools/idl2k/src/main/kotlin/model.kt b/libraries/tools/idl2k/src/main/kotlin/model.kt index e1035a3eeec..976af17dc85 100644 --- a/libraries/tools/idl2k/src/main/kotlin/model.kt +++ b/libraries/tools/idl2k/src/main/kotlin/model.kt @@ -27,7 +27,7 @@ data class Repository( val enums: Map ) -data class GenerateAttribute(val name: String, val type: String, val initializer: String?, val getterSetterNoImpl: Boolean, val readOnly: Boolean, val override: Boolean, var vararg: Boolean) +data class GenerateAttribute(val name: String, val type: String, val initializer: String?, val getterSetterNoImpl: Boolean, val readOnly: Boolean, val override: Boolean, var vararg: Boolean, val static: Boolean) val GenerateAttribute.getterNoImpl: Boolean get() = getterSetterNoImpl @@ -70,7 +70,8 @@ data class GenerateFunction( val name: String, val returnType: String, val arguments: List, - val nativeGetterOrSetter: NativeGetterOrSetter + val nativeGetterOrSetter: NativeGetterOrSetter, + val static: Boolean ) data class ConstructorWithSuperTypeCall(val constructor: GenerateFunction, val constructorAttribute: ExtendedAttribute, val initTypeCall: GenerateFunctionCall?) diff --git a/libraries/tools/idl2k/src/main/kotlin/render.kt b/libraries/tools/idl2k/src/main/kotlin/render.kt index 29d8fb4b9db..f50cbf7ff5c 100644 --- a/libraries/tools/idl2k/src/main/kotlin/render.kt +++ b/libraries/tools/idl2k/src/main/kotlin/render.kt @@ -64,12 +64,13 @@ private fun Appendable.renderArgumentsDeclaration(args: List, private fun renderCall(call: GenerateFunctionCall) = "${call.name.replaceKeywords()}(${call.arguments.map { it.replaceKeywords() }.join(", ")})" -private fun Appendable.renderFunctionDeclaration(f: GenerateFunction, override: Boolean) { - indent(1) +private fun Appendable.renderFunctionDeclaration(f: GenerateFunction, override: Boolean, level: Int = 1) { + indent(level) when (f.nativeGetterOrSetter) { NativeGetterOrSetter.GETTER -> append("nativeGetter ") NativeGetterOrSetter.SETTER -> append("nativeSetter ") + NativeGetterOrSetter.NONE -> {} } if (override) { @@ -137,19 +138,29 @@ fun Appendable.render(allTypes: Map, typeNamesToUn val superFunctions = allSuperTypes.flatMap { it.memberFunctions }.distinct() val superSignatures = superAttributes.map { it.signature } merge superFunctions.map { it.signature } - iface.memberAttributes.filter { it !in superAttributes }.map { it.dynamicIfUnknownType(allTypes.keySet()) }.groupBy { it.signature }.reduceValues().values().forEach { arg -> + iface.memberAttributes.filter { it !in superAttributes && !it.static }.map { it.dynamicIfUnknownType(allTypes.keySet()) }.groupBy { it.signature }.reduceValues().values().forEach { arg -> renderAttributeDeclaration(arg, arg.signature in superSignatures) } - iface.memberFunctions.filter { it !in superFunctions }.map { it.dynamicIfUnknownType(allTypes.keySet()) }.groupBy { it.signature }.reduceValues(::betterFunction).values().forEach { + iface.memberFunctions.filter { it !in superFunctions && !it.static }.map { it.dynamicIfUnknownType(allTypes.keySet()) }.groupBy { it.signature }.reduceValues(::betterFunction).values().forEach { renderFunctionDeclaration(it, it.signature in superSignatures) } - if (iface.constants.isNotEmpty()) { + + val staticAttributes = iface.memberAttributes.filter { it.static } + val staticFunctions = iface.memberFunctions.filter { it.static } + + if (iface.constants.isNotEmpty() || staticAttributes.isNotEmpty() || staticFunctions.isNotEmpty()) { appendln() indent(1) appendln("companion object {") iface.constants.forEach { renderAttributeDeclaration(it, override = false, level = 2) } + staticAttributes.forEach { + renderAttributeDeclaration(it, override = false, level = 2) + } + staticFunctions.forEach { + renderFunctionDeclaration(it, override = false, level = 2) + } indent(1) appendln("}") } diff --git a/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt b/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt index 7c311af93a3..d87fc42678b 100644 --- a/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt +++ b/libraries/tools/idl2k/src/main/kotlin/typeMappings.kt @@ -69,7 +69,7 @@ fun FunctionType(text : String) : FunctionType { parameterTypes = parameters.removeSurrounding("(", ")").split(',') .map { it.trim() } .filter { !it.isEmpty() } - .map { Attribute(name = "", type = it.removePrefix("vararg "), vararg = it.startsWith("vararg ")) } + .map { Attribute(name = "", type = it.removePrefix("vararg "), vararg = it.startsWith("vararg "), static = false) } .toList(), returnType = returnType )