160 lines
5.7 KiB
JavaScript
160 lines
5.7 KiB
JavaScript
|
"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 __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.getSrcCodePosFromEntry = exports.getSrcCodePosFromPath = exports.getRemainderAst = exports.getCurrentSrcLineNum = exports.getAncestorByName = exports.isPathMatch = exports.getEntryName = exports.constructFromCode = exports.construct = void 0;
|
||
|
const util_1 = __importDefault(require("util"));
|
||
|
const fs_1 = __importDefault(require("fs"));
|
||
|
const strip_bom_1 = __importDefault(require("strip-bom"));
|
||
|
const uglify_js_1 = require("../tools/uglify-js/uglify-js");
|
||
|
const ErrCodes = __importStar(require("./err_codes"));
|
||
|
const promisify_1 = __importDefault(require("../../utils/promisify"));
|
||
|
var readFile = (0, promisify_1.default)(fs_1.default.readFile);
|
||
|
function construct(fileName, ownerFilename, callback) {
|
||
|
readFile(fileName)
|
||
|
.then(data => {
|
||
|
data = (0, strip_bom_1.default)(data);
|
||
|
var constructed = null;
|
||
|
try {
|
||
|
constructed = constructFromCode(data, fileName);
|
||
|
}
|
||
|
catch (err) {
|
||
|
callback(err);
|
||
|
return;
|
||
|
}
|
||
|
callback(null, constructed.ast, constructed.preprocessedCode);
|
||
|
})
|
||
|
.catch(() => {
|
||
|
callback({
|
||
|
type: ownerFilename ? ErrCodes.FAILED_LOAD_REQUIRE : ErrCodes.READ_FILE_FAILED,
|
||
|
filename: fileName,
|
||
|
ownerFilename: ownerFilename
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
exports.construct = construct;
|
||
|
;
|
||
|
function constructFromCode(code, fileName) {
|
||
|
var ast = null;
|
||
|
code = code.toString().trim();
|
||
|
//NOTE: perform srcCode preprocessing the same way it's done in the uglify tokenizer, so
|
||
|
//we'll get correct entities positions for code generator
|
||
|
code = code.replace(/\r\n?|[\n\u2028\u2029]/g, "\n");
|
||
|
try {
|
||
|
ast = uglify_js_1.parser.parse(code, false, true);
|
||
|
}
|
||
|
catch (parseErr) {
|
||
|
throw {
|
||
|
type: ErrCodes.JAVASCRIPT_PARSING_FAILED,
|
||
|
filename: fileName,
|
||
|
parserErr: parseErr
|
||
|
};
|
||
|
}
|
||
|
return {
|
||
|
ast: ast,
|
||
|
preprocessedCode: code
|
||
|
};
|
||
|
}
|
||
|
exports.constructFromCode = constructFromCode;
|
||
|
;
|
||
|
function getEntryName(entry) {
|
||
|
return typeof entry[0] === 'object' ? entry[0].name : entry[0];
|
||
|
}
|
||
|
exports.getEntryName = getEntryName;
|
||
|
;
|
||
|
function isPathMatch(expectedPath, actualPath, ensureLast) {
|
||
|
if (expectedPath.length !== actualPath.length - 1)
|
||
|
return false;
|
||
|
//NOTE: Check if it is a last entry in the path root
|
||
|
if (ensureLast && !actualPath[1][0].last)
|
||
|
return false;
|
||
|
for (var i = 0; i < expectedPath.length; i++) {
|
||
|
var hasFlag = util_1.default.isArray(expectedPath[i]), name = hasFlag ? expectedPath[i][0] : expectedPath[i];
|
||
|
if (getEntryName(actualPath[i]) !== name || (hasFlag && actualPath[i][1] !== expectedPath[i][1]))
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
exports.isPathMatch = isPathMatch;
|
||
|
;
|
||
|
function getAncestorByName(name, currentAstPath) {
|
||
|
if (currentAstPath.length > 1) {
|
||
|
for (var i = currentAstPath.length - 2; i >= 0; i--) {
|
||
|
if (getEntryName(currentAstPath[i]) === name)
|
||
|
return currentAstPath[i];
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
exports.getAncestorByName = getAncestorByName;
|
||
|
;
|
||
|
function getCurrentSrcLineNum(currentAst) {
|
||
|
//NOTE: Try to obtain the current line number. currentAst may not contain additional info for unknown reason.
|
||
|
for (var i = currentAst.length - 1; i >= 0; i--) {
|
||
|
if (currentAst[i]) {
|
||
|
if (currentAst[i].start)
|
||
|
return currentAst[i].start.line;
|
||
|
if (currentAst[i][0] && currentAst[i][0].start)
|
||
|
return currentAst[i][0].start.line;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
exports.getCurrentSrcLineNum = getCurrentSrcLineNum;
|
||
|
;
|
||
|
function getRemainderAst(ast) {
|
||
|
//NOTE: We traverse through statements of the 'toplevel' and
|
||
|
//just remove those that are marked with 'remove' flag.
|
||
|
//Everything that's left is a shared code.
|
||
|
var astBranches = [];
|
||
|
ast[1].forEach(function (statement) {
|
||
|
if (!statement[0].remove)
|
||
|
astBranches.push(statement);
|
||
|
});
|
||
|
return astBranches.length ? ['toplevel', astBranches] : null;
|
||
|
}
|
||
|
exports.getRemainderAst = getRemainderAst;
|
||
|
;
|
||
|
function getSrcCodePosFromPath(astPath) {
|
||
|
return getSrcCodePosFromEntry(astPath[astPath.length - 1]);
|
||
|
}
|
||
|
exports.getSrcCodePosFromPath = getSrcCodePosFromPath;
|
||
|
;
|
||
|
function getSrcCodePosFromEntry(astEntry) {
|
||
|
var pos = {
|
||
|
start: 0,
|
||
|
end: 0
|
||
|
};
|
||
|
if (astEntry && astEntry[0] && astEntry[0].start) {
|
||
|
pos.start = astEntry[0].start.pos;
|
||
|
pos.end = astEntry[0].end.endpos;
|
||
|
}
|
||
|
return pos;
|
||
|
}
|
||
|
exports.getSrcCodePosFromEntry = getSrcCodePosFromEntry;
|
||
|
;
|