Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Encoding Stardard by adding browser.webidl.json #300

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 177 additions & 22 deletions TS.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ module Helpers =
match FSharpValue.GetUnionFields(x, typeof<'a>) with
| case, _ -> case.Name

let inline toNameMap< ^a when ^a: (member Name: string) > (data: array< ^a > ) =
data
|> Array.map (fun x -> ((^a: (member Name: string) x), x))
|> Map.ofArray

module Option =
let runIfSome f x =
match x with
Expand Down Expand Up @@ -131,6 +136,142 @@ module Types =

type ExtendConflict = { BaseType: string; ExtendType: string list; MemberNames: string list }

module InputIdlJson =
open Helpers
open System.Xml.Linq

type InputIdlJsonType = JsonProvider<"inputfiles/sample.webidl.json">

let inputIdl =
let jsons =
DirectoryInfo(GlobalVars.inputFolder + @"/idls").GetFiles()
|> Array.map (fun file -> file.FullName |> File.ReadAllText |> InputIdlJsonType.Parse)

let inline extractJsonArray f =
jsons |> Array.collect f |> Array.map (fun item -> (^a: (member JsonValue: JsonValue) item)) |> JsonValue.Array;

let list = [| ("callbackFunctions", extractJsonArray (fun json -> json.CallbackFunctions));
("interfaces", extractJsonArray (fun json -> json.Interfaces));
("dictionaries", extractJsonArray (fun json -> json.Dictionaries));
("typedefs", extractJsonArray (fun json -> json.Typedefs)) |]
InputIdlJsonType.Root(JsonValue.Record list)

let allCallbackFunctionsMap =
inputIdl.CallbackFunctions |> toNameMap

let allInterfacesMap =
inputIdl.Interfaces |> toNameMap

let allDictionariesMap =
inputIdl.Dictionaries |> toNameMap

let allTypedefsMap =
inputIdl.Typedefs |> toNameMap

let hasType itemName =
allCallbackFunctionsMap.ContainsKey itemName ||
allInterfacesMap.ContainsKey itemName ||
allDictionariesMap.ContainsKey itemName ||
allTypedefsMap.ContainsKey itemName

module Compat =
let xNamespace = XNamespace.Get "http://schemas.microsoft.com/ie/webidl-xml"
let convertArgument (i: InputIdlJsonType.Argument) =
let param = XElement(xNamespace + "param", XAttribute (XName.Get "name", i.Name), XAttribute (XName.Get "type", i.Type))
if OptionCheckValue true i.Optional then
param.Add (XAttribute(XName.Get "optional", "1"))
if OptionCheckValue true i.Nullable then
param.Add (XAttribute(XName.Get "nullable", "1"))
if OptionCheckValue true i.Variadic then
param.Add (XAttribute(XName.Get "variadic", "1"))
param

let convertOperation (i: InputIdlJsonType.Operation) =
let method = XElement(xNamespace + "method", XAttribute (XName.Get "name", i.Name), XAttribute (XName.Get "type", i.Type))

method.Add(i.Arguments |> Array.map convertArgument)
if OptionCheckValue true i.Static then
method.Add(XAttribute(XName.Get "static", "1"))
if OptionCheckValue true i.Nullable then
method.Add(XAttribute(XName.Get "nullable", "1"))

method

let convertConstructor(i: InputIdlJsonType.Constructor) =
let constructor = XElement(xNamespace + "constructor")

if not (Array.isEmpty i.Arguments) then
constructor.Add(i.Arguments |> Array.map convertArgument)

constructor

let convertAttribute (i: InputIdlJsonType.Attribute) =
let property = XElement(xNamespace + "property", XAttribute (XName.Get "name", i.Name), XAttribute (XName.Get "type", i.Type))

if OptionCheckValue true i.Readonly then
property.Add(XAttribute(XName.Get "read-only", "1"))
if OptionCheckValue true i.Static then
property.Add(XAttribute(XName.Get "static", "1"))
if OptionCheckValue true i.Stringifier then
property.Add(XAttribute(XName.Get "stringifier", "1"))
if OptionCheckValue true i.Nullable then
property.Add(XAttribute(XName.Get "nullable", "1"))

property

let convertConstant (i: InputIdlJsonType.Constant) =
XElement(xNamespace + "constant", XAttribute (XName.Get "name", i.Name), XAttribute (XName.Get "type", i.Type), XAttribute (XName.Get "value", i.Value))

let convertCallbackFunction (i: InputIdlJsonType.CallbackFunction) =
let callbackFunction = XElement(xNamespace + "callback-function", XAttribute (XName.Get "name", i.Name), XAttribute (XName.Get "type", i.Type))

callbackFunction.Add(i.Arguments |> Array.map convertArgument)
if OptionCheckValue true i.Nullable then
callbackFunction.Add(XAttribute(XName.Get "nullable", "1"))

Types.Browser.CallbackFunction callbackFunction

let convertInterface (i: InputIdlJsonType.Interfacis) =
let interfaceEl = XElement(xNamespace + "interface", XAttribute (XName.Get "name", i.Name))

interfaceEl.Add (XAttribute (XName.Get "extends", if i.Extends.IsSome then i.Extends.Value else "Object"))
if not (Array.isEmpty i.Constructors) then
interfaceEl.Add(i.Constructors |> Array.map convertConstructor)
if not (Array.isEmpty i.Operations) then
interfaceEl.Add(XElement(xNamespace + "methods", i.Operations |> Array.map convertOperation))
if not (Array.isEmpty i.Attributes) then
interfaceEl.Add(XElement(xNamespace + "properties", i.Attributes |> Array.map convertAttribute))
if not (Array.isEmpty i.Constants) then
interfaceEl.Add(XElement(xNamespace + "constants", i.Constants |> Array.map convertConstant))

Types.Browser.Interface interfaceEl

let convertDictionary (i: InputIdlJsonType.Dictionary) =
let dictionary = XElement(xNamespace + "dictionary", XAttribute (XName.Get "name", i.Name))

dictionary.Add (XAttribute (XName.Get "extends", if i.Extends.IsSome then i.Extends.Value else "Object"))
let members =
[ for memberDef in i.Members do
let memberEl = XElement(xNamespace + "member", XAttribute (XName.Get "name", memberDef.Name), XAttribute (XName.Get "type", memberDef.Type))

if OptionCheckValue true memberDef.Nullable then
memberEl.Add(XAttribute(XName.Get "nullable", "1"))
if OptionCheckValue true memberDef.Required then
memberEl.Add(XAttribute(XName.Get "required", "1"))

yield memberEl ]

dictionary.Add(XElement(xNamespace + "members", members))
Types.Browser.Dictionary dictionary

let convertTypedef (i: InputIdlJsonType.Typedef) =
let typedef = XElement(xNamespace + "typedef", XAttribute (XName.Get "new-type", i.Name), XAttribute (XName.Get "type", i.Type))

if OptionCheckValue true i.Nullable then
typedef.Add(XAttribute(XName.Get "nullable", "1"))

Types.Browser.Typedef typedef

module InputJson =
open Helpers
open Types
Expand Down Expand Up @@ -243,6 +384,7 @@ module CommentJson =
| _ -> None

module Data =
open Helpers
open Types

// Used to decide if a member should be emitted given its static property and
Expand Down Expand Up @@ -299,11 +441,6 @@ module Data =
let allInterfaces =
Array.concat [| allWebInterfaces; allWorkerAdditionalInterfaces |]

let inline toNameMap< ^a when ^a: (member Name: string) > (data: array< ^a > ) =
data
|> Array.map (fun x -> ((^a: (member Name: string) x), x))
|> Map.ofArray

let allInterfacesMap =
allInterfaces |> toNameMap

Expand Down Expand Up @@ -682,7 +819,6 @@ module Emit =
| "CanvasPixelArray" -> "number[]"
| "DOMHighResTimeStamp" -> "number"
| "DOMString" -> "string"
| "DOMTimeStamp" -> "number"
| "EndOfStreamError" -> "number"
| "double" | "float" -> "number"
| "object" -> "any"
Expand All @@ -699,7 +835,8 @@ module Emit =
if allInterfacesMap.ContainsKey objDomType ||
allCallbackFuncs.ContainsKey objDomType ||
allDictionariesMap.ContainsKey objDomType ||
allEnumsMap.ContainsKey objDomType then
allEnumsMap.ContainsKey objDomType ||
InputIdlJson.hasType objDomType then
objDomType
// Name of a type alias. Just return itself
elif typeDefSet.Contains objDomType then objDomType
Expand Down Expand Up @@ -867,7 +1004,12 @@ module Emit =
getAddedItems ItemKind.Callback flavor
|> Array.iter emitCallbackFunctionsFromJson

GetCallbackFuncsByFlavor flavor |> Array.iter emitCallBackFunction
let map = GetCallbackFuncsByFlavor flavor |> Array.map(fun i -> (i.Name, i)) |> dict |> Dictionary
InputIdlJson.inputIdl.CallbackFunctions
|> Array.filter (fun i -> flavor <> Worker || knownWorkerInterfaces.Contains i.Name)
|> Array.iter (InputIdlJson.Compat.convertCallbackFunction >> (fun i -> map.[i.Name] <- i))

map.Values |> Array.ofSeq |> Array.iter emitCallBackFunction

let EmitEnums flavor =
let emitEnum (e: Browser.Enum) =
Expand Down Expand Up @@ -1363,7 +1505,7 @@ module Emit =
if hasNonStaticMember then emitStaticInterfaceWithNonStaticMembers() else emitPureStaticInterface()

let EmitNonCallbackInterfaces flavor =
for i in GetNonCallbackInterfacesByFlavor flavor do
let emitNonCallbackInterface (i: Browser.Interface) =
// If the static attribute has a value, it means the type doesn't have a constructor
if i.Static.IsSome then
EmitStaticInterface flavor i
Expand All @@ -1373,6 +1515,13 @@ module Emit =
EmitInterface flavor i
EmitConstructor flavor i

let map = GetNonCallbackInterfacesByFlavor flavor |> Array.map(fun i -> (i.Name, i)) |> dict |> Dictionary
InputIdlJson.inputIdl.Interfaces
|> Array.filter (fun i -> flavor <> Worker || i.Exposed |> Array.contains "Worker")
|> Array.iter (InputIdlJson.Compat.convertInterface >> (fun i -> map.[i.Name] <- i))

map.Values |> Array.ofSeq |> Array.iter emitNonCallbackInterface

let EmitDictionaries flavor =

let emitDictionary (dict:Browser.Dictionary) =
Expand Down Expand Up @@ -1412,12 +1561,19 @@ module Emit =
Pt.Printl "}"
Pt.Printl ""

browser.Dictionaries
|> Array.filter (fun dict -> flavor <> Worker || knownWorkerInterfaces.Contains dict.Name)
|> Array.iter emitDictionary
let map =
browser.Dictionaries
|> Array.filter (fun dict -> flavor <> Worker || knownWorkerInterfaces.Contains dict.Name)
|> Array.map(fun i -> (i.Name, i)) |> dict |> Dictionary

if flavor = Worker then
worker.Dictionaries |> Array.iter emitDictionary
worker.Dictionaries |> Array.iter (fun dict -> map.[dict.Name] <- dict)

InputIdlJson.inputIdl.Dictionaries
|> Array.filter (fun dict -> flavor <> Worker || knownWorkerInterfaces.Contains dict.Name)
|> Array.iter (InputIdlJson.Compat.convertDictionary >> (fun i -> map.[i.Name] <- i))

map.Values |> Array.ofSeq |> Array.iter emitDictionary

let EmitAddedInterface (ai: InputJsonType.Root) =
match ai.Extends with
Expand Down Expand Up @@ -1463,15 +1619,14 @@ module Emit =
let emitTypeDefFromJson (typeDef: InputJsonType.Root) =
Pt.Printl "type %s = %s;" typeDef.Name.Value typeDef.Type.Value

match flavor with
| Flavor.Worker ->
browser.Typedefs
|> Array.filter (fun typedef -> knownWorkerInterfaces.Contains typedef.NewType)
|> Array.iter emitTypeDef
| _ ->
browser.Typedefs
|> Array.filter (fun typedef -> getRemovedItemByName typedef.NewType ItemKind.TypeDef "" |> Option.isNone)
|> Array.iter emitTypeDef
let mutable map = browser.Typedefs |> Array.map(fun i -> (i.NewType, i)) |> Map.ofArray
InputIdlJson.inputIdl.Typedefs
|> Array.iter (InputIdlJson.Compat.convertTypedef >> (fun i -> map <- map.Add(i.NewType, i)))

map |> Map.toArray |> Array.map snd
|> Array.filter (fun typedef -> getRemovedItemByName typedef.NewType ItemKind.TypeDef "" |> Option.isNone)
|> Array.filter (fun i -> (flavor <> Flavor.Worker || knownWorkerInterfaces.Contains i.NewType))
|> Array.iter emitTypeDef

InputJson.getAddedItems ItemKind.TypeDef flavor
|> Array.iter emitTypeDefFromJson
Expand Down
44 changes: 37 additions & 7 deletions baselines/dom.generated.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,15 @@ interface WheelEventInit extends MouseEventInit {
deltaZ?: number;
}

interface TextDecodeOptions {
stream?: boolean;
}

interface TextDecoderOptions {
fatal?: boolean;
ignoreBOM?: boolean;
}

type EventListener = (evt: Event) => void | { handleEvent(evt: Event): void; };

type WebKitEntriesCallback = (entries: WebKitEntry[]) => void | { handleEvent(entries: WebKitEntry[]): void; };
Expand Down Expand Up @@ -3356,7 +3365,6 @@ interface DOMException {
readonly code: number;
readonly message: string;
readonly name: string;
toString(): string;
readonly ABORT_ERR: number;
readonly DATA_CLONE_ERR: number;
readonly DOMSTRING_SIZE_ERR: number;
Expand All @@ -3374,10 +3382,8 @@ interface DOMException {
readonly NO_MODIFICATION_ALLOWED_ERR: number;
readonly NOT_FOUND_ERR: number;
readonly NOT_SUPPORTED_ERR: number;
readonly PARSE_ERR: number;
readonly QUOTA_EXCEEDED_ERR: number;
readonly SECURITY_ERR: number;
readonly SERIALIZE_ERR: number;
readonly SYNTAX_ERR: number;
readonly TIMEOUT_ERR: number;
readonly TYPE_MISMATCH_ERR: number;
Expand Down Expand Up @@ -3406,10 +3412,8 @@ declare var DOMException: {
readonly NO_MODIFICATION_ALLOWED_ERR: number;
readonly NOT_FOUND_ERR: number;
readonly NOT_SUPPORTED_ERR: number;
readonly PARSE_ERR: number;
readonly QUOTA_EXCEEDED_ERR: number;
readonly SECURITY_ERR: number;
readonly SERIALIZE_ERR: number;
readonly SYNTAX_ERR: number;
readonly TIMEOUT_ERR: number;
readonly TYPE_MISMATCH_ERR: number;
Expand Down Expand Up @@ -9069,7 +9073,7 @@ declare var PopStateEvent: {

interface Position {
readonly coords: Coordinates;
readonly timestamp: number;
readonly timestamp: DOMTimeStamp;
}

declare var Position: {
Expand Down Expand Up @@ -14234,6 +14238,28 @@ interface XMLHttpRequestEventTarget {
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
}

interface TextDecoder {
readonly encoding: string;
readonly fatal: boolean;
readonly ignoreBOM: boolean;
decode(input?: BufferSource, options?: TextDecodeOptions): USVString;
}

declare var TextDecoder: {
prototype: TextDecoder;
new(label?: string, options?: TextDecoderOptions): TextDecoder;
};

interface TextEncoder {
readonly encoding: string;
encode(input?: USVString): Uint8Array;
}

declare var TextEncoder: {
prototype: TextEncoder;
new(): TextEncoder;
};

interface BroadcastChannel extends EventTarget {
readonly name: string;
onmessage: (ev: MessageEvent) => any;
Expand Down Expand Up @@ -14914,6 +14940,9 @@ interface RTCStatsCallback {
interface VoidFunction {
(): void;
}
interface Function {
(...arguments: any[]): any;
}
interface HTMLElementTagNameMap {
"a": HTMLAnchorElement;
"abbr": HTMLElement;
Expand Down Expand Up @@ -15318,12 +15347,14 @@ declare function removeEventListener(type: string, listener: EventListener, opti
type AAGUID = string;
type AlgorithmIdentifier = string | Algorithm;
type BodyInit = Blob | BufferSource | FormData | string;
type BufferSource = ArrayBufferView | ArrayBuffer;
type ByteString = string;
type ConstrainBoolean = boolean | ConstrainBooleanParameters;
type ConstrainDOMString = string | string[] | ConstrainDOMStringParameters;
type ConstrainDouble = number | ConstrainDoubleRange;
type ConstrainLong = number | ConstrainLongRange;
type CryptoOperationData = ArrayBufferView;
type DOMTimeStamp = number;
type GLbitfield = number;
type GLboolean = boolean;
type GLbyte = number;
Expand Down Expand Up @@ -15353,7 +15384,6 @@ type payloadtype = number;
type ScrollBehavior = "auto" | "instant" | "smooth";
type ScrollLogicalPosition = "start" | "center" | "end" | "nearest";
type IDBValidKey = number | string | Date | IDBArrayKey;
type BufferSource = ArrayBuffer | ArrayBufferView;
type MouseWheelEvent = WheelEvent;
type ScrollRestoration = "auto" | "manual";
type FormDataEntryValue = string | File;
Expand Down
Loading