"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; ;