From a5d6541f1ed33fb49fc9b2648740b239f9be65bd Mon Sep 17 00:00:00 2001 From: Sergey Mashkov Date: Fri, 10 Mar 2017 18:26:16 +0300 Subject: [PATCH] KT-16252 IDL2K: Add ItemArrayLike interface implementation to collection-like classes --- libraries/tools/idl2k/src/main/kotlin/config.kt | 13 +++++++++++++ libraries/tools/idl2k/src/main/kotlin/gen.kt | 15 ++++++++++++++- libraries/tools/idl2k/src/main/kotlin/render.kt | 5 +++-- .../tools/idl2k/src/main/kotlin/typeMappings.kt | 2 +- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/libraries/tools/idl2k/src/main/kotlin/config.kt b/libraries/tools/idl2k/src/main/kotlin/config.kt index b49b7fa2c39..ebe5a72170c 100644 --- a/libraries/tools/idl2k/src/main/kotlin/config.kt +++ b/libraries/tools/idl2k/src/main/kotlin/config.kt @@ -76,4 +76,17 @@ val requiredArguments = setOf( val inheritanceExclude = mapOf( "SVGAElement" to setOf("HTMLHyperlinkElementUtils") +) + +val kotlinBuiltinInterfaces = mapOf( + "ItemArrayLike" to GenerateTraitOrClass("ItemArrayLike", "org.w3c.dom", GenerateDefinitionKind.INTERFACE, emptyList(), + memberAttributes = mutableListOf(GenerateAttribute("length", SimpleType("Int", false), null, false, AttributeKind.VAL, false, false, false, false)), + memberFunctions = mutableListOf(GenerateFunction("item", DynamicType, listOf( + GenerateAttribute("index", SimpleType("Int", false), null, false, AttributeKind.ARGUMENT, false, false, false, false) + ), NativeGetterOrSetter.NONE, false, false)), + constants = emptyList(), + generateBuilderFunction = false, + primaryConstructor = null, + secondaryConstructors = emptyList() + ) ) \ No newline at end of file diff --git a/libraries/tools/idl2k/src/main/kotlin/gen.kt b/libraries/tools/idl2k/src/main/kotlin/gen.kt index 4dd21112bf3..c42efa3a880 100644 --- a/libraries/tools/idl2k/src/main/kotlin/gen.kt +++ b/libraries/tools/idl2k/src/main/kotlin/gen.kt @@ -161,7 +161,7 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT ConstructorWithSuperTypeCall(constructorAsFunction, secondaryConstructor) } - return GenerateTraitOrClass(iface.name, iface.namespace, entityKind, (iface.superTypes + extensions.map { it.name }).distinct(), + val result = GenerateTraitOrClass(iface.name, iface.namespace, entityKind, (iface.superTypes + extensions.map { it.name }).distinct(), memberAttributes = iface.mapAttributes(repository).toMutableList(), memberFunctions = iface.mapOperations(repository).toMutableList(), constants = (iface.constants.map { it.mapConstant(repository) } + extensions.flatMap { it.constants.map { it.mapConstant(repository) } }.distinct().toList()), @@ -169,6 +169,19 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT secondaryConstructors = secondaryConstructorsWithCall, generateBuilderFunction = iface.dictionary ) + + return markAsArrayLikeIfApplicable(result) +} + +fun markAsArrayLikeIfApplicable(iface: GenerateTraitOrClass): GenerateTraitOrClass { + fun isInt(type: Type) = type is SimpleType && type.type == "Int" + + val lengthProperty = iface.memberAttributes.singleOrNull { it.name == "length" && isInt(it.type) } + val itemAccessFunction = iface.memberFunctions.singleOrNull { it.name == "item" && it.arguments.map { isInt(it.type) } == listOf(true) && it.returnType != UnitType } + + if (lengthProperty == null || itemAccessFunction == null) return iface + + return iface.copy(superTypes = iface.superTypes + "ItemArrayLike<${itemAccessFunction.returnType.dropNullable().render()}>") } fun generateConstructorAsFunction(repository: Repository, constructor: ExtendedAttribute) = generateFunction( diff --git a/libraries/tools/idl2k/src/main/kotlin/render.kt b/libraries/tools/idl2k/src/main/kotlin/render.kt index 3e28df1db04..7b33c943e73 100644 --- a/libraries/tools/idl2k/src/main/kotlin/render.kt +++ b/libraries/tools/idl2k/src/main/kotlin/render.kt @@ -159,7 +159,7 @@ fun Appendable.render(allTypes: Map, enums: List append("interface ") } - val allSuperTypes = iface.allSuperTypes(allTypes) + val allSuperTypes = iface.allSuperTypes(allTypes + kotlinBuiltinInterfaces) val allSuperTypesNames = allSuperTypes.map { it.name }.toSet() append(iface.name) @@ -171,7 +171,8 @@ fun Appendable.render(allTypes: Map, enums: List) = tailrec fun allSuperTypesImpl(roots: List, all: Map, result: MutableSet) { if (roots.isNotEmpty()) { - allSuperTypesImpl(roots.flatMap { it.superTypes }.map { all[it] }.filterNotNull().filter { result.add(it) }, all, result) + allSuperTypesImpl(roots.flatMap { it.superTypes }.map { all[it] ?: all[it.substringBefore("<")] }.filterNotNull().filter { result.add(it) }, all, result) } }