diff --git a/types/webidl2/index.d.ts b/types/webidl2/index.d.ts new file mode 100644 index 0000000000..0dd0cc7f10 --- /dev/null +++ b/types/webidl2/index.d.ts @@ -0,0 +1,283 @@ +// Type definitions for webidl2 10.2 +// Project: https://github.com/w3c/webidl2.js#readme +// Definitions by: Kagama Sascha Rosylight +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +export as namespace WebIDL2; + +export function parse(str: string, options?: ParseOptions): IDLRootType[]; + +export type IDLRootType = InterfaceType | InterfaceMixinType | NamespaceType | CallbackType | DictionaryType | EnumType | TypedefType | ImplementsType | IncludesType; + +export type IDLInterfaceMemberType = OperationMemberType | AttributeMemberType | ConstantMemberType | DeclarationMemberType; + +export type IDLNamespaceMemberType = OperationMemberType | AttributeMemberType; + +export interface ParseOptions { + /** Boolean indicating whether the parser should accept typedefs as valid members of interfaces. */ + allowNestedTypedefs?: boolean; +} + +export interface WebIDLParseError { + /** the error message */ + message: string; + /** the line at which the error occurred. */ + line: number; + /** a short peek at the text at the point where the error happened */ + input: string; + /** the five tokens at the point of error, as understood by the tokeniser */ + tokens: ValueDescription[]; + + toString(): string; +} + +// tslint:disable-next-line interface-name +export interface IDLTypeDescription { + type: string; + /** Boolean indicating if it is a sequence. Same as generic === "sequence" */ + sequence: boolean; + /** String indicating the generic type (e.g. "Promise", "sequence"). null otherwise. */ + generic: string | null; + /** Boolean indicating whether this is nullable or not. */ + nullable: boolean; + /** Boolean indicating whether this is a union type or not. */ + union: boolean; + /** + * In most cases, this will just be a string with the type name. + * If the type is a union, then this contains an array of the types it unites. + * If it is a generic type, it contains the IDL type description for the type in the sequence, + * the eventual value of the promise, etc. + */ + idlType: string | IDLTypeDescription | IDLTypeDescription[]; +} + +export interface InterfaceType { + type: "interface" | "callback interface"; + /** The name of the interface */ + name: string; + /** A boolean indicating whether it's a partial interface. */ + partial: boolean; + /** An array of interface members (attributes, operations, etc.). Empty if there are none. */ + members: IDLInterfaceMemberType[]; + /** A string giving the name of an interface this one inherits from, null otherwise. */ + inheritance: string | null; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface InterfaceMixinType { + type: "interface mixin"; + /** The name of the interface mixin */ + name: string; + /** A boolean indicating whether it's a partial interface mixin. */ + partial: boolean; + /** An array of interface members (attributes, operations, etc.). Empty if there are none. */ + members: IDLInterfaceMemberType[]; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface NamespaceType { + type: "namespace"; + /** A boolean indicating whether it's a partial namespace. */ + partial: boolean; + /** The enum's name. */ + name: string; + /** An array of namespace members (attributes, operations). Empty if there are none. */ + members: IDLNamespaceMemberType[]; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface CallbackType { + type: "callback"; + /** The name of the callback. */ + name: string; + /** An IDL Type describing what the callback returns. */ + idlType: IDLTypeDescription; + /** A list of arguments, as in function paramters. */ + arguments: Argument[]; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface DictionaryType { + type: "dictionary"; + /** The dictionary name. */ + name: string; + /** Boolean indicating whether it's a partial dictionary. */ + partial: boolean; + /** An array of members (see below). */ + members: DictionaryMemberType[]; + /** A string indicating which dictionary is being inherited from, null otherwise. */ + inheritance: string | null; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface DictionaryMemberType extends FieldType { + /** Boolean indicating whether this is a required field. */ + required: boolean; + /** A default value, absent if there is none. */ + default: ValueDescription | null; +} + +export interface FieldType { + type: "field"; + /** The name of the field. */ + name: string; + /** An IDL Type describing what field's type. */ + idlType: IDLTypeDescription; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; + /** A default value, absent if there is none. */ + default: ValueDescription | null; +} + +export interface EnumType { + type: "enum"; + /** The enum's name. */ + name: string; + /** An array of values (strings). */ + values: Array<{ type: "string", value: string }>; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface TypedefType { + type: "typedef"; + /** The typedef's name. */ + name: string; + /** An IDL Type describing what typedef's type. */ + idlType: IDLTypeDescription; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface ImplementsType { + type: "implements"; + /** The interface that implements another. */ + target: string; + /** The interface that is being implemented by the target. */ + implements: string; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface IncludesType { + type: "includes"; + /** The interface that includes an interface mixin. */ + target: string; + /** The interface mixin that is being included by the target. */ + includes: string; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface OperationMemberType { + type: "operation"; + /** True if a getter operation. */ + getter: boolean; + /** True if a setter operation. */ + setter: boolean; + /** True if a deleter operation. */ + deleter: boolean; + /** True if a static operation. */ + static: boolean; + /** True if a stringifier operation. */ + stringifier: boolean; + /** An IDL Type of what the operation returns. If a stringifier, may be absent. */ + idlType: IDLTypeDescription | null; + /** The name of the operation. If a stringifier, may be null. */ + name: string | null; + /** An array of arguments for the operation. */ + arguments: Argument[] | null; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface AttributeMemberType { + type: "attribute"; + /** The attribute's name. */ + name: string; + /** True if it's a static attribute. */ + static: boolean; + /** True if it's a stringifier attribute. */ + stringifier: boolean; + /** True if it's an inherit attribute. */ + inherit: boolean; + /** True if it's a read-only attribute. */ + readonly: boolean; + /** An IDL Type for the attribute. */ + idlType: IDLTypeDescription; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface ConstantMemberType { + type: "const"; + /** Whether its type is nullable. */ + nullable: boolean; + /** The type of the constant (a simple type, the type name). */ + idlType: string; + /** The name of the constant. */ + name: string; + /** The constant value */ + value: ValueDescription; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface Argument { + default: ValueDescription; + /** True if the argument is optional. */ + optional: boolean; + /** True if the argument is variadic. */ + variadic: boolean; + /** An IDL Type describing the type of the argument. */ + idlType: IDLTypeDescription; + /** The argument's name. */ + name: string; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} + +export interface ExtendedAttributes { + /** The extended attribute's name. */ + name: string; + /** If the extended attribute takes arguments or if its right-hand side does they are listed here. */ + arguments: Argument[]; + /** If there is a right-hand side, this will capture its type ("identifier" or "identifier-list") and its value. */ + rhs: ExtendedAttributeRightHandSideIdentifier | ExtendedAttributeRightHandSideIdentifierList; +} + +export interface Token { + type: "float" | "integer" | "identifier" | "string" | "whitespace" | "other"; + value: string; +} + +export interface ExtendedAttributeRightHandSideIdentifier { + type: "identifier"; + value: string; +} + +export interface ExtendedAttributeRightHandSideIdentifierList { + type: "identifier-list"; + value: string[]; +} + +export interface ValueDescription { + type: "string" | "number" | "boolean" | "null" | "Infinity" | "NaN" | "sequence"; + value: string | any[] | null; + negative: boolean | null; +} + +export interface DeclarationMemberType { + type: "iterable" | "legacyiterable" | "setlike" | "maplike"; + /** An array with one or more IDL Types representing the declared type arguments. */ + idlType: IDLTypeDescription[]; + /** Whether the maplike or setlike is declared as read only. */ + readonly: boolean; + /** A list of extended attributes. */ + extAttrs: ExtendedAttributes[]; +} diff --git a/types/webidl2/tsconfig.json b/types/webidl2/tsconfig.json new file mode 100644 index 0000000000..04827a6268 --- /dev/null +++ b/types/webidl2/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "webidl2-tests.ts" + ] +} diff --git a/types/webidl2/tslint.json b/types/webidl2/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/webidl2/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/webidl2/webidl2-tests.ts b/types/webidl2/webidl2-tests.ts new file mode 100644 index 0000000000..61b437f563 --- /dev/null +++ b/types/webidl2/webidl2-tests.ts @@ -0,0 +1,144 @@ +import * as webidl2 from "webidl2"; + +const parsed = webidl2.parse(""); + +for (const rootType of parsed) { + if (rootType.type !== "implements" && rootType.type !== "includes") { + console.log(rootType.name); + } + switch (rootType.type) { + case "interface": + console.log(rootType.inheritance); + logMembers(rootType.members); + console.log(rootType.partial); + break; + case "interface mixin": + logMembers(rootType.members); + console.log(rootType.partial); + break; + case "namespace": + console.log(rootType.partial); + logNamespaceMembers(rootType.members); + break; + case "callback interface": + logMembers(rootType.members); + console.log(rootType.partial); + break; + case "callback": + logArguments(rootType.arguments); + break; + case "dictionary": + console.log(rootType.inheritance); + for (const member of rootType.members) { + console.log(member.required, member.default); + } + break; + case "enum": + for (const v of rootType.values) { + console.log(v.type); + console.log(v.value); + } + break; + case "typedef": + logIdlType(rootType.idlType); + break; + case "implements": + console.log(rootType.target); + console.log(rootType.implements); + break; + case "includes": + console.log(rootType.target); + console.log(rootType.includes); + break; + } + + logExtAttrs(rootType.extAttrs); +} + +function logMembers(members: webidl2.IDLInterfaceMemberType[]) { + for (const member of members) { + switch (member.type) { + case "operation": + case "attribute": + logNamespaceMembers([member]); + break; + case "const": + console.log(member.name); + console.log(member.value); + console.log(member.nullable); + break; + case "iterable": + console.log(member.readonly); + break; + case "legacyiterable": + console.log(member.readonly); + break; + case "setlike": + console.log(member.readonly); + break; + case "maplike": + console.log(member.readonly); + break; + } + logIdlType(member.idlType); + logExtAttrs(member.extAttrs); + } +} + +function logNamespaceMembers(members: webidl2.IDLNamespaceMemberType[]) { + for (const member of members) { + if (member.type === "operation") { + console.log(member.name); + console.log(member.getter, member.setter, member.deleter); + console.log(member.static, member.stringifier); + } else if (member.type === "attribute") { + console.log(member.name); + console.log(member.static, member.stringifier, member.readonly, member.inherit); + } + } +} + +function logExtAttrs(extAttrs: webidl2.ExtendedAttributes[]) { + console.log(extAttrs[0].name); + logArguments(extAttrs[0].arguments); + const { rhs } = extAttrs[0]; + if (rhs.type === "identifier") { + console.log(rhs); + } else { + for (const v of rhs.value) { + console.log(v); + } + } +} + +function logArguments(args: webidl2.Argument[]) { + for (const arg of args) { + console.log(arg.name); + console.log(arg.default, arg.optional, arg.variadic); + logIdlType(arg.idlType); + logExtAttrs(arg.extAttrs); + } +} + +function logIdlType(idlType: string | webidl2.IDLTypeDescription | webidl2.IDLTypeDescription[] | null) { + if (!idlType) { + return; + } + if (typeof idlType === "string") { + console.log(idlType); + return; + } + if (Array.isArray(idlType)) { + for (const t of idlType) { + logEachType(t); + } + return; + } + logEachType(idlType); + + function logEachType(t: webidl2.IDLTypeDescription) { + console.log(t.type); + console.log(t.generic, t.nullable, t.sequence, t.union); + logIdlType(t.idlType); + } +}