Support named constructors in idl-backed code generation
this resolves https://youtrack.jetbrains.com/issue/KT-27361
This commit is contained in:
@@ -647,6 +647,108 @@ public external abstract class HTMLImageElement : HTMLElement, TexImageSource, H
|
||||
open val y: Int
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the JavaScript [Image](https://developer.mozilla.org/en/docs/Web/API/Image) to Kotlin
|
||||
*/
|
||||
public external open class Image(width: Int = definedExternally, height: Int = definedExternally) : HTMLImageElement {
|
||||
override val children: HTMLCollection
|
||||
override val firstElementChild: Element?
|
||||
override val lastElementChild: Element?
|
||||
override val childElementCount: Int
|
||||
override val previousElementSibling: Element?
|
||||
override val nextElementSibling: Element?
|
||||
override val assignedSlot: HTMLSlotElement?
|
||||
override val style: CSSStyleDeclaration
|
||||
override var ongotpointercapture: ((PointerEvent) -> dynamic)?
|
||||
override var onlostpointercapture: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerdown: ((PointerEvent) -> dynamic)?
|
||||
override var onpointermove: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerup: ((PointerEvent) -> dynamic)?
|
||||
override var onpointercancel: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerover: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerout: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerenter: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerleave: ((PointerEvent) -> dynamic)?
|
||||
override var onabort: ((Event) -> dynamic)?
|
||||
override var onblur: ((FocusEvent) -> dynamic)?
|
||||
override var oncancel: ((Event) -> dynamic)?
|
||||
override var oncanplay: ((Event) -> dynamic)?
|
||||
override var oncanplaythrough: ((Event) -> dynamic)?
|
||||
override var onchange: ((Event) -> dynamic)?
|
||||
override var onclick: ((MouseEvent) -> dynamic)?
|
||||
override var onclose: ((Event) -> dynamic)?
|
||||
override var oncontextmenu: ((MouseEvent) -> dynamic)?
|
||||
override var oncuechange: ((Event) -> dynamic)?
|
||||
override var ondblclick: ((MouseEvent) -> dynamic)?
|
||||
override var ondrag: ((DragEvent) -> dynamic)?
|
||||
override var ondragend: ((DragEvent) -> dynamic)?
|
||||
override var ondragenter: ((DragEvent) -> dynamic)?
|
||||
override var ondragexit: ((DragEvent) -> dynamic)?
|
||||
override var ondragleave: ((DragEvent) -> dynamic)?
|
||||
override var ondragover: ((DragEvent) -> dynamic)?
|
||||
override var ondragstart: ((DragEvent) -> dynamic)?
|
||||
override var ondrop: ((DragEvent) -> dynamic)?
|
||||
override var ondurationchange: ((Event) -> dynamic)?
|
||||
override var onemptied: ((Event) -> dynamic)?
|
||||
override var onended: ((Event) -> dynamic)?
|
||||
override var onerror: ((dynamic, String, Int, Int, Any?) -> dynamic)?
|
||||
override var onfocus: ((FocusEvent) -> dynamic)?
|
||||
override var oninput: ((InputEvent) -> dynamic)?
|
||||
override var oninvalid: ((Event) -> dynamic)?
|
||||
override var onkeydown: ((KeyboardEvent) -> dynamic)?
|
||||
override var onkeypress: ((KeyboardEvent) -> dynamic)?
|
||||
override var onkeyup: ((KeyboardEvent) -> dynamic)?
|
||||
override var onload: ((Event) -> dynamic)?
|
||||
override var onloadeddata: ((Event) -> dynamic)?
|
||||
override var onloadedmetadata: ((Event) -> dynamic)?
|
||||
override var onloadend: ((Event) -> dynamic)?
|
||||
override var onloadstart: ((ProgressEvent) -> dynamic)?
|
||||
override var onmousedown: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseenter: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseleave: ((MouseEvent) -> dynamic)?
|
||||
override var onmousemove: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseout: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseover: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseup: ((MouseEvent) -> dynamic)?
|
||||
override var onwheel: ((WheelEvent) -> dynamic)?
|
||||
override var onpause: ((Event) -> dynamic)?
|
||||
override var onplay: ((Event) -> dynamic)?
|
||||
override var onplaying: ((Event) -> dynamic)?
|
||||
override var onprogress: ((ProgressEvent) -> dynamic)?
|
||||
override var onratechange: ((Event) -> dynamic)?
|
||||
override var onreset: ((Event) -> dynamic)?
|
||||
override var onresize: ((Event) -> dynamic)?
|
||||
override var onscroll: ((Event) -> dynamic)?
|
||||
override var onseeked: ((Event) -> dynamic)?
|
||||
override var onseeking: ((Event) -> dynamic)?
|
||||
override var onselect: ((Event) -> dynamic)?
|
||||
override var onshow: ((Event) -> dynamic)?
|
||||
override var onstalled: ((Event) -> dynamic)?
|
||||
override var onsubmit: ((Event) -> dynamic)?
|
||||
override var onsuspend: ((Event) -> dynamic)?
|
||||
override var ontimeupdate: ((Event) -> dynamic)?
|
||||
override var ontoggle: ((Event) -> dynamic)?
|
||||
override var onvolumechange: ((Event) -> dynamic)?
|
||||
override var onwaiting: ((Event) -> dynamic)?
|
||||
override var oncopy: ((ClipboardEvent) -> dynamic)?
|
||||
override var oncut: ((ClipboardEvent) -> dynamic)?
|
||||
override var onpaste: ((ClipboardEvent) -> dynamic)?
|
||||
override var contentEditable: String
|
||||
override val isContentEditable: Boolean
|
||||
override fun prepend(vararg nodes: dynamic): Unit
|
||||
override fun append(vararg nodes: dynamic): Unit
|
||||
override fun querySelector(selectors: String): Element?
|
||||
override fun querySelectorAll(selectors: String): NodeList
|
||||
override fun before(vararg nodes: dynamic): Unit
|
||||
override fun after(vararg nodes: dynamic): Unit
|
||||
override fun replaceWith(vararg nodes: dynamic): Unit
|
||||
override fun remove(): Unit
|
||||
override fun getBoxQuads(options: BoxQuadOptions /* = definedExternally */): Array<DOMQuad>
|
||||
override fun convertQuadFromNode(quad: dynamic, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMQuad
|
||||
override fun convertRectFromNode(rect: DOMRectReadOnly, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMQuad
|
||||
override fun convertPointFromNode(point: DOMPointInit, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMPoint
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the JavaScript [HTMLIFrameElement](https://developer.mozilla.org/en/docs/Web/API/HTMLIFrameElement) to Kotlin
|
||||
*/
|
||||
@@ -745,6 +847,105 @@ public external abstract class HTMLVideoElement : HTMLMediaElement, TexImageSour
|
||||
public external abstract class HTMLAudioElement : HTMLMediaElement {
|
||||
}
|
||||
|
||||
public external open class Audio(src: String = definedExternally) : HTMLAudioElement {
|
||||
override val children: HTMLCollection
|
||||
override val firstElementChild: Element?
|
||||
override val lastElementChild: Element?
|
||||
override val childElementCount: Int
|
||||
override val previousElementSibling: Element?
|
||||
override val nextElementSibling: Element?
|
||||
override val assignedSlot: HTMLSlotElement?
|
||||
override val style: CSSStyleDeclaration
|
||||
override var ongotpointercapture: ((PointerEvent) -> dynamic)?
|
||||
override var onlostpointercapture: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerdown: ((PointerEvent) -> dynamic)?
|
||||
override var onpointermove: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerup: ((PointerEvent) -> dynamic)?
|
||||
override var onpointercancel: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerover: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerout: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerenter: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerleave: ((PointerEvent) -> dynamic)?
|
||||
override var onabort: ((Event) -> dynamic)?
|
||||
override var onblur: ((FocusEvent) -> dynamic)?
|
||||
override var oncancel: ((Event) -> dynamic)?
|
||||
override var oncanplay: ((Event) -> dynamic)?
|
||||
override var oncanplaythrough: ((Event) -> dynamic)?
|
||||
override var onchange: ((Event) -> dynamic)?
|
||||
override var onclick: ((MouseEvent) -> dynamic)?
|
||||
override var onclose: ((Event) -> dynamic)?
|
||||
override var oncontextmenu: ((MouseEvent) -> dynamic)?
|
||||
override var oncuechange: ((Event) -> dynamic)?
|
||||
override var ondblclick: ((MouseEvent) -> dynamic)?
|
||||
override var ondrag: ((DragEvent) -> dynamic)?
|
||||
override var ondragend: ((DragEvent) -> dynamic)?
|
||||
override var ondragenter: ((DragEvent) -> dynamic)?
|
||||
override var ondragexit: ((DragEvent) -> dynamic)?
|
||||
override var ondragleave: ((DragEvent) -> dynamic)?
|
||||
override var ondragover: ((DragEvent) -> dynamic)?
|
||||
override var ondragstart: ((DragEvent) -> dynamic)?
|
||||
override var ondrop: ((DragEvent) -> dynamic)?
|
||||
override var ondurationchange: ((Event) -> dynamic)?
|
||||
override var onemptied: ((Event) -> dynamic)?
|
||||
override var onended: ((Event) -> dynamic)?
|
||||
override var onerror: ((dynamic, String, Int, Int, Any?) -> dynamic)?
|
||||
override var onfocus: ((FocusEvent) -> dynamic)?
|
||||
override var oninput: ((InputEvent) -> dynamic)?
|
||||
override var oninvalid: ((Event) -> dynamic)?
|
||||
override var onkeydown: ((KeyboardEvent) -> dynamic)?
|
||||
override var onkeypress: ((KeyboardEvent) -> dynamic)?
|
||||
override var onkeyup: ((KeyboardEvent) -> dynamic)?
|
||||
override var onload: ((Event) -> dynamic)?
|
||||
override var onloadeddata: ((Event) -> dynamic)?
|
||||
override var onloadedmetadata: ((Event) -> dynamic)?
|
||||
override var onloadend: ((Event) -> dynamic)?
|
||||
override var onloadstart: ((ProgressEvent) -> dynamic)?
|
||||
override var onmousedown: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseenter: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseleave: ((MouseEvent) -> dynamic)?
|
||||
override var onmousemove: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseout: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseover: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseup: ((MouseEvent) -> dynamic)?
|
||||
override var onwheel: ((WheelEvent) -> dynamic)?
|
||||
override var onpause: ((Event) -> dynamic)?
|
||||
override var onplay: ((Event) -> dynamic)?
|
||||
override var onplaying: ((Event) -> dynamic)?
|
||||
override var onprogress: ((ProgressEvent) -> dynamic)?
|
||||
override var onratechange: ((Event) -> dynamic)?
|
||||
override var onreset: ((Event) -> dynamic)?
|
||||
override var onresize: ((Event) -> dynamic)?
|
||||
override var onscroll: ((Event) -> dynamic)?
|
||||
override var onseeked: ((Event) -> dynamic)?
|
||||
override var onseeking: ((Event) -> dynamic)?
|
||||
override var onselect: ((Event) -> dynamic)?
|
||||
override var onshow: ((Event) -> dynamic)?
|
||||
override var onstalled: ((Event) -> dynamic)?
|
||||
override var onsubmit: ((Event) -> dynamic)?
|
||||
override var onsuspend: ((Event) -> dynamic)?
|
||||
override var ontimeupdate: ((Event) -> dynamic)?
|
||||
override var ontoggle: ((Event) -> dynamic)?
|
||||
override var onvolumechange: ((Event) -> dynamic)?
|
||||
override var onwaiting: ((Event) -> dynamic)?
|
||||
override var oncopy: ((ClipboardEvent) -> dynamic)?
|
||||
override var oncut: ((ClipboardEvent) -> dynamic)?
|
||||
override var onpaste: ((ClipboardEvent) -> dynamic)?
|
||||
override var contentEditable: String
|
||||
override val isContentEditable: Boolean
|
||||
override fun prepend(vararg nodes: dynamic): Unit
|
||||
override fun append(vararg nodes: dynamic): Unit
|
||||
override fun querySelector(selectors: String): Element?
|
||||
override fun querySelectorAll(selectors: String): NodeList
|
||||
override fun before(vararg nodes: dynamic): Unit
|
||||
override fun after(vararg nodes: dynamic): Unit
|
||||
override fun replaceWith(vararg nodes: dynamic): Unit
|
||||
override fun remove(): Unit
|
||||
override fun getBoxQuads(options: BoxQuadOptions /* = definedExternally */): Array<DOMQuad>
|
||||
override fun convertQuadFromNode(quad: dynamic, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMQuad
|
||||
override fun convertRectFromNode(rect: DOMRectReadOnly, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMQuad
|
||||
override fun convertPointFromNode(point: DOMPointInit, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMPoint
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the JavaScript [HTMLTrackElement](https://developer.mozilla.org/en/docs/Web/API/HTMLTrackElement) to Kotlin
|
||||
*/
|
||||
@@ -1260,6 +1461,108 @@ public external abstract class HTMLOptionElement : HTMLElement, UnionHTMLOptGrou
|
||||
open val index: Int
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the JavaScript [Option](https://developer.mozilla.org/en/docs/Web/API/Option) to Kotlin
|
||||
*/
|
||||
public external open class Option(text: String = definedExternally, value: String = definedExternally, defaultSelected: Boolean = definedExternally, selected: Boolean = definedExternally) : HTMLOptionElement {
|
||||
override val children: HTMLCollection
|
||||
override val firstElementChild: Element?
|
||||
override val lastElementChild: Element?
|
||||
override val childElementCount: Int
|
||||
override val previousElementSibling: Element?
|
||||
override val nextElementSibling: Element?
|
||||
override val assignedSlot: HTMLSlotElement?
|
||||
override val style: CSSStyleDeclaration
|
||||
override var ongotpointercapture: ((PointerEvent) -> dynamic)?
|
||||
override var onlostpointercapture: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerdown: ((PointerEvent) -> dynamic)?
|
||||
override var onpointermove: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerup: ((PointerEvent) -> dynamic)?
|
||||
override var onpointercancel: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerover: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerout: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerenter: ((PointerEvent) -> dynamic)?
|
||||
override var onpointerleave: ((PointerEvent) -> dynamic)?
|
||||
override var onabort: ((Event) -> dynamic)?
|
||||
override var onblur: ((FocusEvent) -> dynamic)?
|
||||
override var oncancel: ((Event) -> dynamic)?
|
||||
override var oncanplay: ((Event) -> dynamic)?
|
||||
override var oncanplaythrough: ((Event) -> dynamic)?
|
||||
override var onchange: ((Event) -> dynamic)?
|
||||
override var onclick: ((MouseEvent) -> dynamic)?
|
||||
override var onclose: ((Event) -> dynamic)?
|
||||
override var oncontextmenu: ((MouseEvent) -> dynamic)?
|
||||
override var oncuechange: ((Event) -> dynamic)?
|
||||
override var ondblclick: ((MouseEvent) -> dynamic)?
|
||||
override var ondrag: ((DragEvent) -> dynamic)?
|
||||
override var ondragend: ((DragEvent) -> dynamic)?
|
||||
override var ondragenter: ((DragEvent) -> dynamic)?
|
||||
override var ondragexit: ((DragEvent) -> dynamic)?
|
||||
override var ondragleave: ((DragEvent) -> dynamic)?
|
||||
override var ondragover: ((DragEvent) -> dynamic)?
|
||||
override var ondragstart: ((DragEvent) -> dynamic)?
|
||||
override var ondrop: ((DragEvent) -> dynamic)?
|
||||
override var ondurationchange: ((Event) -> dynamic)?
|
||||
override var onemptied: ((Event) -> dynamic)?
|
||||
override var onended: ((Event) -> dynamic)?
|
||||
override var onerror: ((dynamic, String, Int, Int, Any?) -> dynamic)?
|
||||
override var onfocus: ((FocusEvent) -> dynamic)?
|
||||
override var oninput: ((InputEvent) -> dynamic)?
|
||||
override var oninvalid: ((Event) -> dynamic)?
|
||||
override var onkeydown: ((KeyboardEvent) -> dynamic)?
|
||||
override var onkeypress: ((KeyboardEvent) -> dynamic)?
|
||||
override var onkeyup: ((KeyboardEvent) -> dynamic)?
|
||||
override var onload: ((Event) -> dynamic)?
|
||||
override var onloadeddata: ((Event) -> dynamic)?
|
||||
override var onloadedmetadata: ((Event) -> dynamic)?
|
||||
override var onloadend: ((Event) -> dynamic)?
|
||||
override var onloadstart: ((ProgressEvent) -> dynamic)?
|
||||
override var onmousedown: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseenter: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseleave: ((MouseEvent) -> dynamic)?
|
||||
override var onmousemove: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseout: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseover: ((MouseEvent) -> dynamic)?
|
||||
override var onmouseup: ((MouseEvent) -> dynamic)?
|
||||
override var onwheel: ((WheelEvent) -> dynamic)?
|
||||
override var onpause: ((Event) -> dynamic)?
|
||||
override var onplay: ((Event) -> dynamic)?
|
||||
override var onplaying: ((Event) -> dynamic)?
|
||||
override var onprogress: ((ProgressEvent) -> dynamic)?
|
||||
override var onratechange: ((Event) -> dynamic)?
|
||||
override var onreset: ((Event) -> dynamic)?
|
||||
override var onresize: ((Event) -> dynamic)?
|
||||
override var onscroll: ((Event) -> dynamic)?
|
||||
override var onseeked: ((Event) -> dynamic)?
|
||||
override var onseeking: ((Event) -> dynamic)?
|
||||
override var onselect: ((Event) -> dynamic)?
|
||||
override var onshow: ((Event) -> dynamic)?
|
||||
override var onstalled: ((Event) -> dynamic)?
|
||||
override var onsubmit: ((Event) -> dynamic)?
|
||||
override var onsuspend: ((Event) -> dynamic)?
|
||||
override var ontimeupdate: ((Event) -> dynamic)?
|
||||
override var ontoggle: ((Event) -> dynamic)?
|
||||
override var onvolumechange: ((Event) -> dynamic)?
|
||||
override var onwaiting: ((Event) -> dynamic)?
|
||||
override var oncopy: ((ClipboardEvent) -> dynamic)?
|
||||
override var oncut: ((ClipboardEvent) -> dynamic)?
|
||||
override var onpaste: ((ClipboardEvent) -> dynamic)?
|
||||
override var contentEditable: String
|
||||
override val isContentEditable: Boolean
|
||||
override fun prepend(vararg nodes: dynamic): Unit
|
||||
override fun append(vararg nodes: dynamic): Unit
|
||||
override fun querySelector(selectors: String): Element?
|
||||
override fun querySelectorAll(selectors: String): NodeList
|
||||
override fun before(vararg nodes: dynamic): Unit
|
||||
override fun after(vararg nodes: dynamic): Unit
|
||||
override fun replaceWith(vararg nodes: dynamic): Unit
|
||||
override fun remove(): Unit
|
||||
override fun getBoxQuads(options: BoxQuadOptions /* = definedExternally */): Array<DOMQuad>
|
||||
override fun convertQuadFromNode(quad: dynamic, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMQuad
|
||||
override fun convertRectFromNode(rect: DOMRectReadOnly, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMQuad
|
||||
override fun convertPointFromNode(point: DOMPointInit, from: dynamic, options: ConvertCoordinateOptions /* = definedExternally */): DOMPoint
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the JavaScript [HTMLTextAreaElement](https://developer.mozilla.org/en/docs/Web/API/HTMLTextAreaElement) to Kotlin
|
||||
*/
|
||||
|
||||
@@ -85,15 +85,15 @@ val inheritanceExclude = mapOf(
|
||||
)
|
||||
|
||||
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(
|
||||
"ItemArrayLike" to GenerateClass("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()
|
||||
constants = emptyList(),
|
||||
generateBuilderFunction = false,
|
||||
primaryConstructor = null,
|
||||
secondaryConstructors = emptyList()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -107,15 +107,23 @@ fun generateAttribute(putNoImpl: Boolean, repository: Repository, attribute: Att
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun InterfaceDefinition.isInterface() : Boolean {
|
||||
return when {
|
||||
dictionary -> true
|
||||
extendedAttributes.any { it.call == "NoInterfaceObject" } -> true
|
||||
callback -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
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 =
|
||||
when {
|
||||
iface.dictionary -> GenerateDefinitionKind.INTERFACE
|
||||
iface.extendedAttributes.any { it.call == "NoInterfaceObject" } -> GenerateDefinitionKind.INTERFACE
|
||||
iface.isInterface() -> GenerateDefinitionKind.INTERFACE
|
||||
constructors.isNotEmpty() || iface.superTypes(repository).any { resolveDefinitionKind(repository, it) == GenerateDefinitionKind.CLASS } -> {
|
||||
GenerateDefinitionKind.CLASS
|
||||
}
|
||||
iface.callback -> GenerateDefinitionKind.INTERFACE
|
||||
else -> GenerateDefinitionKind.ABSTRACT_CLASS
|
||||
}
|
||||
|
||||
@@ -125,7 +133,7 @@ private fun InterfaceDefinition.mapOperations(repository: Repository) = operatio
|
||||
private fun Constant.mapConstant(repository : Repository) = GenerateAttribute(name, mapType(repository, type), null, false, AttributeKind.VAL, false, false, true, false)
|
||||
private val EMPTY_CONSTRUCTOR = ExtendedAttribute(null, "Constructor", emptyList())
|
||||
|
||||
fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateTraitOrClass {
|
||||
fun generateTrait(repository: Repository, iface: InterfaceDefinition): List<GenerateClass> {
|
||||
val superClasses = iface.superTypes
|
||||
.mapNotNull { repository.interfaces[it] }
|
||||
.filter {
|
||||
@@ -161,19 +169,38 @@ fun generateTrait(repository: Repository, iface: InterfaceDefinition): GenerateT
|
||||
ConstructorWithSuperTypeCall(constructorAsFunction, secondaryConstructor)
|
||||
}
|
||||
|
||||
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()),
|
||||
primaryConstructor = primaryConstructorWithCall,
|
||||
secondaryConstructors = secondaryConstructorsWithCall,
|
||||
generateBuilderFunction = iface.dictionary
|
||||
)
|
||||
val memberAttributes = iface.mapAttributes(repository)
|
||||
val memberFunctions = iface.mapOperations(repository)
|
||||
|
||||
return markAsArrayLikeIfApplicable(result)
|
||||
val extensionsNames = extensions.map { it.name }
|
||||
|
||||
val namedConstructors =
|
||||
iface.findExtendedAttributes("NamedConstructor").map { namedConstructor ->
|
||||
GenerateClass(
|
||||
name = namedConstructor.call,
|
||||
namespace = iface.namespace,
|
||||
kind = GenerateDefinitionKind.CLASS,
|
||||
superTypes = listOf(iface.name) + extensionsNames,
|
||||
memberAttributes = memberAttributes.toMutableList(),
|
||||
memberFunctions = memberFunctions.toMutableList(),
|
||||
constants = emptyList(),
|
||||
primaryConstructor = ConstructorWithSuperTypeCall(generateConstructorAsFunction(repository, namedConstructor), namedConstructor),
|
||||
secondaryConstructors = emptyList(),
|
||||
generateBuilderFunction = false
|
||||
)
|
||||
}
|
||||
|
||||
return (listOf(GenerateClass(iface.name, iface.namespace, entityKind, (iface.superTypes + extensionsNames).distinct(),
|
||||
memberAttributes = memberAttributes.toMutableList(),
|
||||
memberFunctions = memberFunctions.toMutableList(),
|
||||
constants = (iface.constants.map { it.mapConstant(repository) } + extensions.flatMap { it.constants.map { it.mapConstant(repository) } }.distinct().toList()),
|
||||
primaryConstructor = primaryConstructorWithCall,
|
||||
secondaryConstructors = secondaryConstructorsWithCall,
|
||||
generateBuilderFunction = iface.dictionary
|
||||
)) + namedConstructors).map(::markAsArrayLikeIfApplicable)
|
||||
}
|
||||
|
||||
fun markAsArrayLikeIfApplicable(iface: GenerateTraitOrClass): GenerateTraitOrClass {
|
||||
fun markAsArrayLikeIfApplicable(iface: GenerateClass): GenerateClass {
|
||||
fun isInt(type: Type) = type is SimpleType && type.type == "Int"
|
||||
|
||||
val lengthProperty = iface.memberAttributes.singleOrNull { it.name == "length" && isInt(it.type) }
|
||||
@@ -191,7 +218,7 @@ fun generateConstructorAsFunction(repository: Repository, constructor: ExtendedA
|
||||
nativeGetterOrSetter = NativeGetterOrSetter.NONE)
|
||||
|
||||
|
||||
fun mapUnionType(it: UnionType) = GenerateTraitOrClass(
|
||||
fun mapUnionType(it: UnionType) = GenerateClass(
|
||||
name = it.name,
|
||||
namespace = it.namespace,
|
||||
kind = GenerateDefinitionKind.INTERFACE,
|
||||
@@ -204,12 +231,12 @@ fun mapUnionType(it: UnionType) = GenerateTraitOrClass(
|
||||
generateBuilderFunction = false
|
||||
)
|
||||
|
||||
fun generateUnionTypeTraits(allUnionTypes: Sequence<UnionType>): Sequence<GenerateTraitOrClass> = allUnionTypes.map(::mapUnionType)
|
||||
fun generateUnionTypeTraits(allUnionTypes: Sequence<UnionType>): Sequence<GenerateClass> = allUnionTypes.map(::mapUnionType)
|
||||
|
||||
fun mapDefinitions(repository: Repository, definitions: Iterable<InterfaceDefinition>) =
|
||||
definitions.map { generateTrait(repository, it) }
|
||||
definitions.flatMap { generateTrait(repository, it) }
|
||||
|
||||
fun generateUnions(ifaces: List<GenerateTraitOrClass>, typedefs: Iterable<TypedefDefinition>): GenerateUnionTypes {
|
||||
fun generateUnions(ifaces: List<GenerateClass>, typedefs: Iterable<TypedefDefinition>): GenerateUnionTypes {
|
||||
val declaredTypes = ifaces.associateBy { it.name }
|
||||
|
||||
val anonymousUnionTypes = collectUnionTypes(declaredTypes)
|
||||
@@ -259,8 +286,7 @@ private fun mapLiteral(literal: String?, expectedType: Type = DynamicType, enums
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun specifyType(name: String, type: Type, context: String): Type {
|
||||
private fun specifyType(name: String, type: Type, context: String): Type {
|
||||
|
||||
if ((type is SimpleType) && (type.type == "Event")) {
|
||||
(eventSpecifierMapper[name] ?: eventSpecifierMapperWithContext[EventMapKey(name, context)])?.let {
|
||||
@@ -279,7 +305,7 @@ private fun generalizeType(name: String, type: Type, context: String): Type {
|
||||
return type
|
||||
}
|
||||
|
||||
fun implementInterfaces(declarations: List<GenerateTraitOrClass>) : List<GenerateTraitOrClass> {
|
||||
fun implementInterfaces(declarations: List<GenerateClass>) : List<GenerateClass> {
|
||||
val unimplementedMemberMap = getUnimplementedMembers(declarations)
|
||||
val nonAbstractDeclarations = declarations.filter { it.kind == GenerateDefinitionKind.CLASS }
|
||||
for (declaration in nonAbstractDeclarations) {
|
||||
@@ -301,7 +327,7 @@ fun implementInterfaces(declarations: List<GenerateTraitOrClass>) : List<Generat
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUnimplementedMembers(declarations: List<GenerateTraitOrClass>): Map<String, UnimplementedMembers> {
|
||||
private fun getUnimplementedMembers(declarations: List<GenerateClass>): Map<String, UnimplementedMembers> {
|
||||
val declarationMap = declarations.associate { it.name to it }
|
||||
val unimplementedMemberCache = mutableMapOf<String, UnimplementedMembers>()
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ enum class GenerateDefinitionKind {
|
||||
ABSTRACT_CLASS
|
||||
}
|
||||
|
||||
data class GenerateFunctionCall(val name: String, val arguments: List<String>)
|
||||
data class GenerateFunction(
|
||||
val name: String,
|
||||
val returnType: Type,
|
||||
@@ -74,17 +73,18 @@ data class GenerateFunction(
|
||||
)
|
||||
|
||||
data class ConstructorWithSuperTypeCall(val constructor: GenerateFunction, val constructorAttribute: ExtendedAttribute)
|
||||
data class GenerateTraitOrClass(
|
||||
val name: String,
|
||||
val namespace: String,
|
||||
val kind: GenerateDefinitionKind,
|
||||
val superTypes: List<String>,
|
||||
val memberAttributes: MutableList<GenerateAttribute>,
|
||||
val memberFunctions: MutableList<GenerateFunction>,
|
||||
val constants: List<GenerateAttribute>,
|
||||
val primaryConstructor: ConstructorWithSuperTypeCall?,
|
||||
val secondaryConstructors: List<ConstructorWithSuperTypeCall>,
|
||||
val generateBuilderFunction: Boolean
|
||||
|
||||
data class GenerateClass(
|
||||
val name: String,
|
||||
val namespace: String,
|
||||
val kind: GenerateDefinitionKind,
|
||||
val superTypes: List<String>,
|
||||
val memberAttributes: MutableList<GenerateAttribute>,
|
||||
val memberFunctions: MutableList<GenerateFunction>,
|
||||
val constants: List<GenerateAttribute>,
|
||||
val primaryConstructor: ConstructorWithSuperTypeCall?,
|
||||
val secondaryConstructors: List<ConstructorWithSuperTypeCall>,
|
||||
val generateBuilderFunction: Boolean
|
||||
)
|
||||
|
||||
val GenerateFunction.signature: String
|
||||
@@ -94,12 +94,11 @@ fun GenerateFunction.dynamicIfUnknownType(allTypes : Set<String>) = standardType
|
||||
copy(returnType = returnType.dynamicIfUnknownType(allTypes, standardTypes), arguments = arguments.map { it.dynamicIfUnknownType(allTypes, standardTypes) })
|
||||
}
|
||||
|
||||
fun InterfaceDefinition.findExtendedAttributes(name: String) = extendedAttributes.filter { it.call == name }
|
||||
fun InterfaceDefinition?.hasExtendedAttribute(name: String) = this?.findExtendedAttributes(name)?.isNotEmpty() ?: false
|
||||
fun InterfaceDefinition.findConstructors() = findExtendedAttributes("Constructor")
|
||||
fun InterfaceDefinition.findExtendedAttributes(name: String) = extendedAttributes.filter { it.name == name }
|
||||
fun InterfaceDefinition.findConstructors() = extendedAttributes.filter { it.call == "Constructor" }
|
||||
|
||||
data class GenerateUnionTypes(
|
||||
val typeNamesToUnionsMap: Map<String, List<String>>,
|
||||
val anonymousUnionsMap: Map<String, GenerateTraitOrClass>,
|
||||
val typedefsMarkersMap: Map<String, GenerateTraitOrClass>
|
||||
val typeNamesToUnionsMap: Map<String, List<String>>,
|
||||
val anonymousUnionsMap: Map<String, GenerateClass>,
|
||||
val typedefsMarkersMap: Map<String, GenerateClass>
|
||||
)
|
||||
|
||||
@@ -100,8 +100,6 @@ private fun Appendable.renderArgumentsDeclaration(args: List<GenerateAttribute>,
|
||||
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 Appendable.renderFunctionDeclaration(owner: String, f: GenerateFunction, override: Boolean, commented: Boolean, level: Int = 1) {
|
||||
indent(commented, level)
|
||||
|
||||
@@ -147,7 +145,8 @@ private fun GenerateFunction.isCommented(parent: String) =
|
||||
private fun GenerateAttribute.isRequiredFunctionArgument(owner: String, functionName: String) = "$owner.$functionName.$name" in requiredArguments
|
||||
private fun GenerateFunction.fixRequiredArguments(parent: String) = copy(arguments = arguments.map { arg -> arg.copy(initializer = if (arg.isRequiredFunctionArgument(parent, name)) null else arg.initializer) })
|
||||
|
||||
fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, enums: List<EnumDefinition>, typeNamesToUnions: Map<String, List<String>>, iface: GenerateTraitOrClass, markerAnnotation: Boolean = false, mdnCache: MDNDocumentationCache? = null) {
|
||||
fun Appendable.render(allTypes: Map<String, GenerateClass>, enums: List<EnumDefinition>, typeNamesToUnions: Map<String, List<String>>, iface: GenerateClass, markerAnnotation: Boolean = false, mdnCache: MDNDocumentationCache? = null) {
|
||||
|
||||
val url = "https://developer.mozilla.org/en/docs/Web/API/${iface.name}"
|
||||
if (mdnCache?.checkInCache(url) == true) {
|
||||
appendln("/**")
|
||||
@@ -182,6 +181,7 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, enums: List<E
|
||||
(typeNamesToUnions[iface.name] ?: emptyList()) +
|
||||
(iface.superTypes.filter { it.substringBefore("<") in kotlinBuiltinInterfaces }) // TODO in theory we have to parse type but for now it is the only place needs it so let's just cut string
|
||||
|
||||
|
||||
if (superTypesWithCalls.isNotEmpty()) {
|
||||
superTypesWithCalls.joinTo(this, ", ", " : ")
|
||||
}
|
||||
@@ -218,6 +218,10 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, enums: List<E
|
||||
else -> MemberModality.FINAL
|
||||
}
|
||||
|
||||
val skipAttributeDeclaration = modality == MemberModality.OVERRIDE
|
||||
&& attribute.kindNotChanged(superAttributesByName)
|
||||
&& (iface.kind == GenerateDefinitionKind.INTERFACE || attribute.hasSuperImplementation(allSuperTypes))
|
||||
|
||||
if (attribute.name in superAttributesByName && attribute.signature !in superSignatures) {
|
||||
System.err.println("Property ${iface.name}.${attribute.name} has different type in super type(s) so will not be generated: ")
|
||||
for ((superTypeName, attributes) in allSuperTypes.map { it.name to it.memberAttributes.filter { it.name == attribute.name }.distinct() }) {
|
||||
@@ -225,10 +229,7 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, enums: List<E
|
||||
System.err.println(" $superTypeName.${attribute.name}: ${superAttribute.type.render()}")
|
||||
}
|
||||
}
|
||||
} else if (modality == MemberModality.OVERRIDE
|
||||
&& attribute.kindNotChanged(superAttributesByName)
|
||||
&& (iface.kind == GenerateDefinitionKind.INTERFACE || attribute.hasSuperImplementation(allSuperTypes))
|
||||
) {
|
||||
} else if (skipAttributeDeclaration) {
|
||||
// then don't generate
|
||||
} else {
|
||||
renderAttributeDeclarationAsProperty(attribute,
|
||||
@@ -239,8 +240,9 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, enums: List<E
|
||||
)
|
||||
}
|
||||
}
|
||||
val memberFunctions = iface.memberFunctions.filter { (it !in superFunctions || it.override) && !it.static }
|
||||
.map { it.dynamicIfUnknownType(allTypesAndEnums) }.groupBy { it.signature }.reduceValues(::betterFunction).values
|
||||
val memberFunctions= iface.memberFunctions.filter {
|
||||
(it !in superFunctions || it.override) && !it.static
|
||||
}.map { it.dynamicIfUnknownType(allTypesAndEnums) }.groupBy { it.signature }.reduceValues(::betterFunction).values
|
||||
|
||||
fun doRenderFunction(function: GenerateFunction, level: Int = 1) {
|
||||
renderFunctionDeclaration(
|
||||
@@ -284,12 +286,12 @@ fun Appendable.render(allTypes: Map<String, GenerateTraitOrClass>, enums: List<E
|
||||
|
||||
private fun GenerateAttribute.kindNotChanged(superAttributesByName: Map<String, List<GenerateAttribute>>) = superAttributesByName[name].orEmpty().all { it.kind == kind }
|
||||
|
||||
private fun GenerateAttribute.hasSuperImplementation(allSuperTypes: List<GenerateTraitOrClass>) = allSuperTypes.any { st -> st.kind != GenerateDefinitionKind.INTERFACE && st.memberAttributes.any { it.signature == signature } }
|
||||
private fun GenerateAttribute.hasSuperImplementation(allSuperTypes: List<GenerateClass>) = allSuperTypes.any { st -> st.kind != GenerateDefinitionKind.INTERFACE && st.memberAttributes.any { it.signature == signature } }
|
||||
|
||||
private fun GenerateAttribute.hasNoDefaultValue() =
|
||||
this.initializer == null && (this.type.nullable || this.type == DynamicType) && !this.required
|
||||
|
||||
fun Appendable.renderBuilderFunction(dictionary: GenerateTraitOrClass, allSuperTypes: List<GenerateTraitOrClass>, allTypes: Set<String>) {
|
||||
fun Appendable.renderBuilderFunction(dictionary: GenerateClass, allSuperTypes: List<GenerateClass>, allTypes: Set<String>) {
|
||||
val fields = (dictionary.memberAttributes + allSuperTypes.flatMap { it.memberAttributes })
|
||||
.distinctBy { it.signature }
|
||||
.map { it.copy(kind = AttributeKind.ARGUMENT) }
|
||||
@@ -397,10 +399,11 @@ fun Appendable.render(enumDefinition: EnumDefinition) {
|
||||
appendln()
|
||||
}
|
||||
|
||||
fun Appendable.render(namespace: String, ifaces: List<GenerateTraitOrClass>, unions: GenerateUnionTypes, enums: List<EnumDefinition>, mdnCache: MDNDocumentationCache) {
|
||||
fun Appendable.render(namespace: String, ifaces: List<GenerateClass>, unions: GenerateUnionTypes, enums: List<EnumDefinition>, mdnCache: MDNDocumentationCache) {
|
||||
val declaredTypes = ifaces.associateBy { it.name }
|
||||
|
||||
val allTypes = declaredTypes + unions.anonymousUnionsMap + unions.typedefsMarkersMap
|
||||
|
||||
declaredTypes.values.filter { it.namespace == namespace }.forEach {
|
||||
render(allTypes, enums, unions.typeNamesToUnionsMap, it, mdnCache = mdnCache)
|
||||
}
|
||||
|
||||
@@ -46,14 +46,9 @@ private val typeMapper = mapOf(
|
||||
)
|
||||
|
||||
|
||||
fun GenerateTraitOrClass.allSuperTypes(all: Map<String, GenerateTraitOrClass>) =
|
||||
LinkedHashSet<GenerateTraitOrClass>().let { result -> allSuperTypesImpl(listOf(this), all, result); result.toList() }
|
||||
fun GenerateClass.allSuperTypes(all: Map<String, GenerateClass>) = LinkedHashSet<GenerateClass>().let { result -> allSuperTypesImpl(listOf(this), all, result); result.toList() }
|
||||
|
||||
tailrec fun allSuperTypesImpl(
|
||||
roots: List<GenerateTraitOrClass>,
|
||||
all: Map<String, GenerateTraitOrClass>,
|
||||
result: MutableSet<GenerateTraitOrClass>
|
||||
) {
|
||||
tailrec fun allSuperTypesImpl(roots: List<GenerateClass>, all: Map<String, GenerateClass>, result: MutableSet<GenerateClass>) {
|
||||
if (roots.isNotEmpty()) {
|
||||
allSuperTypesImpl(roots.flatMap { it.superTypes }.map {
|
||||
all[it] ?: all[it.substringBefore("<")]
|
||||
@@ -132,27 +127,22 @@ private fun mapTypedef(repository: Repository, type: SimpleType): Type {
|
||||
private fun GenerateFunction?.allTypes() =
|
||||
if (this != null) sequenceOf(returnType) + arguments.asSequence().map { it.type } else emptySequence()
|
||||
|
||||
internal fun collectUnionTypes(allTypes: Map<String, GenerateTraitOrClass>) =
|
||||
allTypes.values.asSequence()
|
||||
.flatMap {
|
||||
it.secondaryConstructors.asSequence().flatMap { it.constructor.allTypes() } +
|
||||
internal fun collectUnionTypes(allTypes: Map<String, GenerateClass>) =
|
||||
allTypes.values.asSequence()
|
||||
.flatMap {
|
||||
it.secondaryConstructors.asSequence().flatMap { it.constructor.allTypes() } +
|
||||
sequenceOf(it.primaryConstructor).filterNotNull().flatMap { it.constructor.allTypes() } +
|
||||
it.memberAttributes.asSequence().map { it.type } +
|
||||
it.memberFunctions.asSequence().flatMap { it.allTypes() }
|
||||
}
|
||||
.filterIsInstance<UnionType>()
|
||||
.map { it.dropNullable() }
|
||||
.filter { it.memberTypes.all { unionMember -> unionMember is SimpleType && unionMember.type in allTypes } }
|
||||
.distinct()
|
||||
.map {
|
||||
it.copy(
|
||||
namespace = guessPackage(it.memberTypes.filterIsInstance<SimpleType>().map { it.type }, allTypes),
|
||||
types = it.memberTypes
|
||||
)
|
||||
}
|
||||
it.memberAttributes.asSequence().map { it.type } +
|
||||
it.memberFunctions.asSequence().flatMap { it.allTypes() }
|
||||
}
|
||||
.filterIsInstance<UnionType>()
|
||||
.map { it.dropNullable() }
|
||||
.filter { it.memberTypes.all { unionMember -> unionMember is SimpleType && unionMember.type in allTypes } }
|
||||
.distinct()
|
||||
.map { it.copy(namespace = guessPackage(it.memberTypes.filterIsInstance<SimpleType>().map { it.type }, allTypes), types = it.memberTypes) }
|
||||
|
||||
private fun guessPackage(types: List<String>, allTypes: Map<String, GenerateTraitOrClass>) =
|
||||
types.map { allTypes[it] }
|
||||
private fun guessPackage(types : List<String>, allTypes: Map<String, GenerateClass>) =
|
||||
types.map { allTypes[it] }
|
||||
.map { it?.namespace }
|
||||
.filterNotNull()
|
||||
.filter { it.isNotEmpty() }
|
||||
|
||||
Reference in New Issue
Block a user