From 82515c449f4d3f1ce8ba20313b3ba5a15c0348ef Mon Sep 17 00:00:00 2001 From: kekee000 Date: Wed, 28 Jan 2015 14:16:58 +0800 Subject: [PATCH] modify amd2module --- edp-build-config-node.js | 2 +- node/amd2module.js | 185 ++++++++++++++++----------------------- node/generated.js | 35 -------- node/test.js | 2 +- 4 files changed, 79 insertions(+), 145 deletions(-) delete mode 100644 node/generated.js diff --git a/edp-build-config-node.js b/edp-build-config-node.js index 1eb49c1..ac00704 100644 --- a/edp-build-config-node.js +++ b/edp-build-config-node.js @@ -13,7 +13,7 @@ exports.getProcessors = function () { 'common/lang.js', 'common/string.js', 'common/observable.js', - 'common/DomParser.js', + 'common/DOMParser.js', 'math/**/*.js', 'graphics/**/*.js', 'ttf/**/*.js' diff --git a/node/amd2module.js b/node/amd2module.js index 05111da..cd88589 100644 --- a/node/amd2module.js +++ b/node/amd2module.js @@ -11,36 +11,7 @@ var SYNTAX = estraverse.Syntax; // 顶级模块,用来生成相对位置 var REG_TOP_MODULE = /^(:?common|math|graphics|ttf)/; -var EXPORT_SEGMENT = { - "expression": { - "left": { - "computed": false, - "object": { - "name": "module", - "type": "Identifier" - }, - "property": { - "name": "exports", - "type": "Identifier" - }, - "type": "MemberExpression" - }, - "operator": "=", - "right": null, - "type": "AssignmentExpression" - }, - "type": "ExpressionStatement" -}; - -/** - * 获取导出声明 - * - * @return {Object} - */ -function getExportStatement() { - return JSON.parse(JSON.stringify(EXPORT_SEGMENT)); -} - +var REG_REQUIRE = /require\(\s*(['"])([^'"]+)\1\s*\)/g; /** * 获取ast树 @@ -52,10 +23,7 @@ function getAst(code) { try { ast = esprima.parse(code, { - // raw: true, - // tokens: true, - // range: true, - // comment: true + range: true }); } catch (ex) { throw 'can\'t parse amd code'; @@ -87,107 +55,111 @@ function getDefineFactory(defineExpr) { } /** - * 替换define的return为 module.exports + * 解析define块,提取factory和return * - * @param {Object} ast ast - * @return {Object} ast + * @param {Object} code code + * @return {Array} */ -function replaceDefine(ast) { - - estraverse.replace(ast, { +function getDefineBlock(code) { + var ast = getAst(code); + var defineList = []; + // require('fs').writeFileSync('ast.json', JSON.stringify(ast)); + estraverse.traverse(ast, { enter: function (node, parent) { - - if ( node.type === SYNTAX.ExpressionStatement - && node.expression.type === SYNTAX.CallExpression - && node.expression.callee.name === 'define' + if ( node.type == SYNTAX.ExpressionStatement + && node.expression.type == SYNTAX.CallExpression + && node.expression.callee.name == 'define' ) { - var factory = getDefineFactory(node.expression); + var defineBlock = {}; + defineBlock.defineRange = node.range; + + var factory = getDefineFactory(node.expression); // define('xxx', {}) if (factory.type === SYNTAX.ObjectExpression) { - var exportStatment = getExportStatement(); - exportStatment.expression.right = factory; - - return exportStatment; + defineBlock.type = 'object'; + defineBlock.factoryRange = factory.range; } // define(function() {}) else if (factory.type === SYNTAX.FunctionExpression){ - + defineBlock.type = 'function'; var body = factory.body.body; + defineBlock.factoryRange = factory.body.range; + var returnList = defineBlock.returnRange = []; // 替换return for (var i = body.length - 1; i >=0; i--) { - if (body[i].type === SYNTAX.ReturnStatement) { - var exportStatment = getExportStatement(); - exportStatment.expression.right = body[i].argument; - body.splice(i, 1, exportStatment); - break; + if (body[i].type == SYNTAX.ReturnStatement) { + returnList.push(body[i].range); } } - - var index = parent.body.indexOf(node); - Array.prototype.splice.apply(parent.body, [index, 1].concat(body)); - - return body[0]; } + defineList.push(defineBlock); + this.skip(); } - - return node; } }); - return ast; + return defineList; } + /** - * 去除生成的代码缩进 + * 替换define的return为 module.exports * - * @param {Object} ast ast - * @return {Object} ast + * @param {Object} code code + * @return {Object} */ -function replaceComments(ast) { - if (ast.comments && ast.comments.length) { - ast.comments.forEach(function (comment) { - if (comment.type === 'Block') { - // 去除缩进 - comment.value = comment.value.replace(/ /g, ''); - } - }); - } +function replaceDefine(code) { + var defineList = getDefineBlock(code); + var segments = []; + var index = 0; + defineList.forEach(function (block) { - return ast; + if (block.type === 'function') { + segments.push(code.slice(index, block.defineRange[0])); + index = block.factoryRange[0] + 1; + + block.returnRange.forEach(function (range) { + segments.push(code.slice(index, range[0])); + segments.push('module.exports = '); + segments.push(code.slice(range[0] + 6, range[1])); + index = range[1]; + }); + index = block.defineRange[1]; + } + else if (block.type === 'object'){ + segments.push(code.slice(index, block.defineRange[0])); + segments.push('module.exports = '); + segments.push(code.slice(block.factoryRange[0], block.factoryRange[1]) + ';'); + index = block.defineRange[1]; + } + }); + + segments.push(code.slice(index)); + + code = segments.join(''); + + return code; } + /** * 替换require的绝对路径为相对路径 * - * @param {Object} ast ast + * @param {Object} code code * @param {Object} codeDepth 当前模块位置 - * @return {Object} ast + * @return {Object} code */ -function replaceRequire(ast, codeDepth) { - - estraverse.replace(ast, { - enter: function (node, parent) { - - if ( node.type === SYNTAX.CallExpression - && node.callee.name === 'require' - && node.arguments.length - && node.arguments[0].type === 'Literal' - ) { - var argument = node.arguments[0]; - if (REG_TOP_MODULE.test(argument.value)) { - argument.value = codeDepth + argument.value; - } - } - - return node; +function replaceRequire(code, codeDepth) { + return code.replace(REG_REQUIRE, function ($0, $1, moduleId) { + if (REG_TOP_MODULE.test(moduleId)) { + moduleId = codeDepth + moduleId; } - } ); - - return ast; + return 'require(\'' + moduleId + '\')'; + }); } @@ -197,11 +169,7 @@ function replaceRequire(ast, codeDepth) { * @return {string} 生成后的代码 */ function genCommonJS(ast) { - - // ast = escodegen.attachComments(ast, ast.comments, ast.tokens); - return escodegen.generate(ast, { - // comment: true - }); + return escodegen.generate(ast); } module.exports = function (code, codeDepth) { @@ -210,9 +178,10 @@ module.exports = function (code, codeDepth) { codeDepth += '/'; } - var ast = getAst(code); - ast = replaceRequire(ast, codeDepth); - ast = replaceDefine(ast); - // ast = replaceComments(ast); - return genCommonJS(ast); + code = String(code); + + code = replaceDefine(code); + code = replaceRequire(code, codeDepth); + + return code; }; diff --git a/node/generated.js b/node/generated.js deleted file mode 100644 index 0dd1521..0000000 --- a/node/generated.js +++ /dev/null @@ -1,35 +0,0 @@ -var string = require('../common/string'); -var error = { - 10001: '\u8D85\u51FA\u8BFB\u53D6\u8303\u56F4\uFF1A${0}, ${1}', - 10002: '\u8D85\u51FA\u5199\u5165\u8303\u56F4\uFF1A${0}, ${1}', - 10003: '\u672A\u77E5\u6570\u636E\u7C7B\u578B\uFF1A${0}, ${1}', - 10004: '\u4E0D\u652F\u6301svg\u89E3\u6790', - 10101: '\u9519\u8BEF\u7684ttf\u6587\u4EF6', - 10102: '\u9519\u8BEF\u7684woff\u6587\u4EF6', - 10103: '\u9519\u8BEF\u7684svg\u6587\u4EF6', - 10104: '\u8BFB\u53D6ttf\u6587\u4EF6\u9519\u8BEF', - 10105: '\u8BFB\u53D6woff\u6587\u4EF6\u9519\u8BEF', - 10106: '\u8BFB\u53D6svg\u6587\u4EF6\u9519\u8BEF', - 10107: '\u5199\u5165ttf\u6587\u4EF6\u9519\u8BEF', - 10108: '\u5199\u5165woff\u6587\u4EF6\u9519\u8BEF', - 10109: '\u5199\u5165svg\u6587\u4EF6\u9519\u8BEF', - 10110: '\u8BFB\u53D6eot\u6587\u4EF6\u9519\u8BEF', - 10111: '\u8BFB\u53D6eot\u5B57\u4F53\u9519\u8BEF', - 10200: '\u91CD\u590D\u7684unicode\u4EE3\u7801\u70B9\uFF0C\u5B57\u5F62\u5E8F\u53F7\uFF1A${0}', - 10201: '\u5B57\u5F62\u8F6E\u5ED3\u6570\u636E\u4E3A\u7A7A', - 10202: '\u4E0D\u652F\u6301\u6807\u5FD7\u4F4D\uFF1AARGS_ARE_XY_VALUES', - 10203: '\u672A\u627E\u5230\u8868\uFF1A${0}', - 10204: '\u8BFB\u53D6\u8868\u9519\u8BEF', - 10205: '\u672A\u627E\u5230\u89E3\u538B\u51FD\u6570' -}; -error.raise = function (number) { - var message = error[number]; - if (arguments.length > 1) { - var args = typeof arguments[1] === 'object' ? arguments[1] : Array.prototype.slice.call(arguments, 1); - message = string.format(message, args); - } - var e = new Error(message); - e.number = number; - throw e; -}; -module.exports = error; \ No newline at end of file diff --git a/node/test.js b/node/test.js index 9099f31..3072e5c 100644 --- a/node/test.js +++ b/node/test.js @@ -6,7 +6,7 @@ var fs = require('fs'); var amd2module = require('./amd2module'); function main() { - var code = fs.readFileSync('../src/ttf/error.js'); + var code = fs.readFileSync('../src/fonteditor/data/online-font.js'); fs.writeFileSync('./generated.js', amd2module(code, '../')); }