Permalink
Browse files

tools, feat: support generating *.d.ts by tools/tsdeclare.js based on…

… idlc.js (#421)

* sandbox, bugfix: fix core dump when required ts in sub sandbox.

* tools, feat: basic support for generating *.d.ts from '*.idl'.

* tools, bugfix: fix lack of overload methods when generating *.d.ts

* tools, feat: separate tsdeclare.js from idlc.js

* tools, bugfix: remove fib-types in tools/package.json
  • Loading branch information...
richardo2016 authored and xicilion committed Jun 3, 2018
1 parent 1ac350b commit 50555bebb9792eccd07fb5e5a52ffd7178b695bd
Showing with 396 additions and 8 deletions.
  1. +4 −5 test/ts_test.ts
  2. +6 −3 tools/idlc.js
  3. +16 −0 tools/tsdeclare.js
  4. +225 −0 tools/util/gen_ts_type.js
  5. +145 −0 tools/util/tmpl/type.d.ts.txt
View
@@ -1,9 +1,8 @@
var test = require("test");
test.setup();
// / <reference path="fib-types/declare/index.d.ts" />
// / <reference path="fib-types/declare/_test_env.d.ts" />
var encoding = require("encoding");
var util = require("util");
var vm = require("vm");
import * as test from "test";
test.setup();
describe('typescript', () => {
function assertBasicModule(rawModule) {
View
@@ -2,8 +2,11 @@ var path = require('path');
var parser = require('./util/parser');
var gen_code = require('./util/gen_code');
var idlFolder = path.join(__dirname, "../idl/zh-cn");
var baseFolder = path.join(__dirname, "../fibjs/include/ifs/");
var idlLang = process.env.FIBJS_IDL_LANG || 'zh-cn'
var idlFolder = path.join(__dirname, `../idl/${idlLang}`);
var baseCodeFolder = path.join(__dirname, "../fibjs/include/ifs/");
var defs = parser(idlFolder);
gen_code(defs, baseFolder);
gen_code(defs, baseCodeFolder);
module.exports = defs;
View
@@ -0,0 +1,16 @@
const fs = require('fs')
const gen_ts_type = require('./util/gen_ts_type');
const defs = require('./idlc')
const typesDistDir = process.env.FIBJS_IDL2TYPE_DIST
if (!typesDistDir) {
throw `no target dist for *.d.ts files to be generated.`
if (!fs.exists(typesDistDir)) {
throw `${FIBJS_IDL2TYPE_DIST} doesn's exist.`
}
console.log(`would write *.d.ts to ${typesDistDir}`)
gen_ts_type(defs, typesDistDir);
}
View
@@ -0,0 +1,225 @@
var fs = require("fs");
var util = require("util");
var path = require('path');
var ejs = require('ejs');
module.exports = function (defs, baseFolder) {
const defNames = Object.keys(defs)
const defModules = {}
const defObjetMirror = {}
const defObjects = {}
defNames.forEach((defName) => {
const def = defs[defName]
switch (def.declare.type) {
case 'interface':
defObjetMirror[defName] = defName
defObjects[defName] = def
break
case 'module':
defModules[defName] = def
break
}
})
const defModuleNames = Object.keys(defModules)
const defObjectNames = Object.keys(defObjects)
const topLevelVariablesInGlobalModule = [
'__dirname',
'__filename',
'require',
'setHrInterval',
'clearHrInterval',
'GC',
'repl',
]
function gen_ts_type_code(cls, def) {
var typeMap = {
"Integer": "number",
"Long": "number",
"Number": "number",
"Boolean": "boolean",
"String": "string",
"Date": "Date",
"Object": "Object",
"Iterator": "Object",
"Array": "any[]",
"TypedArray": "TypedArray",
"ArrayBuffer": "ArrayBuffer",
"ArrayBufferView": "ArrayBufferView",
"Function": "Function",
"Value": "any",
"Variant": "any",
"NObject": "any",
"NArray": "any[]",
...defObjetMirror,
"...": "any[]"
};
function isRestArgs(argType) {
return argType === '...'
}
function transObjectName(className) {
return className === 'object' ? '_object' : className
}
var txts = [];
var refers = [];
var hasNew = false;
var staticCallAsFunc = false;
var callAsFunc = false;
var fnIndexed = null;
var fnNamed = null;
function get_type(t) {
return typeMap[t];
}
function get_rtype(t) {
if (Array.isArray(t))
return `Array<${t.name}>`;
return typeMap[t] || t;
}
function params2paramList(params, typeMap = typeMap) {
return (params || []).map(param => {
var hasDefault = param.default;
if (isRestArgs(param.type)) {
param.name = `...${param.name}`
}
var mappedType = typeMap[param.type] || 'any';
return `${param.name}${hasDefault ? '?' : ''}: ${mappedType}${hasDefault ? `/** = ${param.default.value}*/` : ''}`
})
}
function build_refer(def) {
var types = {};
function add_type(type) {
if (type && (type !== cls) && (type !== 'object') &&
(type !== def.declare.extend) &&
(!typeMap[type]))
types[type] = true;
}
def.members.forEach(m => {
if (Array.isArray(m.type))
m.type.forEach(rt => add_type(rt.type));
else
add_type(m.type);
if (!m.overs)
return;
m.overs.forEach(ov => {
if (!ov.params)
return;
ov.params.forEach(p => {
add_type(p.type);
if (p.default && util.isArray(p.default.const) && p.default.const.length > 1)
add_type(p.default.const[0]);
});
});
});
refers = Object.keys(types);
return refers;
}
var filename = `${cls}.d.ts`;
var fname = path.join(baseFolder, filename);
var typeDTs = ejs.compile(fs.readTextFile(path.join(__dirname, './tmpl/type.d.ts.txt')));
function getTypeDTsParams(def) {
return {
def: def,
defNames: defNames,
member_fns: util.flatten(def.members.filter(x => x.memType === 'method')
.map(x => util.isArray(x.overs) && x.overs.length ? x.overs : x)
, true
),
member_constants: def.members.filter(x => x.memType === 'const'),
member_props: def.members.filter(x => x.memType === 'prop'),
typeMap,
defModules,
defObjects,
defModuleNames,
defObjectNames,
topLevelVariablesInGlobalModule,
refers: build_refer(def),
_fns: {
get_type,
get_rtype,
params2paramList,
isRestArgs,
transObjectName
},
filename: def.filename || ''
}
}
var txt = '';
switch (cls) {
case 'index':
txt = typeDTs(getTypeDTsParams({
"declare": {
"comments": "! @brief Global objects and functions",
"type": "index",
"name": "index",
"index": true,
"doc": {
"descript": "Global objects and functions",
"detail": [],
"params": []
}
},
members: [],
filename: 'index'
}));
break;
case '_test_env':
txt = typeDTs(getTypeDTsParams({
"declare": {
"comments": "! @brief Global objects and functions",
"type": "_test_env",
"name": "_test_env",
"doc": {
"descript": "Global objects and functions",
"detail": [],
"params": []
}
},
members: defs['test'].members,
filename: '_test_env'
}));
break;
default:
txt = typeDTs(getTypeDTsParams(def));
break;
}
if (!fs.exists(fname) || fs.readTextFile(fname) !== txt) {
console.log(filename);
fs.writeTextFile(fname, txt);
}
}
for (var cls in defs) {
gen_ts_type_code(cls, defs[cls]);
}
gen_ts_type_code('index');
gen_ts_type_code('_test_env');
}
const indexMembers = [{
"memType": "method",
"comments": "! @brief Global require",
"deprecated": null,
"async": "async",
"name": "require",
"type": null,
"params": [{
"type": "string",
"name": "path",
"default": null
}]
}]
Oops, something went wrong.

0 comments on commit 50555be

Please sign in to comment.