diff --git a/.gitignore b/.gitignore index 6cb772b..1f9143b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules tmp +.idea diff --git a/dist/cli.js b/dist/cli.js index 587b919..6bb2b2c 100755 --- a/dist/cli.js +++ b/dist/cli.js @@ -1,5 +1,28 @@ #!/usr/bin/env node "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -15,7 +38,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { @@ -37,11 +60,11 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; Object.defineProperty(exports, "__esModule", { value: true }); -var yargs = require("yargs"); +var yargs = __importStar(require("yargs")); var parse_idl_1 = require("./parse-idl"); var convert_idl_1 = require("./convert-idl"); var print_ts_1 = require("./print-ts"); -var fs = require("fs"); +var fs = __importStar(require("fs")); var fetch_idl_1 = require("./fetch-idl"); var fixes_1 = require("./fixes"); function main() { @@ -106,10 +129,10 @@ function convert(options) { var idlString, idl, ts, tsString; return __generator(this, function (_a) { switch (_a.label) { - case 0: return [4 /*yield*/, fetch_idl_1.fetchIDL(options.input)]; + case 0: return [4 /*yield*/, (0, fetch_idl_1.fetchIDL)(options.input)]; case 1: idlString = _a.sent(); - return [4 /*yield*/, parse_idl_1.parseIDL(idlString, { + return [4 /*yield*/, (0, parse_idl_1.parseIDL)(idlString, { preprocess: function (idl) { if (options.emscripten) { idl = fixes_1.fixes.inheritance(idl); @@ -120,13 +143,13 @@ function convert(options) { })]; case 2: idl = _a.sent(); - ts = convert_idl_1.convertIDL(idl, options); + ts = (0, convert_idl_1.convertIDL)(idl, options); tsString = null; if (options.emscripten) { - tsString = print_ts_1.printEmscriptenModule(options.module, ts, options.defaultExport); + tsString = (0, print_ts_1.printEmscriptenModule)(options.module, ts, options.defaultExport); } else { - tsString = print_ts_1.printTs(ts); + tsString = (0, print_ts_1.printTs)(ts); } fs.writeFileSync(options.output, tsString); return [2 /*return*/]; diff --git a/dist/convert-idl.js b/dist/convert-idl.js index 5771dcd..317accf 100644 --- a/dist/convert-idl.js +++ b/dist/convert-idl.js @@ -1,14 +1,39 @@ "use strict"; -var __spreadArrays = (this && this.__spreadArrays) || function () { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertIDL = void 0; -var ts = require("typescript"); +var ts = __importStar(require("typescript")); var bufferSourceTypes = [ 'ArrayBuffer', 'ArrayBufferView', @@ -27,14 +52,14 @@ var integerTypes = ['byte', 'octet', 'short', 'unsigned short', 'long', 'unsigne var stringTypes = ['ByteString', 'DOMString', 'USVString', 'CSSOMString']; var floatTypes = ['float', 'unrestricted float', 'double', 'unrestricted double']; var sameTypes = ['any', 'boolean', 'Date', 'Function', 'Promise', 'void']; -var baseTypeConversionMap = new Map(__spreadArrays(__spreadArrays(bufferSourceTypes).map(function (type) { return [type, type]; }), __spreadArrays(integerTypes).map(function (type) { return [type, 'number']; }), __spreadArrays(floatTypes).map(function (type) { return [type, 'number']; }), __spreadArrays(stringTypes).map(function (type) { return [type, 'string']; }), __spreadArrays(sameTypes).map(function (type) { return [type, type]; }), [ +var baseTypeConversionMap = new Map(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __spreadArray([], bufferSourceTypes, true).map(function (type) { return [type, type]; }), true), __spreadArray([], integerTypes, true).map(function (type) { return [type, 'number']; }), true), __spreadArray([], floatTypes, true).map(function (type) { return [type, 'number']; }), true), __spreadArray([], stringTypes, true).map(function (type) { return [type, 'string']; }), true), __spreadArray([], sameTypes, true).map(function (type) { return [type, type]; }), true), [ ['object', 'any'], ['sequence', 'Array'], ['record', 'Record'], ['FrozenArray', 'ReadonlyArray'], ['EventHandler', 'EventHandler'], ['VoidPtr', 'unknown'], -])); +], false)); function convertIDL(rootTypes, options) { var _a; var nodes = []; @@ -48,8 +73,8 @@ function convertIDL(rootTypes, options) { for (var _b = 0, _c = rootType.extAttrs; _b < _c.length; _b++) { var attr = _c[_b]; if (attr.name === 'Exposed' && ((_a = attr.rhs) === null || _a === void 0 ? void 0 : _a.value) === 'Window') { - nodes.push(ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.DeclareKeyword)], ts.createVariableDeclarationList([ - ts.createVariableDeclaration(ts.createIdentifier(rootType.name), ts.createTypeReferenceNode(ts.createIdentifier(rootType.name), undefined), undefined), + nodes.push(ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)], ts.factory.createVariableDeclarationList([ + ts.factory.createVariableDeclaration(ts.factory.createIdentifier(rootType.name), undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(rootType.name), undefined), undefined), ], undefined))); } } @@ -75,55 +100,93 @@ function convertIDL(rootTypes, options) { } exports.convertIDL = convertIDL; function convertTypedef(idl) { - return ts.createTypeAliasDeclaration(undefined, undefined, ts.createIdentifier(idl.name), undefined, convertType(idl.idlType)); -} -function createIterableMethods(name, keyType, valueType, pair, async) { - return [ - ts.createMethodSignature([], [], ts.createExpressionWithTypeArguments(pair ? [ts.createTupleTypeNode([keyType, valueType])] : [valueType], ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator')), async ? '[Symbol.asyncIterator]' : '[Symbol.iterator]', undefined), - ts.createMethodSignature([], [], ts.createExpressionWithTypeArguments([ts.createTupleTypeNode([keyType, valueType])], ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator')), 'entries', undefined), - ts.createMethodSignature([], [], ts.createExpressionWithTypeArguments([keyType], ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator')), 'keys', undefined), - ts.createMethodSignature([], [], ts.createExpressionWithTypeArguments([valueType], ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator')), 'values', undefined), - ts.createMethodSignature([], [ - ts.createParameter([], [], undefined, 'callbackfn', undefined, ts.createFunctionTypeNode([], [ - ts.createParameter([], [], undefined, 'value', undefined, valueType), - ts.createParameter([], [], undefined, pair ? 'key' : 'index', undefined, keyType), - ts.createParameter([], [], undefined, pair ? 'iterable' : 'array', undefined, pair ? ts.createTypeReferenceNode(name, []) : ts.createArrayTypeNode(valueType)), - ], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword))), - ts.createParameter([], [], undefined, 'thisArg', ts.createToken(ts.SyntaxKind.QuestionToken), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), - ], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), 'forEach', undefined), + return ts.factory.createTypeAliasDeclaration(undefined, ts.factory.createIdentifier(idl.name), undefined, convertType(idl.idlType)); +} +function createIterableMethods(name, keyType, valueType, pair, async, declarations) { + var result = []; + var iteratorName = async ? '[Symbol.asyncIterator]' : '[Symbol.iterator]'; + var iteratorType = ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), pair ? [ts.factory.createTupleTypeNode([keyType, valueType])] : [valueType]); + result.push(declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, iteratorName, undefined, undefined, undefined, iteratorType, undefined) + : ts.factory.createMethodSignature(undefined, iteratorName, undefined, undefined, undefined, iteratorType)); + var entriesName = 'entries'; + var entriesType = ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), [ts.factory.createTupleTypeNode([keyType, valueType])]); + result.push(declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, entriesName, undefined, undefined, undefined, entriesType, undefined) + : ts.factory.createMethodSignature(undefined, entriesName, undefined, undefined, undefined, entriesType)); + var keysName = 'keys'; + var keysType = ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), [keyType]); + result.push(declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, keysName, undefined, undefined, undefined, keysType, undefined) + : ts.factory.createMethodSignature(undefined, keysName, undefined, undefined, undefined, keysType)); + var valuesName = 'values'; + var valuesType = ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), [valueType]); + result.push(declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, valuesName, undefined, undefined, undefined, valuesType, undefined) + : ts.factory.createMethodSignature(undefined, valuesName, undefined, undefined, undefined, valuesType)); + var forEachName = 'forEach'; + var forEachParameters = [ + ts.factory.createParameterDeclaration([], undefined, 'callbackfn', undefined, ts.factory.createFunctionTypeNode([], [ + ts.factory.createParameterDeclaration([], undefined, 'value', undefined, valueType), + ts.factory.createParameterDeclaration([], undefined, pair ? 'key' : 'index', undefined, keyType), + ts.factory.createParameterDeclaration([], undefined, pair ? 'iterable' : 'array', undefined, pair ? ts.factory.createTypeReferenceNode(name, []) : ts.factory.createArrayTypeNode(valueType)), + ], ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword))), + ts.factory.createParameterDeclaration([], undefined, 'thisArg', ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), ]; + var forEachType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword); + result.push(declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, forEachName, undefined, undefined, forEachParameters, forEachType, undefined) + : ts.factory.createMethodSignature(undefined, forEachName, undefined, undefined, forEachParameters, forEachType)); + return result; } function convertInterface(idl, options) { - var members = []; + var typeMembers = []; + var classMembers = []; var inheritance = []; if ('inheritance' in idl && idl.inheritance) { - inheritance.push(ts.createExpressionWithTypeArguments(undefined, ts.createIdentifier(idl.inheritance))); + inheritance.push(ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(idl.inheritance), undefined)); } idl.members.forEach(function (member) { switch (member.type) { case 'attribute': if (options === null || options === void 0 ? void 0 : options.emscripten) { - members.push(createAttributeGetter(member)); - members.push(createAttributeSetter(member)); + classMembers.push(createAttributeGetter(member), createAttributeSetter(member), convertMemberAttribute(member, true)); + } + else { + typeMembers.push(convertMemberAttribute(member, false)); } - members.push(convertMemberAttribute(member)); break; case 'operation': - if (member.name === idl.name) { - members.push(convertMemberConstructor(member, options)); + if (options === null || options === void 0 ? void 0 : options.emscripten) { + classMembers.push(member.name === idl.name ? convertMemberConstructor(member, true) : convertMemberOperation(member, true)); } else { - members.push(convertMemberOperation(member)); + typeMembers.push(member.name === idl.name ? convertMemberConstructor(member, false) : convertMemberOperation(member, false)); } break; case 'constructor': - members.push(convertMemberConstructor(member, options)); + if (options === null || options === void 0 ? void 0 : options.emscripten) { + classMembers.push(convertMemberConstructor(member, true)); + } + else { + typeMembers.push(convertMemberConstructor(member, false)); + } break; case 'field': - members.push(convertMemberField(member)); + if (options === null || options === void 0 ? void 0 : options.emscripten) { + classMembers.push(convertMemberField(member, true)); + } + else { + typeMembers.push(convertMemberField(member, false)); + } break; case 'const': - members.push(convertMemberConst(member)); + if (options === null || options === void 0 ? void 0 : options.emscripten) { + classMembers.push(convertMemberConst(member, true)); + } + else { + typeMembers.push(convertMemberConst(member, false)); + } break; case 'iterable': { var indexedPropertyGetter = idl.members.find(function (member) { @@ -132,7 +195,13 @@ function convertInterface(idl, options) { if ((indexedPropertyGetter && member.idlType.length === 1) || member.idlType.length === 2) { var keyType = convertType(indexedPropertyGetter ? indexedPropertyGetter.arguments[0].idlType : member.idlType[0]); var valueType = convertType(member.idlType[member.idlType.length - 1]); - members.push.apply(members, createIterableMethods(idl.name, keyType, valueType, member.idlType.length === 2, member.async)); + var pairs = member.idlType.length === 2; + if (options === null || options === void 0 ? void 0 : options.emscripten) { + classMembers.push.apply(classMembers, createIterableMethods(idl.name, keyType, valueType, pairs, member.async, true)); + } + else { + typeMembers.push.apply(typeMembers, createIterableMethods(idl.name, keyType, valueType, pairs, member.async, false)); + } } break; } @@ -141,80 +210,98 @@ function convertInterface(idl, options) { break; } }); - if (options === null || options === void 0 ? void 0 : options.emscripten) { - return ts.createClassDeclaration(undefined, [], ts.createIdentifier(idl.name), undefined, !inheritance.length ? undefined : [ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, inheritance)], members); - } - return ts.createInterfaceDeclaration(undefined, [], ts.createIdentifier(idl.name), undefined, !inheritance.length ? undefined : [ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, inheritance)], members); + var name = ts.factory.createIdentifier(idl.name); + var heritageClauses = inheritance.length ? [ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, inheritance)] : undefined; + return (options === null || options === void 0 ? void 0 : options.emscripten) + ? ts.factory.createClassDeclaration([], name, undefined, heritageClauses, classMembers) + : ts.factory.createInterfaceDeclaration([], name, undefined, heritageClauses, typeMembers); } function convertInterfaceIncludes(idl) { - return ts.createInterfaceDeclaration(undefined, [], ts.createIdentifier(idl.target), undefined, [ - ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ - ts.createExpressionWithTypeArguments(undefined, ts.createIdentifier(idl.includes)), + return ts.factory.createInterfaceDeclaration([], ts.factory.createIdentifier(idl.target), undefined, [ + ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ + ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(idl.includes), undefined), ]), ], []); } function createAttributeGetter(value) { - return ts.createMethodSignature([], [], convertType(value.idlType), 'get_' + value.name, undefined); + return ts.factory.createMethodDeclaration(undefined, undefined, 'get_' + value.name, undefined, [], [], convertType(value.idlType), undefined); } function createAttributeSetter(value) { - var parameter = ts.createParameter([], [], undefined, value.name, undefined, convertType(value.idlType)); - return ts.createMethodSignature([], [parameter], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), 'set_' + value.name, undefined); + var parameter = ts.factory.createParameterDeclaration([], undefined, value.name, undefined, convertType(value.idlType)); + return ts.factory.createMethodDeclaration(undefined, undefined, 'set_' + value.name, undefined, [], [parameter], ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), undefined); } -function convertMemberOperation(idl) { +function convertMemberOperation(idl, declaration) { + var name = idl.name; var args = idl.arguments.map(convertArgument); - return ts.createMethodSignature([], args, convertType(idl.idlType), idl.name, undefined); + var type = convertType(idl.idlType); + return declaration + ? ts.factory.createMethodDeclaration(undefined, undefined, name, undefined, [], args, type, undefined) + : ts.factory.createMethodSignature(undefined, name, undefined, [], args, type); } -function convertMemberConstructor(idl, options) { +function convertMemberConstructor(idl, declaration) { var args = idl.arguments.map(convertArgument); - if (options.emscripten) { - return ts.createMethodSignature([], args, undefined, 'constructor', undefined); - } - return ts.createConstructSignature([], args, undefined); + return declaration + ? ts.factory.createMethodDeclaration(undefined, undefined, 'constructor', undefined, [], args, undefined, undefined) + : ts.factory.createConstructSignature([], args, undefined); } -function convertMemberField(idl) { - var optional = !idl.required ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined; - return ts.createPropertySignature(undefined, ts.createIdentifier(idl.name), optional, convertType(idl.idlType), undefined); +function convertMemberField(idl, declaration) { + var name = ts.factory.createIdentifier(idl.name); + var optional = !idl.required ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined; + var type = convertType(idl.idlType); + return declaration + ? ts.factory.createPropertyDeclaration(undefined, name, optional, type, undefined) + : ts.factory.createPropertySignature(undefined, name, optional, type); } -function convertMemberConst(idl) { - return ts.createPropertySignature([ts.createModifier(ts.SyntaxKind.ReadonlyKeyword)], ts.createIdentifier(idl.name), undefined, convertType(idl.idlType), undefined); +function convertMemberConst(idl, declaration) { + var modifiers = [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)]; + var name = ts.factory.createIdentifier(idl.name); + var type = convertType(idl.idlType); + return declaration + ? ts.factory.createPropertyDeclaration(modifiers, name, undefined, type, undefined) + : ts.factory.createPropertySignature(modifiers, name, undefined, type); } -function convertMemberAttribute(idl) { - return ts.createPropertySignature([idl.readonly ? ts.createModifier(ts.SyntaxKind.ReadonlyKeyword) : null].filter(function (it) { return it != null; }), ts.createIdentifier(idl.name), undefined, convertType(idl.idlType), undefined); +function convertMemberAttribute(idl, declaration) { + var modifiers = [idl.readonly ? ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword) : null].filter(function (it) { return it != null; }); + var name = ts.factory.createIdentifier(idl.name); + var type = convertType(idl.idlType); + return declaration + ? ts.factory.createPropertyDeclaration(modifiers, name, undefined, type, undefined) + : ts.factory.createPropertySignature(modifiers, name, undefined, type); } function convertArgument(idl) { - var optional = idl.optional ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined; - return ts.createParameter([], [], undefined, idl.name, optional, convertType(idl.idlType)); + var optional = idl.optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined; + return ts.factory.createParameterDeclaration([], undefined, idl.name, optional, convertType(idl.idlType)); } function convertType(idl) { if (typeof idl.idlType === 'string') { var type = baseTypeConversionMap.get(idl.idlType) || idl.idlType; switch (type) { case 'number': - return ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); case 'string': - return ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); case 'void': - return ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword); default: - return ts.createTypeReferenceNode(type, []); + return ts.factory.createTypeReferenceNode(type, []); } } if (idl.generic) { var type = baseTypeConversionMap.get(idl.generic) || idl.generic; - return ts.createTypeReferenceNode(ts.createIdentifier(type), idl.idlType.map(convertType)); + return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type), idl.idlType.map(convertType)); } if (idl.union) { - return ts.createUnionTypeNode(idl.idlType.map(convertType)); + return ts.factory.createUnionTypeNode(idl.idlType.map(convertType)); } console.log(newUnsupportedError('Unsupported IDL type', idl)); - return ts.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword); } function convertEnum(idl) { - return ts.createTypeAliasDeclaration(undefined, undefined, ts.createIdentifier(idl.name), undefined, ts.createUnionTypeNode(idl.values.map(function (it) { return ts.createLiteralTypeNode(ts.createStringLiteral(it.value)); }))); + return ts.factory.createTypeAliasDeclaration(undefined, ts.factory.createIdentifier(idl.name), undefined, ts.factory.createUnionTypeNode(idl.values.map(function (it) { return ts.factory.createLiteralTypeNode(ts.createStringLiteral(it.value)); }))); } function convertCallback(idl) { - return ts.createTypeAliasDeclaration(undefined, undefined, ts.createIdentifier(idl.name), undefined, ts.createFunctionTypeNode(undefined, idl.arguments.map(convertArgument), convertType(idl.idlType))); + return ts.factory.createTypeAliasDeclaration(undefined, ts.factory.createIdentifier(idl.name), undefined, ts.factory.createFunctionTypeNode(undefined, idl.arguments.map(convertArgument), convertType(idl.idlType))); } function newUnsupportedError(message, idl) { - return new Error("\n " + message + "\n " + JSON.stringify(idl, null, 2) + "\n\n Please file an issue at https://github.com/giniedp/webidl2ts and provide the used idl file or example.\n"); + return new Error("\n ".concat(message, "\n ").concat(JSON.stringify(idl, null, 2), "\n\n Please file an issue at https://github.com/giniedp/webidl2ts and provide the used idl file or example.\n")); } diff --git a/dist/fetch-idl.js b/dist/fetch-idl.js index 633c4ce..3ce49ae 100644 --- a/dist/fetch-idl.js +++ b/dist/fetch-idl.js @@ -1,4 +1,27 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -14,7 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { @@ -37,14 +60,14 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchIDL = void 0; -var https = require("https"); -var fs = require("fs"); +var https = __importStar(require("https")); +var fs = __importStar(require("fs")); var jsdom_1 = require("jsdom"); var idlSelector = [ 'pre.idl:not(.extract):not(.example)', 'pre.code code.idl-code', 'pre:not(.extract) code.idl', - '#permission-registry + pre.highlight', + '#permission-registry + pre.highlight', // Permissions ].join(','); function fetchIDL(uri) { return __awaiter(this, void 0, void 0, function () { diff --git a/dist/fixes.js b/dist/fixes.js index 939aa76..ac353f6 100644 --- a/dist/fixes.js +++ b/dist/fixes.js @@ -26,11 +26,11 @@ exports.fixes = { var inheritance = []; idlString = idlString.replace(/([a-zA-Z0-9]+) implements ([a-zA-Z0-9]+);/gi, function (line, left, right) { inheritance.push({ left: left, right: right }); - return "// " + line; + return "// ".concat(line); }); inheritance.forEach(function (_a) { var left = _a.left, right = _a.right; - idlString = idlString.replace(new RegExp("interface " + left + " {"), "interface " + left + ": " + right + " {"); + idlString = idlString.replace(new RegExp("interface ".concat(left, " {")), "interface ".concat(left, ": ").concat(right, " {")); }); return idlString; }, @@ -44,7 +44,7 @@ exports.fixes = { // current solution: use sequence type return idlString .replace(/attribute (\w+)\[\]/gi, function (match, group) { - return "attribute FrozenArray<" + group + ">"; + return "attribute FrozenArray<".concat(group, ">"); }) .replace(/float\[\]/gi, 'FrozenArray') .replace(/long\[\]/gi, 'FrozenArray'); diff --git a/dist/index.d.ts b/dist/index.d.ts index b7e31f9..41955b7 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -2,3 +2,4 @@ export * from './convert-idl'; export * from './print-ts'; export * from './parse-idl'; export * from './fetch-idl'; +export * from './types'; diff --git a/dist/index.js b/dist/index.js index 7e67267..8773f29 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,7 +1,11 @@ "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; @@ -14,3 +18,4 @@ __exportStar(require("./convert-idl"), exports); __exportStar(require("./print-ts"), exports); __exportStar(require("./parse-idl"), exports); __exportStar(require("./fetch-idl"), exports); +__exportStar(require("./types"), exports); diff --git a/dist/parse-idl.js b/dist/parse-idl.js index 856826f..dd78b5e 100644 --- a/dist/parse-idl.js +++ b/dist/parse-idl.js @@ -1,4 +1,27 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -14,7 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { @@ -37,7 +60,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseIDL = void 0; -var webidl2 = require("webidl2"); +var webidl2 = __importStar(require("webidl2")); function parseIDL(idlString, options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { diff --git a/dist/print-ts.js b/dist/print-ts.js index 4ecdbdd..4ddd021 100644 --- a/dist/print-ts.js +++ b/dist/print-ts.js @@ -1,14 +1,39 @@ "use strict"; -var __spreadArrays = (this && this.__spreadArrays) || function () { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.printEmscriptenModule = exports.printTs = void 0; -var ts = require("typescript"); +var ts = __importStar(require("typescript")); function printTs(nodes) { var file = ts.createSourceFile("index.d.ts", '', ts.ScriptTarget.Latest, false, ts.ScriptKind.TS); var printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); @@ -20,36 +45,36 @@ function printEmscriptenModule(moduleName, nodes, defaultExport) { if (defaultExport) { // adds default export // export default Module; - result.push(ts.createExportAssignment( - /* decorators */ [], - /* modifiers */ [ts.createModifier(ts.SyntaxKind.DefaultKeyword)], + result.push(ts.factory.createExportAssignment( + /* modifiers */ [ts.factory.createModifier(ts.SyntaxKind.DefaultKeyword)], /* isExportEquals */ false, - /* expression */ ts.createIdentifier(moduleName))); + /* expression */ ts.factory.createIdentifier(moduleName))); } // adds module function // declare function Module(target?: T): Promise; - result.push(ts.createFunctionDeclaration( - /* decorators */ [], - /* modifiers */ [ts.createModifier(ts.SyntaxKind.DeclareKeyword)], + result.push(ts.factory.createFunctionDeclaration( + /* modifiers */ [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)], /* asteriskToken */ undefined, /* name */ moduleName, - /* typeParameters */ [ts.createTypeParameterDeclaration('T')], + /* typeParameters */ [ts.factory.createTypeParameterDeclaration(undefined, 'T')], /* parameters */ [ - ts.createParameter([], [], undefined, 'target', ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode('T', [])), + ts.factory.createParameterDeclaration([], undefined, 'target', ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createTypeReferenceNode('T', [])), ], - /* type */ ts.createTypeReferenceNode('Promise', [ - ts.createIntersectionTypeNode([ts.createTypeReferenceNode('T', []), ts.createTypeQueryNode(ts.createIdentifier(moduleName))]), + /* type */ ts.factory.createTypeReferenceNode('Promise', [ + ts.factory.createIntersectionTypeNode([ + ts.factory.createTypeReferenceNode('T', []), + ts.factory.createTypeQueryNode(ts.factory.createIdentifier(moduleName)), + ]), ]), /* body */ undefined)); // adds module declaration with all types // export declare module Module { // ... // } - result.push(ts.createModuleDeclaration( - /* decorators */ [], - /* modifiers */ [ts.createModifier(ts.SyntaxKind.DeclareKeyword)], - /* name */ ts.createIdentifier(moduleName), - /* body */ ts.createModuleBlock(__spreadArrays(emscriptenAdditions(), nodes)))); + result.push(ts.factory.createModuleDeclaration( + /* modifiers */ [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)], + /* name */ ts.factory.createIdentifier(moduleName), + /* body */ ts.factory.createModuleBlock(__spreadArray(__spreadArray([], emscriptenAdditions(), true), nodes, true)))); return printTs(result); } exports.printEmscriptenModule = printEmscriptenModule; @@ -58,27 +83,28 @@ function emscriptenAdditions() { // adds emscripten specific types // // function destroy(obj: any): void; - result.push(ts.createFunctionDeclaration( - /* decorators */ [], + result.push(ts.factory.createFunctionDeclaration( /* modifiers */ [], /* asteriskToken */ undefined, /* name */ 'destroy', /* typeParameters */ [], - /* parameters */ [ts.createParameter([], [], undefined, 'obj', undefined, ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))], - /* type */ ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), + /* parameters */ [ + ts.factory.createParameterDeclaration([], undefined, 'obj', undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ], + /* type */ ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), /* body */ undefined)); // adds malloc function // // function _malloc(size: number): number; - result.push(ts.createFunctionDeclaration(undefined, undefined, undefined, ts.createIdentifier('_malloc'), undefined, [ - ts.createParameter(undefined, undefined, undefined, ts.createIdentifier('size'), undefined, ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined), - ], ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined)); + result.push(ts.factory.createFunctionDeclaration(undefined, undefined, ts.factory.createIdentifier('_malloc'), undefined, [ + ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier('size'), undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined), + ], ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined)); // adds free function // // function _free(size: number): number; - result.push(ts.createFunctionDeclaration(undefined, undefined, undefined, ts.createIdentifier('_free'), undefined, [ - ts.createParameter(undefined, undefined, undefined, ts.createIdentifier('ptr'), undefined, ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined), - ], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), undefined)); + result.push(ts.factory.createFunctionDeclaration(undefined, undefined, ts.factory.createIdentifier('_free'), undefined, [ + ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier('ptr'), undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined), + ], ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), undefined)); // adds HEAP* properties var heaps = [ ['HEAP8', Int8Array.name], @@ -92,8 +118,8 @@ function emscriptenAdditions() { ]; for (var _i = 0, heaps_1 = heaps; _i < heaps_1.length; _i++) { var _a = heaps_1[_i], name_1 = _a[0], type = _a[1]; - result.push(ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ - ts.createVariableDeclaration(ts.createIdentifier(name_1), ts.createTypeReferenceNode(ts.createIdentifier(type), undefined), undefined), + result.push(ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList([ + ts.factory.createVariableDeclaration(ts.factory.createIdentifier(name_1), undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type), undefined), undefined), ], ts.NodeFlags.Const))); } return result; diff --git a/package.json b/package.json index ec92e57..0e0d93e 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { "name": "webidl2ts", - "version": "1.0.4", + "version": "2.0.0", "description": "Converts Web IDL to Typescript (.d.ts)", "main": "dist/index.js", "scripts": { "build": "tsc && chmod 755 dist/cli.js", "lint": "tsc --noEmit", "start": "yarn build && ./dist/cli.js", - "format": "yarn prettier --write ." + "format": "yarn prettier --write .", + "test": "node --test --require ts-node/register ./test/*.spec.ts" }, "repository": { "type": "git", @@ -23,18 +24,18 @@ "LICENSE.md" ], "devDependencies": { - "@types/node": "^14.14.6", + "@types/node": "^18.0.0", "@types/webidl2": "^23.13.5", "@types/yargs": "^15.0.9", "@typescript-eslint/eslint-plugin": "^4.6.1", "@typescript-eslint/parser": "^4.6.1", "eslint": "^7.12.1", "prettier": "^2.1.2", - "ts-node": "^9.0.0" + "ts-node": "^10.0.0" }, "dependencies": { "jsdom": "^16.4.0", - "typescript": "^4.0.5", + "typescript": "^4.9.3", "webidl2": "^23.13.0", "yargs": "^16.1.0" }, diff --git a/src/convert-idl.ts b/src/convert-idl.ts index 57c8641..bf0b2cd 100644 --- a/src/convert-idl.ts +++ b/src/convert-idl.ts @@ -1,3 +1,4 @@ +import { MethodDeclaration } from 'typescript' import * as webidl2 from 'webidl2' import * as ts from 'typescript' import { Options } from './types' @@ -45,13 +46,14 @@ export function convertIDL(rootTypes: webidl2.IDLRootType[], options?: Options): for (const attr of rootType.extAttrs) { if (attr.name === 'Exposed' && attr.rhs?.value === 'Window') { nodes.push( - ts.createVariableStatement( - [ts.createModifier(ts.SyntaxKind.DeclareKeyword)], - ts.createVariableDeclarationList( + ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)], + ts.factory.createVariableDeclarationList( [ - ts.createVariableDeclaration( - ts.createIdentifier(rootType.name), - ts.createTypeReferenceNode(ts.createIdentifier(rootType.name), undefined), + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(rootType.name), + undefined, + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(rootType.name), undefined), undefined, ), ], @@ -83,118 +85,175 @@ export function convertIDL(rootTypes: webidl2.IDLRootType[], options?: Options): } function convertTypedef(idl: webidl2.TypedefType) { - return ts.createTypeAliasDeclaration(undefined, undefined, ts.createIdentifier(idl.name), undefined, convertType(idl.idlType)) + return ts.factory.createTypeAliasDeclaration(undefined, ts.factory.createIdentifier(idl.name), undefined, convertType(idl.idlType)) } -function createIterableMethods(name: string, keyType: ts.TypeNode, valueType: ts.TypeNode, pair: boolean, async: boolean) { - return [ - ts.createMethodSignature( - [], - [], - ts.createExpressionWithTypeArguments( - pair ? [ts.createTupleTypeNode([keyType, valueType])] : [valueType], - ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), - ), - async ? '[Symbol.asyncIterator]' : '[Symbol.iterator]', - undefined, - ), - ts.createMethodSignature( - [], +function createIterableMethods( + name: string, + keyType: ts.TypeNode, + valueType: ts.TypeNode, + pair: boolean, + async: boolean, + declarations: true, +): ts.MethodDeclaration[] +function createIterableMethods( + name: string, + keyType: ts.TypeNode, + valueType: ts.TypeNode, + pair: boolean, + async: boolean, + declarations: false, +): ts.MethodSignature[] +function createIterableMethods( + name: string, + keyType: ts.TypeNode, + valueType: ts.TypeNode, + pair: boolean, + async: boolean, + declarations: boolean, +): ts.MethodDeclaration[] | ts.MethodSignature[] { + const result = [] + + const iteratorName = async ? '[Symbol.asyncIterator]' : '[Symbol.iterator]' + const iteratorType = ts.factory.createExpressionWithTypeArguments( + ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), + pair ? [ts.factory.createTupleTypeNode([keyType, valueType])] : [valueType], + ) + result.push( + declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, iteratorName, undefined, undefined, undefined, iteratorType, undefined) + : ts.factory.createMethodSignature(undefined, iteratorName, undefined, undefined, undefined, iteratorType), + ) + + const entriesName = 'entries' + const entriesType = ts.factory.createExpressionWithTypeArguments( + ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), + [ts.factory.createTupleTypeNode([keyType, valueType])], + ) + result.push( + declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, entriesName, undefined, undefined, undefined, entriesType, undefined) + : ts.factory.createMethodSignature(undefined, entriesName, undefined, undefined, undefined, entriesType), + ) + + const keysName = 'keys' + const keysType = ts.factory.createExpressionWithTypeArguments( + ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), + [keyType], + ) + result.push( + declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, keysName, undefined, undefined, undefined, keysType, undefined) + : ts.factory.createMethodSignature(undefined, keysName, undefined, undefined, undefined, keysType), + ) + + const valuesName = 'values' + const valuesType = ts.factory.createExpressionWithTypeArguments( + ts.factory.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), + [valueType], + ) + result.push( + declarations + ? ts.factory.createMethodDeclaration(undefined, undefined, valuesName, undefined, undefined, undefined, valuesType, undefined) + : ts.factory.createMethodSignature(undefined, valuesName, undefined, undefined, undefined, valuesType), + ) + + const forEachName = 'forEach' + const forEachParameters = [ + ts.factory.createParameterDeclaration( [], - ts.createExpressionWithTypeArguments( - [ts.createTupleTypeNode([keyType, valueType])], - ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator'), - ), - 'entries', undefined, - ), - ts.createMethodSignature( - [], - [], - ts.createExpressionWithTypeArguments([keyType], ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator')), - 'keys', + 'callbackfn', undefined, + ts.factory.createFunctionTypeNode( + [], + [ + ts.factory.createParameterDeclaration([], undefined, 'value', undefined, valueType), + ts.factory.createParameterDeclaration([], undefined, pair ? 'key' : 'index', undefined, keyType), + ts.factory.createParameterDeclaration( + [], + undefined, + pair ? 'iterable' : 'array', + undefined, + pair ? ts.factory.createTypeReferenceNode(name, []) : ts.factory.createArrayTypeNode(valueType), + ), + ], + ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), + ), ), - ts.createMethodSignature( - [], + ts.factory.createParameterDeclaration( [], - ts.createExpressionWithTypeArguments([valueType], ts.createIdentifier(async ? 'AsyncIterableIterator' : 'IterableIterator')), - 'values', undefined, + 'thisArg', + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), ), - ts.createMethodSignature( - [], - [ - ts.createParameter( - [], - [], + ] + const forEachType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword) + + result.push( + declarations + ? ts.factory.createMethodDeclaration( undefined, - 'callbackfn', undefined, - ts.createFunctionTypeNode( - [], - [ - ts.createParameter([], [], undefined, 'value', undefined, valueType), - ts.createParameter([], [], undefined, pair ? 'key' : 'index', undefined, keyType), - ts.createParameter( - [], - [], - undefined, - pair ? 'iterable' : 'array', - undefined, - pair ? ts.createTypeReferenceNode(name, []) : ts.createArrayTypeNode(valueType), - ), - ], - ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), - ), - ), - ts.createParameter( - [], - [], + forEachName, undefined, - 'thisArg', - ts.createToken(ts.SyntaxKind.QuestionToken), - ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), - ), - ], - ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), - 'forEach', - undefined, - ), - ] + undefined, + forEachParameters, + forEachType, + undefined, + ) + : ts.factory.createMethodSignature(undefined, forEachName, undefined, undefined, forEachParameters, forEachType), + ) + + return result } function convertInterface(idl: webidl2.InterfaceType | webidl2.DictionaryType | webidl2.InterfaceMixinType, options?: Options) { - const members: ts.TypeElement[] = [] + const typeMembers: ts.TypeElement[] = [] + const classMembers: ts.ClassElement[] = [] + const inheritance = [] if ('inheritance' in idl && idl.inheritance) { - inheritance.push(ts.createExpressionWithTypeArguments(undefined, ts.createIdentifier(idl.inheritance))) + inheritance.push(ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(idl.inheritance), undefined)) } idl.members.forEach((member: webidl2.IDLInterfaceMemberType | webidl2.FieldType) => { switch (member.type) { case 'attribute': if (options?.emscripten) { - members.push(createAttributeGetter(member)) - members.push(createAttributeSetter(member)) + classMembers.push(createAttributeGetter(member), createAttributeSetter(member), convertMemberAttribute(member, true)) + } else { + typeMembers.push(convertMemberAttribute(member, false)) } - members.push(convertMemberAttribute(member)) break case 'operation': - if (member.name === idl.name) { - members.push(convertMemberConstructor(member, options)) + if (options?.emscripten) { + classMembers.push(member.name === idl.name ? convertMemberConstructor(member, true) : convertMemberOperation(member, true)) } else { - members.push(convertMemberOperation(member)) + typeMembers.push(member.name === idl.name ? convertMemberConstructor(member, false) : convertMemberOperation(member, false)) } break case 'constructor': - members.push(convertMemberConstructor(member, options)) + if (options?.emscripten) { + classMembers.push(convertMemberConstructor(member, true)) + } else { + typeMembers.push(convertMemberConstructor(member, false)) + } break case 'field': - members.push(convertMemberField(member)) + if (options?.emscripten) { + classMembers.push(convertMemberField(member, true)) + } else { + typeMembers.push(convertMemberField(member, false)) + } break case 'const': - members.push(convertMemberConst(member)) + if (options?.emscripten) { + classMembers.push(convertMemberConst(member, true)) + } else { + typeMembers.push(convertMemberConst(member, false)) + } break case 'iterable': { type Members = Array @@ -206,7 +265,12 @@ function convertInterface(idl: webidl2.InterfaceType | webidl2.DictionaryType | if ((indexedPropertyGetter && member.idlType.length === 1) || member.idlType.length === 2) { const keyType = convertType(indexedPropertyGetter ? indexedPropertyGetter.arguments[0].idlType : member.idlType[0]) const valueType = convertType(member.idlType[member.idlType.length - 1]) - members.push(...createIterableMethods(idl.name, keyType, valueType, member.idlType.length === 2, member.async)) + const pairs = member.idlType.length === 2 + if (options?.emscripten) { + classMembers.push(...createIterableMethods(idl.name, keyType, valueType, pairs, member.async, true)) + } else { + typeMembers.push(...createIterableMethods(idl.name, keyType, valueType, pairs, member.async, false)) + } } break } @@ -216,92 +280,119 @@ function convertInterface(idl: webidl2.InterfaceType | webidl2.DictionaryType | } }) - if (options?.emscripten) { - return ts.createClassDeclaration( - undefined, - [], - ts.createIdentifier(idl.name), - undefined, - !inheritance.length ? undefined : [ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, inheritance)], - members as any, // TODO: - ) - } + const name = ts.factory.createIdentifier(idl.name) + const heritageClauses = inheritance.length ? [ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, inheritance)] : undefined - return ts.createInterfaceDeclaration( - undefined, - [], - ts.createIdentifier(idl.name), - undefined, - !inheritance.length ? undefined : [ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, inheritance)], - members, - ) + return options?.emscripten + ? ts.factory.createClassDeclaration([], name, undefined, heritageClauses, classMembers) + : ts.factory.createInterfaceDeclaration([], name, undefined, heritageClauses, typeMembers) } function convertInterfaceIncludes(idl: webidl2.IncludesType) { - return ts.createInterfaceDeclaration( - undefined, + return ts.factory.createInterfaceDeclaration( [], - ts.createIdentifier(idl.target), + ts.factory.createIdentifier(idl.target), undefined, [ - ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ - ts.createExpressionWithTypeArguments(undefined, ts.createIdentifier(idl.includes)), + ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ + ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(idl.includes), undefined), ]), ], [], ) } -function createAttributeGetter(value: webidl2.AttributeMemberType) { - return ts.createMethodSignature([], [], convertType(value.idlType), 'get_' + value.name, undefined) +function createAttributeGetter(value: webidl2.AttributeMemberType): MethodDeclaration { + return ts.factory.createMethodDeclaration( + undefined, + undefined, + 'get_' + value.name, + undefined, + [], + [], + convertType(value.idlType), + undefined, + ) } -function createAttributeSetter(value: webidl2.AttributeMemberType) { - const parameter = ts.createParameter([], [], undefined, value.name, undefined, convertType(value.idlType)) - return ts.createMethodSignature([], [parameter], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), 'set_' + value.name, undefined) +function createAttributeSetter(value: webidl2.AttributeMemberType): MethodDeclaration { + const parameter = ts.factory.createParameterDeclaration([], undefined, value.name, undefined, convertType(value.idlType)) + return ts.factory.createMethodDeclaration( + undefined, + undefined, + 'set_' + value.name, + undefined, + [], + [parameter], + ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), + undefined, + ) } -function convertMemberOperation(idl: webidl2.OperationMemberType) { +function convertMemberOperation(idl: webidl2.OperationMemberType, declaration: true): ts.MethodDeclaration +function convertMemberOperation(idl: webidl2.OperationMemberType, declaration: false): ts.MethodSignature +function convertMemberOperation(idl: webidl2.OperationMemberType, declaration: boolean): ts.MethodSignature | ts.MethodDeclaration { + const name = idl.name const args = idl.arguments.map(convertArgument) - return ts.createMethodSignature([], args, convertType(idl.idlType), idl.name, undefined) + const type = convertType(idl.idlType) + + return declaration + ? ts.factory.createMethodDeclaration(undefined, undefined, name, undefined, [], args, type, undefined) + : ts.factory.createMethodSignature(undefined, name, undefined, [], args, type) } -function convertMemberConstructor(idl: webidl2.ConstructorMemberType | webidl2.OperationMemberType, options?: Options) { +function convertMemberConstructor(idl: webidl2.ConstructorMemberType | webidl2.OperationMemberType, declaration: true): ts.MethodDeclaration +function convertMemberConstructor( + idl: webidl2.ConstructorMemberType | webidl2.OperationMemberType, + declaration: false, +): ts.ConstructSignatureDeclaration +function convertMemberConstructor( + idl: webidl2.ConstructorMemberType | webidl2.OperationMemberType, + declaration: boolean, +): ts.MethodDeclaration | ts.ConstructSignatureDeclaration { const args = idl.arguments.map(convertArgument) - if (options.emscripten) { - return ts.createMethodSignature([], args, undefined, 'constructor', undefined) - } - return ts.createConstructSignature([], args, undefined) + return declaration + ? ts.factory.createMethodDeclaration(undefined, undefined, 'constructor', undefined, [], args, undefined, undefined) + : ts.factory.createConstructSignature([], args, undefined) } -function convertMemberField(idl: webidl2.FieldType) { - const optional = !idl.required ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined - return ts.createPropertySignature(undefined, ts.createIdentifier(idl.name), optional, convertType(idl.idlType), undefined) +function convertMemberField(idl: webidl2.FieldType, declaration: true): ts.PropertyDeclaration +function convertMemberField(idl: webidl2.FieldType, declaration: false): ts.PropertySignature +function convertMemberField(idl: webidl2.FieldType, declaration: boolean): ts.PropertyDeclaration | ts.PropertySignature { + const name = ts.factory.createIdentifier(idl.name) + const optional = !idl.required ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined + const type = convertType(idl.idlType) + return declaration + ? ts.factory.createPropertyDeclaration(undefined, name, optional, type, undefined) + : ts.factory.createPropertySignature(undefined, name, optional, type) } -function convertMemberConst(idl: webidl2.ConstantMemberType) { - return ts.createPropertySignature( - [ts.createModifier(ts.SyntaxKind.ReadonlyKeyword)], - ts.createIdentifier(idl.name), - undefined, - convertType(idl.idlType), - undefined, - ) +function convertMemberConst(idl: webidl2.ConstantMemberType, declaration: true): ts.PropertyDeclaration +function convertMemberConst(idl: webidl2.ConstantMemberType, declaration: false): ts.PropertySignature +function convertMemberConst(idl: webidl2.ConstantMemberType, declaration: boolean): ts.PropertyDeclaration | ts.PropertySignature { + const modifiers = [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] + const name = ts.factory.createIdentifier(idl.name) + const type = convertType(idl.idlType) + return declaration + ? ts.factory.createPropertyDeclaration(modifiers, name, undefined, type, undefined) + : ts.factory.createPropertySignature(modifiers, name, undefined, type) } -function convertMemberAttribute(idl: webidl2.AttributeMemberType) { - return ts.createPropertySignature( - [idl.readonly ? ts.createModifier(ts.SyntaxKind.ReadonlyKeyword) : null].filter((it) => it != null), - ts.createIdentifier(idl.name), - undefined, - convertType(idl.idlType), - undefined, - ) +function convertMemberAttribute(idl: webidl2.AttributeMemberType, declaration: true): ts.PropertyDeclaration +function convertMemberAttribute(idl: webidl2.AttributeMemberType, declaration: false): ts.PropertySignature +function convertMemberAttribute(idl: webidl2.AttributeMemberType, declaration: boolean): ts.PropertyDeclaration | ts.PropertySignature { + const modifiers = [idl.readonly ? ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword) : null].filter((it) => it != null) + const name = ts.factory.createIdentifier(idl.name) + const type = convertType(idl.idlType) + + return declaration + ? ts.factory.createPropertyDeclaration(modifiers, name, undefined, type, undefined) + : ts.factory.createPropertySignature(modifiers, name, undefined, type) } function convertArgument(idl: webidl2.Argument) { - const optional = idl.optional ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined - return ts.createParameter([], [], undefined, idl.name, optional, convertType(idl.idlType)) + const optional = idl.optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined + return ts.factory.createParameterDeclaration([], undefined, idl.name, optional, convertType(idl.idlType)) } function convertType(idl: webidl2.IDLTypeDescription): ts.TypeNode { @@ -309,44 +400,42 @@ function convertType(idl: webidl2.IDLTypeDescription): ts.TypeNode { const type = baseTypeConversionMap.get(idl.idlType) || idl.idlType switch (type) { case 'number': - return ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword) + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword) case 'string': - return ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) case 'void': - return ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword) + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword) default: - return ts.createTypeReferenceNode(type, []) + return ts.factory.createTypeReferenceNode(type, []) } } if (idl.generic) { const type = baseTypeConversionMap.get(idl.generic) || idl.generic - return ts.createTypeReferenceNode(ts.createIdentifier(type), idl.idlType.map(convertType)) + return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type), idl.idlType.map(convertType)) } if (idl.union) { - return ts.createUnionTypeNode(idl.idlType.map(convertType)) + return ts.factory.createUnionTypeNode(idl.idlType.map(convertType)) } console.log(newUnsupportedError('Unsupported IDL type', idl)) - return ts.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword) + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword) } function convertEnum(idl: webidl2.EnumType) { - return ts.createTypeAliasDeclaration( + return ts.factory.createTypeAliasDeclaration( undefined, + ts.factory.createIdentifier(idl.name), undefined, - ts.createIdentifier(idl.name), - undefined, - ts.createUnionTypeNode(idl.values.map((it) => ts.createLiteralTypeNode(ts.createStringLiteral(it.value)))), + ts.factory.createUnionTypeNode(idl.values.map((it) => ts.factory.createLiteralTypeNode(ts.createStringLiteral(it.value)))), ) } function convertCallback(idl: webidl2.CallbackType) { - return ts.createTypeAliasDeclaration( - undefined, + return ts.factory.createTypeAliasDeclaration( undefined, - ts.createIdentifier(idl.name), + ts.factory.createIdentifier(idl.name), undefined, - ts.createFunctionTypeNode(undefined, idl.arguments.map(convertArgument), convertType(idl.idlType)), + ts.factory.createFunctionTypeNode(undefined, idl.arguments.map(convertArgument), convertType(idl.idlType)), ) } diff --git a/src/index.ts b/src/index.ts index 0320686..3f95a9e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,3 +2,4 @@ export * from './convert-idl' export * from './print-ts' export * from './parse-idl' export * from './fetch-idl' +export * from './types' diff --git a/src/print-ts.ts b/src/print-ts.ts index b116325..92b3f29 100644 --- a/src/print-ts.ts +++ b/src/print-ts.ts @@ -12,11 +12,10 @@ export function printEmscriptenModule(moduleName: string, nodes: ts.Statement[], // adds default export // export default Module; result.push( - ts.createExportAssignment( - /* decorators */ [], - /* modifiers */ [ts.createModifier(ts.SyntaxKind.DefaultKeyword)], + ts.factory.createExportAssignment( + /* modifiers */ [ts.factory.createModifier(ts.SyntaxKind.DefaultKeyword)], /* isExportEquals */ false, - /* expression */ ts.createIdentifier(moduleName), + /* expression */ ts.factory.createIdentifier(moduleName), ), ) } @@ -24,17 +23,25 @@ export function printEmscriptenModule(moduleName: string, nodes: ts.Statement[], // adds module function // declare function Module(target?: T): Promise; result.push( - ts.createFunctionDeclaration( - /* decorators */ [], - /* modifiers */ [ts.createModifier(ts.SyntaxKind.DeclareKeyword)], + ts.factory.createFunctionDeclaration( + /* modifiers */ [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)], /* asteriskToken */ undefined, /* name */ moduleName, - /* typeParameters */ [ts.createTypeParameterDeclaration('T')], + /* typeParameters */ [ts.factory.createTypeParameterDeclaration(undefined, 'T')], /* parameters */ [ - ts.createParameter([], [], undefined, 'target', ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode('T', [])), + ts.factory.createParameterDeclaration( + [], + undefined, + 'target', + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createTypeReferenceNode('T', []), + ), ], - /* type */ ts.createTypeReferenceNode('Promise', [ - ts.createIntersectionTypeNode([ts.createTypeReferenceNode('T', []), ts.createTypeQueryNode(ts.createIdentifier(moduleName))]), + /* type */ ts.factory.createTypeReferenceNode('Promise', [ + ts.factory.createIntersectionTypeNode([ + ts.factory.createTypeReferenceNode('T', []), + ts.factory.createTypeQueryNode(ts.factory.createIdentifier(moduleName)), + ]), ]), /* body */ undefined, ), @@ -45,11 +52,10 @@ export function printEmscriptenModule(moduleName: string, nodes: ts.Statement[], // ... // } result.push( - ts.createModuleDeclaration( - /* decorators */ [], - /* modifiers */ [ts.createModifier(ts.SyntaxKind.DeclareKeyword)], - /* name */ ts.createIdentifier(moduleName), - /* body */ ts.createModuleBlock([...emscriptenAdditions(), ...nodes]), + ts.factory.createModuleDeclaration( + /* modifiers */ [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)], + /* name */ ts.factory.createIdentifier(moduleName), + /* body */ ts.factory.createModuleBlock([...emscriptenAdditions(), ...nodes]), ), ) @@ -63,14 +69,15 @@ function emscriptenAdditions() { // // function destroy(obj: any): void; result.push( - ts.createFunctionDeclaration( - /* decorators */ [], + ts.factory.createFunctionDeclaration( /* modifiers */ [], /* asteriskToken */ undefined, /* name */ 'destroy', /* typeParameters */ [], - /* parameters */ [ts.createParameter([], [], undefined, 'obj', undefined, ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))], - /* type */ ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), + /* parameters */ [ + ts.factory.createParameterDeclaration([], undefined, 'obj', undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ], + /* type */ ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), /* body */ undefined, ), ) @@ -79,24 +86,22 @@ function emscriptenAdditions() { // // function _malloc(size: number): number; result.push( - ts.createFunctionDeclaration( - undefined, + ts.factory.createFunctionDeclaration( undefined, undefined, - ts.createIdentifier('_malloc'), + ts.factory.createIdentifier('_malloc'), undefined, [ - ts.createParameter( + ts.factory.createParameterDeclaration( undefined, undefined, + ts.factory.createIdentifier('size'), undefined, - ts.createIdentifier('size'), - undefined, - ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined, ), ], - ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined, ), ) @@ -105,24 +110,22 @@ function emscriptenAdditions() { // // function _free(size: number): number; result.push( - ts.createFunctionDeclaration( - undefined, + ts.factory.createFunctionDeclaration( undefined, undefined, - ts.createIdentifier('_free'), + ts.factory.createIdentifier('_free'), undefined, [ - ts.createParameter( + ts.factory.createParameterDeclaration( undefined, undefined, + ts.factory.createIdentifier('ptr'), undefined, - ts.createIdentifier('ptr'), - undefined, - ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), undefined, ), ], - ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), undefined, ), ) @@ -139,13 +142,14 @@ function emscriptenAdditions() { ] for (const [name, type] of heaps) { result.push( - ts.createVariableStatement( + ts.factory.createVariableStatement( undefined, - ts.createVariableDeclarationList( + ts.factory.createVariableDeclarationList( [ - ts.createVariableDeclaration( - ts.createIdentifier(name), - ts.createTypeReferenceNode(ts.createIdentifier(type), undefined), + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(name), + undefined, + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type), undefined), undefined, ), ], diff --git a/test/default.d.ts b/test/default.d.ts new file mode 100644 index 0000000..d676be7 --- /dev/null +++ b/test/default.d.ts @@ -0,0 +1,4 @@ +interface Test { + add(a: number, b: number): number + remove(a: number, b: number): number +} diff --git a/test/emscripten.d.ts b/test/emscripten.d.ts new file mode 100644 index 0000000..d1358f4 --- /dev/null +++ b/test/emscripten.d.ts @@ -0,0 +1,18 @@ +declare function Module(target?: T): Promise +declare module Module { + function destroy(obj: any): void + function _malloc(size: number): number + function _free(ptr: number): void + const HEAP8: Int8Array + const HEAP16: Int16Array + const HEAP32: Int32Array + const HEAPU8: Uint8Array + const HEAPU16: Uint16Array + const HEAPU32: Uint32Array + const HEAPF32: Float32Array + const HEAPF64: Float64Array + class Test { + add(a: number, b: number): number + remove(a: number, b: number): number + } +} diff --git a/test/test.idl b/test/test.idl new file mode 100644 index 0000000..c48de4a --- /dev/null +++ b/test/test.idl @@ -0,0 +1,4 @@ +interface Test { + long add(long a, long b); + long remove(long a, long b); +}; diff --git a/test/webidl2ts.spec.ts b/test/webidl2ts.spec.ts new file mode 100644 index 0000000..cb1f515 --- /dev/null +++ b/test/webidl2ts.spec.ts @@ -0,0 +1,50 @@ +import fs from 'fs' +import assert from 'node:assert' +import { it, describe } from 'node:test' +import * as path from 'path' +import { convertIDL, parseIDL, printEmscriptenModule, printTs, Options, fetchIDL } from '../src' +import { fixes } from '../src/fixes' + +describe('webidl2ts', () => { + const testCases: { title: string; options: Options }[] = [ + { + title: 'should work in default mode', + options: { + emscripten: false, + defaultExport: false, + module: 'Module', + input: path.join(__dirname, 'test.idl'), + output: path.join(__dirname, 'default.d.ts'), + }, + }, + { + title: 'should work in emscripten mode', + options: { + emscripten: true, + defaultExport: false, + module: 'Module', + input: path.join(__dirname, 'test.idl'), + output: path.join(__dirname, 'emscripten.d.ts'), + }, + }, + ] + + testCases.forEach(({ title, options }) => { + it(title, async () => { + const idlString = await fetchIDL(options.input) + const idl = await parseIDL(idlString, { + preprocess: (idl: string) => { + if (options.emscripten) { + idl = fixes.inheritance(idl) + idl = fixes.array(idl) + } + return idl + }, + }) + const ts = convertIDL(idl, options) + const actual = options.emscripten ? printEmscriptenModule(options.module, ts, options.defaultExport) : printTs(ts) + const expected = fs.readFileSync(options.output).toString() + assert.equal(actual, expected) + }) + }) +}) diff --git a/tsconfig.json b/tsconfig.json index 754d5d2..87639c6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,11 +2,13 @@ "compilerOptions": { "outDir": "./dist", "moduleResolution": "node", + "esModuleInterop": true, "declaration": true, "target": "es5", "newLine": "LF", "baseUrl": ".", - "typeRoots": ["node_modules/@types", "types"] + "typeRoots": ["node_modules/@types", "types"], + "types": ["node"] }, "include": ["src/**/*.ts"], "exclude": ["dist", "node_modules", "snapshots"] diff --git a/yarn.lock b/yarn.lock index dcf69b1..877f5a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,13 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@eslint/eslintrc@^0.2.1": version "0.2.1" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.1.tgz#f72069c330461a06684d119384435e12a5d76e3c" @@ -39,6 +46,24 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -60,6 +85,26 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -70,10 +115,10 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== -"@types/node@^14.14.6": - version "14.14.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" - integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== +"@types/node@^18.0.0": + version "18.11.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.11.tgz#1d455ac0211549a8409d3cdb371cd55cc971e8dc" + integrity sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g== "@types/webidl2@^23.13.5": version "23.13.5" @@ -185,6 +230,11 @@ acorn-walk@^7.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" @@ -195,6 +245,11 @@ acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.4.1: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -333,11 +388,6 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -415,6 +465,11 @@ core-util-is@1.0.2: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -1353,15 +1408,7 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -source-map-support@^0.5.17: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@~0.6.1: +source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -1493,15 +1540,23 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" -ts-node@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.0.0.tgz#e7699d2a110cc8c0d3b831715e417688683460b3" - integrity sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg== - dependencies: +ts-node@^10.0.0: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" arg "^4.1.0" + create-require "^1.1.0" diff "^4.0.1" make-error "^1.1.1" - source-map-support "^0.5.17" + v8-compile-cache-lib "^3.0.1" yn "3.1.1" tslib@^1.8.1: @@ -1547,10 +1602,10 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -typescript@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" - integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== +typescript@^4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" + integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== uri-js@^4.2.2: version "4.2.2" @@ -1564,6 +1619,11 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-compile-cache@^2.0.3: version "2.2.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132"