Introduce better typing for on[event-name] attributes from idl

see https://upsource.jetbrains.com/kotlin/review/KOTLIN-CR-2548
This commit is contained in:
Shagen Ogandzhanian
2018-12-14 13:13:27 +01:00
parent 8c0ad321e2
commit 714b4f25c0
8 changed files with 285 additions and 170 deletions
+90 -90
View File
@@ -75,62 +75,62 @@ public external open class Document : Node, GlobalEventHandlers, DocumentAndElem
open val documentElement: Element?
open val scrollingElement: Element?
open val styleSheets: StyleSheetList
override var ongotpointercapture: ((Event) -> dynamic)?
override var onlostpointercapture: ((Event) -> dynamic)?
override var onpointerdown: ((Event) -> dynamic)?
override var onpointermove: ((Event) -> dynamic)?
override var onpointerup: ((Event) -> dynamic)?
override var onpointercancel: ((Event) -> dynamic)?
override var onpointerover: ((Event) -> dynamic)?
override var onpointerout: ((Event) -> dynamic)?
override var onpointerenter: ((Event) -> dynamic)?
override var onpointerleave: ((Event) -> dynamic)?
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: ((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: ((Event) -> dynamic)?
override var onclick: ((MouseEvent) -> dynamic)?
override var onclose: ((Event) -> dynamic)?
override var oncontextmenu: ((Event) -> dynamic)?
override var oncontextmenu: ((MouseEvent) -> dynamic)?
override var oncuechange: ((Event) -> dynamic)?
override var ondblclick: ((Event) -> dynamic)?
override var ondrag: ((Event) -> dynamic)?
override var ondragend: ((Event) -> dynamic)?
override var ondragenter: ((Event) -> dynamic)?
override var ondragexit: ((Event) -> dynamic)?
override var ondragleave: ((Event) -> dynamic)?
override var ondragover: ((Event) -> dynamic)?
override var ondragstart: ((Event) -> dynamic)?
override var ondrop: ((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: ((Event) -> dynamic)?
override var oninput: ((Event) -> dynamic)?
override var onfocus: ((FocusEvent) -> dynamic)?
override var oninput: ((InputEvent) -> dynamic)?
override var oninvalid: ((Event) -> dynamic)?
override var onkeydown: ((Event) -> dynamic)?
override var onkeypress: ((Event) -> dynamic)?
override var onkeyup: ((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: ((Event) -> dynamic)?
override var onmousedown: ((Event) -> dynamic)?
override var onmouseenter: ((Event) -> dynamic)?
override var onmouseleave: ((Event) -> dynamic)?
override var onmousemove: ((Event) -> dynamic)?
override var onmouseout: ((Event) -> dynamic)?
override var onmouseover: ((Event) -> dynamic)?
override var onmouseup: ((Event) -> dynamic)?
override var onwheel: ((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: ((Event) -> dynamic)?
override var onprogress: ((ProgressEvent) -> dynamic)?
override var onratechange: ((Event) -> dynamic)?
override var onreset: ((Event) -> dynamic)?
override var onresize: ((Event) -> dynamic)?
@@ -2032,7 +2032,7 @@ public external abstract class ApplicationCache : EventTarget {
open var onerror: ((Event) -> dynamic)?
open var onnoupdate: ((Event) -> dynamic)?
open var ondownloading: ((Event) -> dynamic)?
open var onprogress: ((Event) -> dynamic)?
open var onprogress: ((ProgressEvent) -> dynamic)?
open var onupdateready: ((Event) -> dynamic)?
open var oncached: ((Event) -> dynamic)?
open var onobsolete: ((Event) -> dynamic)?
@@ -2136,62 +2136,62 @@ public inline fun PromiseRejectionEventInit(promise: Promise<Any?>?, reason: Any
* Exposes the JavaScript [GlobalEventHandlers](https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers) to Kotlin
*/
public external interface GlobalEventHandlers {
var ongotpointercapture: ((Event) -> dynamic)?
var onlostpointercapture: ((Event) -> dynamic)?
var onpointerdown: ((Event) -> dynamic)?
var onpointermove: ((Event) -> dynamic)?
var onpointerup: ((Event) -> dynamic)?
var onpointercancel: ((Event) -> dynamic)?
var onpointerover: ((Event) -> dynamic)?
var onpointerout: ((Event) -> dynamic)?
var onpointerenter: ((Event) -> dynamic)?
var onpointerleave: ((Event) -> dynamic)?
var ongotpointercapture: ((PointerEvent) -> dynamic)?
var onlostpointercapture: ((PointerEvent) -> dynamic)?
var onpointerdown: ((PointerEvent) -> dynamic)?
var onpointermove: ((PointerEvent) -> dynamic)?
var onpointerup: ((PointerEvent) -> dynamic)?
var onpointercancel: ((PointerEvent) -> dynamic)?
var onpointerover: ((PointerEvent) -> dynamic)?
var onpointerout: ((PointerEvent) -> dynamic)?
var onpointerenter: ((PointerEvent) -> dynamic)?
var onpointerleave: ((PointerEvent) -> dynamic)?
var onabort: ((Event) -> dynamic)?
var onblur: ((Event) -> dynamic)?
var onblur: ((FocusEvent) -> dynamic)?
var oncancel: ((Event) -> dynamic)?
var oncanplay: ((Event) -> dynamic)?
var oncanplaythrough: ((Event) -> dynamic)?
var onchange: ((Event) -> dynamic)?
var onclick: ((Event) -> dynamic)?
var onclick: ((MouseEvent) -> dynamic)?
var onclose: ((Event) -> dynamic)?
var oncontextmenu: ((Event) -> dynamic)?
var oncontextmenu: ((MouseEvent) -> dynamic)?
var oncuechange: ((Event) -> dynamic)?
var ondblclick: ((Event) -> dynamic)?
var ondrag: ((Event) -> dynamic)?
var ondragend: ((Event) -> dynamic)?
var ondragenter: ((Event) -> dynamic)?
var ondragexit: ((Event) -> dynamic)?
var ondragleave: ((Event) -> dynamic)?
var ondragover: ((Event) -> dynamic)?
var ondragstart: ((Event) -> dynamic)?
var ondrop: ((Event) -> dynamic)?
var ondblclick: ((MouseEvent) -> dynamic)?
var ondrag: ((DragEvent) -> dynamic)?
var ondragend: ((DragEvent) -> dynamic)?
var ondragenter: ((DragEvent) -> dynamic)?
var ondragexit: ((DragEvent) -> dynamic)?
var ondragleave: ((DragEvent) -> dynamic)?
var ondragover: ((DragEvent) -> dynamic)?
var ondragstart: ((DragEvent) -> dynamic)?
var ondrop: ((DragEvent) -> dynamic)?
var ondurationchange: ((Event) -> dynamic)?
var onemptied: ((Event) -> dynamic)?
var onended: ((Event) -> dynamic)?
var onerror: ((dynamic, String, Int, Int, Any?) -> dynamic)?
var onfocus: ((Event) -> dynamic)?
var oninput: ((Event) -> dynamic)?
var onfocus: ((FocusEvent) -> dynamic)?
var oninput: ((InputEvent) -> dynamic)?
var oninvalid: ((Event) -> dynamic)?
var onkeydown: ((Event) -> dynamic)?
var onkeypress: ((Event) -> dynamic)?
var onkeyup: ((Event) -> dynamic)?
var onkeydown: ((KeyboardEvent) -> dynamic)?
var onkeypress: ((KeyboardEvent) -> dynamic)?
var onkeyup: ((KeyboardEvent) -> dynamic)?
var onload: ((Event) -> dynamic)?
var onloadeddata: ((Event) -> dynamic)?
var onloadedmetadata: ((Event) -> dynamic)?
var onloadend: ((Event) -> dynamic)?
var onloadstart: ((Event) -> dynamic)?
var onmousedown: ((Event) -> dynamic)?
var onmouseenter: ((Event) -> dynamic)?
var onmouseleave: ((Event) -> dynamic)?
var onmousemove: ((Event) -> dynamic)?
var onmouseout: ((Event) -> dynamic)?
var onmouseover: ((Event) -> dynamic)?
var onmouseup: ((Event) -> dynamic)?
var onwheel: ((Event) -> dynamic)?
var onloadstart: ((ProgressEvent) -> dynamic)?
var onmousedown: ((MouseEvent) -> dynamic)?
var onmouseenter: ((MouseEvent) -> dynamic)?
var onmouseleave: ((MouseEvent) -> dynamic)?
var onmousemove: ((MouseEvent) -> dynamic)?
var onmouseout: ((MouseEvent) -> dynamic)?
var onmouseover: ((MouseEvent) -> dynamic)?
var onmouseup: ((MouseEvent) -> dynamic)?
var onwheel: ((WheelEvent) -> dynamic)?
var onpause: ((Event) -> dynamic)?
var onplay: ((Event) -> dynamic)?
var onplaying: ((Event) -> dynamic)?
var onprogress: ((Event) -> dynamic)?
var onprogress: ((ProgressEvent) -> dynamic)?
var onratechange: ((Event) -> dynamic)?
var onreset: ((Event) -> dynamic)?
var onresize: ((Event) -> dynamic)?
@@ -2215,18 +2215,18 @@ public external interface GlobalEventHandlers {
public external interface WindowEventHandlers {
var onafterprint: ((Event) -> dynamic)?
var onbeforeprint: ((Event) -> dynamic)?
var onbeforeunload: ((Event) -> String?)?
var onhashchange: ((Event) -> dynamic)?
var onbeforeunload: ((BeforeUnloadEvent) -> String?)?
var onhashchange: ((HashChangeEvent) -> dynamic)?
var onlanguagechange: ((Event) -> dynamic)?
var onmessage: ((Event) -> dynamic)?
var onmessage: ((MessageEvent) -> dynamic)?
var onoffline: ((Event) -> dynamic)?
var ononline: ((Event) -> dynamic)?
var onpagehide: ((Event) -> dynamic)?
var onpageshow: ((Event) -> dynamic)?
var onpopstate: ((Event) -> dynamic)?
var onpagehide: ((PageTransitionEvent) -> dynamic)?
var onpageshow: ((PageTransitionEvent) -> dynamic)?
var onpopstate: ((PopStateEvent) -> dynamic)?
var onrejectionhandled: ((Event) -> dynamic)?
var onstorage: ((Event) -> dynamic)?
var onunhandledrejection: ((Event) -> dynamic)?
var onstorage: ((StorageEvent) -> dynamic)?
var onunhandledrejection: ((PromiseRejectionEvent) -> dynamic)?
var onunload: ((Event) -> dynamic)?
}
@@ -2454,7 +2454,7 @@ public external open class EventSource(url: String, eventSourceInitDict: EventSo
open val withCredentials: Boolean
open val readyState: Short
var onopen: ((Event) -> dynamic)?
var onmessage: ((Event) -> dynamic)?
var onmessage: ((MessageEvent) -> dynamic)?
var onerror: ((Event) -> dynamic)?
fun close(): Unit
@@ -2492,7 +2492,7 @@ public external open class WebSocket(url: String, protocols: dynamic = definedEx
var onclose: ((Event) -> dynamic)?
open val extensions: String
open val protocol: String
var onmessage: ((Event) -> dynamic)?
var onmessage: ((MessageEvent) -> dynamic)?
var binaryType: BinaryType
fun close(code: Short = definedExternally, reason: String = definedExternally): Unit
fun send(data: String): Unit
@@ -2555,7 +2555,7 @@ public external open class MessageChannel {
* Exposes the JavaScript [MessagePort](https://developer.mozilla.org/en/docs/Web/API/MessagePort) to Kotlin
*/
public external abstract class MessagePort : EventTarget, UnionMessagePortOrWindow, UnionMessagePortOrServiceWorker, UnionClientOrMessagePortOrServiceWorker {
open var onmessage: ((Event) -> dynamic)?
open var onmessage: ((MessageEvent) -> dynamic)?
fun postMessage(message: Any?, transfer: Array<dynamic> = definedExternally): Unit
fun start(): Unit
fun close(): Unit
@@ -2566,7 +2566,7 @@ public external abstract class MessagePort : EventTarget, UnionMessagePortOrWind
*/
public external open class BroadcastChannel(name: String) : EventTarget {
open val name: String
var onmessage: ((Event) -> dynamic)?
var onmessage: ((MessageEvent) -> dynamic)?
fun postMessage(message: Any?): Unit
fun close(): Unit
}
@@ -2583,7 +2583,7 @@ public external abstract class WorkerGlobalScope : EventTarget, WindowOrWorkerGl
open var onoffline: ((Event) -> dynamic)?
open var ononline: ((Event) -> dynamic)?
open var onrejectionhandled: ((Event) -> dynamic)?
open var onunhandledrejection: ((Event) -> dynamic)?
open var onunhandledrejection: ((PromiseRejectionEvent) -> dynamic)?
fun importScripts(vararg urls: String): Unit
}
@@ -2591,7 +2591,7 @@ public external abstract class WorkerGlobalScope : EventTarget, WindowOrWorkerGl
* Exposes the JavaScript [DedicatedWorkerGlobalScope](https://developer.mozilla.org/en/docs/Web/API/DedicatedWorkerGlobalScope) to Kotlin
*/
public external abstract class DedicatedWorkerGlobalScope : WorkerGlobalScope {
open var onmessage: ((Event) -> dynamic)?
open var onmessage: ((MessageEvent) -> dynamic)?
fun postMessage(message: Any?, transfer: Array<dynamic> = definedExternally): Unit
fun close(): Unit
}
@@ -2617,7 +2617,7 @@ public external interface AbstractWorker {
* Exposes the JavaScript [Worker](https://developer.mozilla.org/en/docs/Web/API/Worker) to Kotlin
*/
public external open class Worker(scriptURL: String, options: WorkerOptions = definedExternally) : EventTarget, AbstractWorker {
var onmessage: ((Event) -> dynamic)?
var onmessage: ((MessageEvent) -> dynamic)?
override var onerror: ((Event) -> dynamic)?
fun terminate(): Unit
fun postMessage(message: Any?, transfer: Array<dynamic> = definedExternally): Unit
@@ -90,8 +90,8 @@ public external open class FileReader : EventTarget {
open val readyState: Short
open val result: dynamic
open val error: dynamic
var onloadstart: ((Event) -> dynamic)?
var onprogress: ((Event) -> dynamic)?
var onloadstart: ((ProgressEvent) -> dynamic)?
var onprogress: ((ProgressEvent) -> dynamic)?
var onload: ((Event) -> dynamic)?
var onabort: ((Event) -> dynamic)?
var onerror: ((Event) -> dynamic)?
@@ -28,7 +28,7 @@ import org.w3c.xhr.*
* Exposes the JavaScript [Notification](https://developer.mozilla.org/en/docs/Web/API/Notification) to Kotlin
*/
public external open class Notification(title: String, options: NotificationOptions = definedExternally) : EventTarget {
var onclick: ((Event) -> dynamic)?
var onclick: ((MouseEvent) -> dynamic)?
var onerror: ((Event) -> dynamic)?
open val title: String
open val dir: NotificationDirection
@@ -49,12 +49,12 @@ public external abstract class ServiceWorkerGlobalScope : WorkerGlobalScope {
open val registration: ServiceWorkerRegistration
open var oninstall: ((Event) -> dynamic)?
open var onactivate: ((Event) -> dynamic)?
open var onfetch: ((Event) -> dynamic)?
open var onfetch: ((FetchEvent) -> dynamic)?
open var onforeignfetch: ((Event) -> dynamic)?
open var onmessage: ((Event) -> dynamic)?
open var onmessage: ((MessageEvent) -> dynamic)?
open var onfunctionalevent: ((Event) -> dynamic)?
open var onnotificationclick: ((Event) -> dynamic)?
open var onnotificationclose: ((Event) -> dynamic)?
open var onnotificationclick: ((NotificationEvent) -> dynamic)?
open var onnotificationclose: ((NotificationEvent) -> dynamic)?
fun skipWaiting(): Promise<Unit>
}
@@ -75,7 +75,7 @@ public external abstract class ServiceWorkerContainer : EventTarget {
open val controller: ServiceWorker?
open val ready: Promise<ServiceWorkerRegistration>
open var oncontrollerchange: ((Event) -> dynamic)?
open var onmessage: ((Event) -> dynamic)?
open var onmessage: ((MessageEvent) -> dynamic)?
fun register(scriptURL: String, options: RegistrationOptions = definedExternally): Promise<ServiceWorkerRegistration>
fun getRegistration(clientURL: String = definedExternally): Promise<Any?>
fun getRegistrations(): Promise<dynamic>
@@ -28,8 +28,8 @@ import org.w3c.workers.*
* Exposes the JavaScript [XMLHttpRequestEventTarget](https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequestEventTarget) to Kotlin
*/
public external abstract class XMLHttpRequestEventTarget : EventTarget {
open var onloadstart: ((Event) -> dynamic)?
open var onprogress: ((Event) -> dynamic)?
open var onloadstart: ((ProgressEvent) -> dynamic)?
open var onprogress: ((ProgressEvent) -> dynamic)?
open var onabort: ((Event) -> dynamic)?
open var onerror: ((Event) -> dynamic)?
open var onload: ((Event) -> dynamic)?
@@ -91,4 +91,71 @@ val kotlinBuiltinInterfaces = mapOf(
primaryConstructor = null,
secondaryConstructors = emptyList()
)
)
)
val specifyEventMapper = mapOf<String, String>(
"onbeforeunload" to "BeforeUnloadEvent",
"ondrag" to "DragEvent",
"ondragend" to "DragEvent",
"ondragenter" to "DragEvent",
"ondragexit" to "DragEvent",
"ondragleave" to "DragEvent",
"ondragover" to "DragEvent",
"ondragstart" to "DragEvent",
"ondrop" to "DragEvent",
"onfetch" to "FetchEvent",
"onblur" to "FocusEvent",
"onfocus" to "FocusEvent",
"onhashchange" to "HashChangeEvent",
"oninput" to "InputEvent",
"onkeydown" to "KeyboardEvent",
"onkeypress" to "KeyboardEvent",
"onkeyup" to "KeyboardEvent",
"onmessage" to "MessageEvent",
"onclick" to "MouseEvent",
"oncontextmenu" to "MouseEvent",
"ondblclick" to "MouseEvent",
"onmousedown" to "MouseEvent",
"onmouseenter" to "MouseEvent",
"onmouseleave" to "MouseEvent",
"onmousemove" to "MouseEvent",
"onmouseout" to "MouseEvent",
"onmouseover" to "MouseEvent",
"onmouseup" to "MouseEvent",
"onnotificationclick" to "NotificationEvent",
"onnotificationclose" to "NotificationEvent",
"onpagehide" to "PageTransitionEvent",
"onpageshow" to "PageTransitionEvent",
"ongotpointercapture" to "PointerEvent",
"onlostpointercapture" to "PointerEvent",
"onpointercancel" to "PointerEvent",
"onpointerdown" to "PointerEvent",
"onpointerenter" to "PointerEvent",
"onpointerleave" to "PointerEvent",
"onpointermove" to "PointerEvent",
"onpointerout" to "PointerEvent",
"onpointerover" to "PointerEvent",
"onpointerup" to "PointerEvent",
"onpopstate" to "PopStateEvent",
"onloadstart" to "ProgressEvent",
"onprogress" to "ProgressEvent",
"onunhandledrejection" to "PromiseRejectionEvent",
"onstorage" to "StorageEvent",
"onwheel" to "WheelEvent"
)
+40 -21
View File
@@ -86,26 +86,26 @@ fun generateFunctions(repository: Repository, function: Operation): List<Generat
return listOf(realFunction, getterOrSetterFunction, functionWithCallbackOrNull).filterNotNull()
}
fun generateAttribute(putNoImpl: Boolean, repository: Repository, attribute: Attribute, nullableAttributes: Boolean): GenerateAttribute =
GenerateAttribute(attribute.name,
type = mapType(repository, attribute.type).let { if (nullableAttributes) it.toNullable() else it },
initializer =
if (putNoImpl && !attribute.static) {
mapLiteral(attribute.defaultValue, mapType(repository, attribute.type), repository.enums)
}
else if (attribute.defaultValue != null) {
"definedExternally"
}
else {
null
},
getterSetterNoImpl = putNoImpl,
kind = if (attribute.readOnly) AttributeKind.VAL else AttributeKind.VAR,
override = false,
vararg = attribute.vararg,
static = attribute.static,
required = attribute.required
)
fun generateAttribute(putNoImpl: Boolean, repository: Repository, attribute: Attribute, nullableAttributes: Boolean): GenerateAttribute {
val mappedType = mapType(repository, attribute.type).let { if (nullableAttributes) it.toNullable() else it }
return GenerateAttribute(attribute.name,
type = generalizeType(attribute.name, mappedType),
initializer =
if (putNoImpl && !attribute.static) {
mapLiteral(attribute.defaultValue, mapType(repository, attribute.type), repository.enums)
} else if (attribute.defaultValue != null) {
"definedExternally"
} else {
null
},
getterSetterNoImpl = putNoImpl,
kind = if (attribute.readOnly) AttributeKind.VAL else AttributeKind.VAR,
override = false,
vararg = attribute.vararg,
static = attribute.static,
required = attribute.required
)
}
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 =
@@ -259,6 +259,25 @@ private fun mapLiteral(literal: String?, expectedType: Type = DynamicType, enums
}
}
private fun specifyType(name: String, type: Type): Type {
if ((type is SimpleType) && (type.type == "Event")) {
specifyEventMapper[name]?.let {
return type.copy(type = it)
}
}
return type
}
private fun generalizeType(name: String, type: Type): Type {
if ((type is FunctionType) && (type.parameterTypes.size == 1)) {
val paramAttribute = type.parameterTypes[0]
return type.copy(parameterTypes = listOf(paramAttribute.copy(type = specifyType(name, paramAttribute.type))))
}
return type
}
fun implementInterfaces(declarations: List<GenerateTraitOrClass>) {
val unimplementedMemberMap = getUnimplementedMembers(declarations)
val nonAbstractDeclarations = declarations.filter { it.kind == GenerateDefinitionKind.CLASS }
@@ -266,7 +285,7 @@ fun implementInterfaces(declarations: List<GenerateTraitOrClass>) {
val unimplementedMembers = unimplementedMemberMap[declaration.name] ?: continue
for (attribute in unimplementedMembers.attributes) {
declaration.memberAttributes += attribute.copy(override = true)
declaration.memberAttributes += attribute.copy(override = true, type = generalizeType(attribute.name, attribute.type))
}
for (function in unimplementedMembers.functions) {
declaration.memberFunctions += function.copy(override = true)
@@ -19,42 +19,49 @@ package org.jetbrains.idl2k
import java.util.*
private val typeMapper = mapOf(
"unsignedlong" to SimpleType("Int", false),
"unsignedlonglong" to SimpleType("Int", false),
"longlong" to SimpleType("Int", false),
"unsignedshort" to SimpleType("Short", false),
"unsignedbyte" to SimpleType("Byte", false),
"octet" to SimpleType("Byte", false),
"void" to UnitType,
"boolean" to SimpleType("Boolean", false),
"byte" to SimpleType("Byte", false),
"short" to SimpleType("Short", false),
"long" to SimpleType("Int", false),
"float" to SimpleType("Float", false),
"double" to SimpleType("Double", false),
"any" to AnyType(true),
"DOMTimeStamp" to SimpleType("Number", false),
"object" to DynamicType, // TODO map to Any?
"WindowProxy" to SimpleType("Window", false),
"USVString" to SimpleType("String", false),
"DOMString" to SimpleType("String", false),
"ByteString" to SimpleType("String", false),
"DOMError" to DynamicType,
"Elements" to DynamicType,
"Date" to SimpleType("Date", false),
"" to DynamicType
"unsignedlong" to SimpleType("Int", false),
"unsignedlonglong" to SimpleType("Int", false),
"longlong" to SimpleType("Int", false),
"unsignedshort" to SimpleType("Short", false),
"unsignedbyte" to SimpleType("Byte", false),
"octet" to SimpleType("Byte", false),
"void" to UnitType,
"boolean" to SimpleType("Boolean", false),
"byte" to SimpleType("Byte", false),
"short" to SimpleType("Short", false),
"long" to SimpleType("Int", false),
"float" to SimpleType("Float", false),
"double" to SimpleType("Double", false),
"any" to AnyType(true),
"DOMTimeStamp" to SimpleType("Number", false),
"object" to DynamicType, // TODO map to Any?
"WindowProxy" to SimpleType("Window", false),
"USVString" to SimpleType("String", false),
"DOMString" to SimpleType("String", false),
"ByteString" to SimpleType("String", false),
"DOMError" to DynamicType,
"Elements" to DynamicType,
"Date" to SimpleType("Date", false),
"" to DynamicType
)
fun GenerateTraitOrClass.allSuperTypes(all: Map<String, GenerateTraitOrClass>) = LinkedHashSet<GenerateTraitOrClass>().let { result -> allSuperTypesImpl(listOf(this), all, result); result.toList() }
fun GenerateTraitOrClass.allSuperTypes(all: Map<String, GenerateTraitOrClass>) =
LinkedHashSet<GenerateTraitOrClass>().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<GenerateTraitOrClass>,
all: Map<String, GenerateTraitOrClass>,
result: MutableSet<GenerateTraitOrClass>
) {
if (roots.isNotEmpty()) {
allSuperTypesImpl(roots.flatMap { it.superTypes }.map { all[it] ?: all[it.substringBefore("<")] }.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)
}
}
fun standardTypes() = typeMapper.values.map {it.dropNullable()}.toSet()
fun standardTypes() = typeMapper.values.map { it.dropNullable() }.toSet()
fun Type.dynamicIfUnknownType(allTypes: Set<String>, standardTypes: Set<Type> = standardTypes()): Type = when {
this is DynamicType || this is UnitType -> this
@@ -62,7 +69,16 @@ fun Type.dynamicIfUnknownType(allTypes: Set<String>, standardTypes: Set<Type> =
this.dropNullable() in standardTypes -> this
this is ArrayType -> copy(memberType = this.memberType.dynamicIfUnknownType(allTypes, standardTypes))
this is UnionType -> if (this.name !in allTypes) DynamicType else this
this is FunctionType -> copy(returnType = returnType.dynamicIfUnknownType(allTypes, standardTypes), parameterTypes = parameterTypes.map { it.copy(type = it.type.dynamicIfUnknownType(allTypes, standardTypes)) })
this is FunctionType -> copy(
returnType = returnType.dynamicIfUnknownType(allTypes, standardTypes),
parameterTypes = parameterTypes.map {
it.copy(
type = it.type.dynamicIfUnknownType(
allTypes,
standardTypes
)
)
})
this is PromiseType ->
copy(valueType = valueType.dynamicIfUnknownType(allTypes, standardTypes))
@@ -84,11 +100,15 @@ internal fun mapType(repository: Repository, type: Type): Type = when (type) {
}
is PromiseType -> type.copy(valueType = mapType(repository, type.valueType))
is ArrayType -> type.copy(memberType = mapType(repository, type.memberType))
is UnionType -> UnionType(type.namespace, type.memberTypes.map { mt -> mapType(repository, mt) }, type.nullable).toSingleTypeIfPossible()
is UnionType -> UnionType(
type.namespace,
type.memberTypes.map { mt -> mapType(repository, mt) },
type.nullable
).toSingleTypeIfPossible()
is FunctionType -> type.copy(
// TODO: Remove takeWhile { !vararg } when we have varargs supported. See KT-3115
returnType = mapType(repository, type.returnType).dynamicIfAnyType(),
parameterTypes = type.parameterTypes.takeWhile { !it.vararg }.map { it.copy(type = mapType(repository, it.type)) }
// TODO: Remove takeWhile { !vararg } when we have varargs supported. See KT-3115
returnType = mapType(repository, type.returnType).dynamicIfAnyType(),
parameterTypes = type.parameterTypes.takeWhile { !it.vararg }.map { it.copy(type = mapType(repository, it.type)) }
)
is AnyType,
@@ -100,30 +120,39 @@ private fun mapTypedef(repository: Repository, type: SimpleType): Type {
val typedef = repository.typeDefs[type.type]!!
return when {
typedef.types is UnionType && typedef.types.memberTypes.size == 1 -> mapType(repository, typedef.types.memberTypes.single().withNullability(type.nullable))
typedef.types is UnionType && typedef.types.memberTypes.size == 1 -> mapType(
repository,
typedef.types.memberTypes.single().withNullability(type.nullable)
)
typedef.types is UnionType -> SimpleType(typedef.name, type.nullable)
else -> mapType(repository, typedef.types.withNullability(type.nullable))
}
}
private fun GenerateFunction?.allTypes() = if (this != null) sequenceOf(returnType) + arguments.asSequence().map { it.type } else emptySequence()
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() } +
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, GenerateTraitOrClass>) =
types.map { allTypes[it] }
.map { it?.namespace }
.filterNotNull()
.filter { it.isNotEmpty() }