[Wasm] IDL: Generate overloads for functions with union-typed arguments
This commit is contained in:
committed by
Space Team
parent
24656b1576
commit
2fd77d0925
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.tools.dukat.wasm
|
||||
|
||||
import org.jetbrains.dukat.idlDeclarations.*
|
||||
import org.jetbrains.dukat.idlLowerings.IDLLowering
|
||||
|
||||
class UnionParametersOverloadsLowering : IDLLowering {
|
||||
// Types that are present as union components, but somehow missing IDL declarations. Should be ignored.
|
||||
private val typesMissingFromIDL: Set<String> =
|
||||
setOf("CSSPseudoElement", "BufferSource")
|
||||
|
||||
override fun lowerInterfaceDeclaration(declaration: IDLInterfaceDeclaration, owner: IDLFileDeclaration): IDLInterfaceDeclaration {
|
||||
return declaration.copy(
|
||||
operations = declaration.operations.flatMap(::generateOverloads)
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateOverloads(op: IDLOperationDeclaration): List<IDLOperationDeclaration> {
|
||||
val numUnionTypes = op.arguments.count { it.type is IDLUnionTypeDeclaration }
|
||||
if (numUnionTypes == 0)
|
||||
return listOf(op)
|
||||
|
||||
if (numUnionTypes > 1)
|
||||
TODO(
|
||||
"""
|
||||
Not supported in current implementation to keep it simple.
|
||||
If updated IDL contains multiple union arguments and this check fails,
|
||||
consider updating the algorithm or return listOf(op) as a fallback.
|
||||
"""
|
||||
)
|
||||
|
||||
val unionTypedArgumentIndex = op.arguments.indexOfFirst { it.type is IDLUnionTypeDeclaration }
|
||||
val unionTypedArgument = op.arguments[unionTypedArgumentIndex]
|
||||
val unionType = unionTypedArgument.type as IDLUnionTypeDeclaration
|
||||
|
||||
var unionMembersFlattened = unionType.unionMembers
|
||||
while (unionMembersFlattened.any { it is IDLUnionTypeDeclaration }) {
|
||||
unionMembersFlattened = unionMembersFlattened.flatMap {
|
||||
if (it is IDLUnionTypeDeclaration) it.unionMembers else listOf(it)
|
||||
}
|
||||
}
|
||||
|
||||
val result = unionMembersFlattened.mapNotNull { unionMember ->
|
||||
if (unionMember.name in typesMissingFromIDL)
|
||||
return@mapNotNull null
|
||||
|
||||
op.copy(
|
||||
arguments = op.arguments.mapIndexed { argumentIndex, argument: IDLArgumentDeclaration ->
|
||||
if (argumentIndex == unionTypedArgumentIndex) {
|
||||
argument.copy(type = unionMember, defaultValue = null, optional = false)
|
||||
} else {
|
||||
argument.copy()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// If union typed argument is optional - create an overload without union argument.
|
||||
if (unionTypedArgument.optional || unionTypedArgument.defaultValue != null) {
|
||||
return result + op.copy(arguments = op.arguments.subList(0, unionTypedArgumentIndex))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun IDLSourceSetDeclaration.addOverloadsForUnions(): IDLSourceSetDeclaration {
|
||||
return UnionParametersOverloadsLowering().lowerSourceSetDeclaration(this)
|
||||
}
|
||||
+8
@@ -50,6 +50,7 @@ import org.jetbrains.dukat.panic.raiseConcern
|
||||
import org.jetbrains.dukat.stdlib.TSLIBROOT
|
||||
import org.jetbrains.dukat.stdlib.isTsStdlibPrefixed
|
||||
import org.jetbrains.dukat.translator.ROOT_PACKAGENAME
|
||||
import org.jetbrains.dukat.translatorString.translate
|
||||
import java.io.File
|
||||
|
||||
private val jsAnyHeritageModel: HeritageModel = HeritageModel(
|
||||
@@ -224,6 +225,13 @@ private class IdlFileConverter(
|
||||
return when (this) {
|
||||
is IDLSingleTypeDeclaration -> convertToModel(isTypeParameter)
|
||||
is IDLFunctionTypeDeclaration -> convertToModel()
|
||||
is IDLUnionTypeDeclaration -> TypeValueModel(
|
||||
IdentifierEntity("JsAny"),
|
||||
listOf(),
|
||||
metaDescription = this.unionMembers.joinToString("|") { it.convertToModel(false).translate() },
|
||||
null,
|
||||
nullable = true,
|
||||
)
|
||||
//there shouldn't be any UnionTypeDeclarations at this stage
|
||||
else -> raiseConcern("unprocessed type declaration: ${this}") {
|
||||
TypeValueModel(
|
||||
|
||||
+3
-7
@@ -98,12 +98,8 @@ private class TypeResolver : IDLLowering {
|
||||
nullable = declaration.nullable,
|
||||
comment = declaration.comment
|
||||
)
|
||||
in failedToResolveUnionTypes -> IDLSingleTypeDeclaration(
|
||||
name = "\$dynamic",
|
||||
typeParameter = null,
|
||||
nullable = false,
|
||||
comment = declaration.comment
|
||||
)
|
||||
// Keeping unresolved union types as-is to process later
|
||||
in failedToResolveUnionTypes -> declaration
|
||||
else -> raiseConcern("unprocessed UnionTypeDeclaration: $this") { declaration }
|
||||
}
|
||||
}
|
||||
@@ -203,7 +199,7 @@ private class DependencyResolver(val typeResolver: TypeResolver) : IDLLowering {
|
||||
}
|
||||
}
|
||||
|
||||
fun IDLSourceSetDeclaration.resolveTypes(): IDLSourceSetDeclaration {
|
||||
fun IDLSourceSetDeclaration.resolveTypesKeepingUnions(): IDLSourceSetDeclaration {
|
||||
val typeResolver = TypeResolver()
|
||||
val dependencyResolver = DependencyResolver(typeResolver)
|
||||
val declarationAdder = DeclarationAdder(typeResolver)
|
||||
|
||||
+2
-1
@@ -27,7 +27,8 @@ fun translateIdlToSourceSet(fileName: String): SourceSetModel {
|
||||
.resolveImplementsStatements()
|
||||
.resolveMixins()
|
||||
.addItemArrayLike()
|
||||
.resolveTypes()
|
||||
.resolveTypesKeepingUnions()
|
||||
.addOverloadsForUnions()
|
||||
.markAbstractOrOpen()
|
||||
.addMissingMembers()
|
||||
.addOverloadsForCallbacks()
|
||||
|
||||
Reference in New Issue
Block a user