diff --git a/external/builder/.eslintrc b/external/builder/.eslintrc new file mode 100644 index 000000000..4a0b538f6 --- /dev/null +++ b/external/builder/.eslintrc @@ -0,0 +1,10 @@ +{ + "extends": [ + "../.eslintrc" + ], + + "rules": { + // ECMAScript 6 + "no-var": "error", + }, +} diff --git a/external/builder/builder.js b/external/builder/builder.js index 2454f3da5..a3ed4e956 100644 --- a/external/builder/builder.js +++ b/external/builder/builder.js @@ -1,6 +1,6 @@ "use strict"; -var fs = require("fs"), +const fs = require("fs"), path = require("path"), vm = require("vm"); @@ -33,18 +33,23 @@ var fs = require("fs"), * //#endif */ function preprocess(inFilename, outFilename, defines) { + let lineNumber = 0; + function loc() { + return fs.realpathSync(inFilename) + ":" + lineNumber; + } + // TODO make this really read line by line. - var lines = fs.readFileSync(inFilename).toString().split("\n"); - var totalLines = lines.length; - var out = ""; - var i = 0; + const lines = fs.readFileSync(inFilename).toString().split("\n"); + const totalLines = lines.length; + let out = ""; + let i = 0; function readLine() { if (i < totalLines) { return lines[i++]; } return null; } - var writeLine = + const writeLine = typeof outFilename === "function" ? outFilename : function (line) { @@ -70,10 +75,10 @@ function preprocess(inFilename, outFilename, defines) { } } function include(file) { - var realPath = fs.realpathSync(inFilename); - var dir = path.dirname(realPath); + const realPath = fs.realpathSync(inFilename); + const dir = path.dirname(realPath); try { - var fullpath; + let fullpath; if (file.indexOf("$ROOT/") === 0) { fullpath = path.join( __dirname, @@ -103,28 +108,25 @@ function preprocess(inFilename, outFilename, defines) { } // not inside if or else (process lines) - var STATE_NONE = 0; + const STATE_NONE = 0; // inside if, condition false (ignore until #else or #endif) - var STATE_IF_FALSE = 1; + const STATE_IF_FALSE = 1; // inside else, #if was false, so #else is true (process lines until #endif) - var STATE_ELSE_TRUE = 2; + const STATE_ELSE_TRUE = 2; // inside if, condition true (process lines until #else or #endif) - var STATE_IF_TRUE = 3; + const STATE_IF_TRUE = 3; // inside else or elif, #if/#elif was true, so following #else or #elif is // false (ignore lines until #endif) - var STATE_ELSE_FALSE = 4; + const STATE_ELSE_FALSE = 4; + + let line; + let state = STATE_NONE; + const stack = []; + const control = /^(?:\/\/|)?$)?/; - var line; - var state = STATE_NONE; - var stack = []; - var control = /^(?:\/\/|)?$)?/; - var lineNumber = 0; - var loc = function () { - return fs.realpathSync(inFilename) + ":" + lineNumber; - }; while ((line = readLine()) !== null) { ++lineNumber; - var m = control.exec(line); + const m = control.exec(line); if (m) { switch (m[1]) { case "if": @@ -205,27 +207,27 @@ function preprocessCSS(mode, source, destination) { return content.replace( /^\s*@import\s+url\(([^)]+)\);\s*$/gm, function (all, url) { - var file = path.join(path.dirname(baseUrl), url); - var imported = fs.readFileSync(file, "utf8").toString(); + const file = path.join(path.dirname(baseUrl), url); + const imported = fs.readFileSync(file, "utf8").toString(); return expandImports(imported, file); } ); } function removePrefixed(content, hasPrefixedFilter) { - var lines = content.split(/\r?\n/g); - var i = 0; + const lines = content.split(/\r?\n/g); + let i = 0; while (i < lines.length) { - var line = lines[i]; + const line = lines[i]; if (!hasPrefixedFilter(line)) { i++; continue; } if (/\{\s*$/.test(line)) { - var bracketLevel = 1; - var j = i + 1; + let bracketLevel = 1; + let j = i + 1; while (j < lines.length && bracketLevel > 0) { - var checkBracket = /([{}])\s*$/.exec(lines[j]); + const checkBracket = /([{}])\s*$/.exec(lines[j]); if (checkBracket) { if (checkBracket[1] === "{") { bracketLevel++; @@ -263,7 +265,7 @@ function preprocessCSS(mode, source, destination) { throw new Error("Invalid CSS preprocessor mode"); } - var content = fs.readFileSync(source, "utf8").toString(); + let content = fs.readFileSync(source, "utf8").toString(); content = expandImports(content, source); if (mode === "mozcentral") { content = removePrefixed(content, hasPrefixedMozcentral); @@ -277,11 +279,11 @@ exports.preprocessCSS = preprocessCSS; * the first. */ function merge(defaults, defines) { - var ret = {}; - for (var key in defaults) { + const ret = Object.create(null); + for (const key in defaults) { ret[key] = defaults[key]; } - for (key in defines) { + for (const key in defines) { ret[key] = defines[key]; } return ret; diff --git a/external/builder/preprocessor2.js b/external/builder/preprocessor2.js index eb991a032..b918b1df2 100644 --- a/external/builder/preprocessor2.js +++ b/external/builder/preprocessor2.js @@ -1,13 +1,13 @@ "use strict"; -var acorn = require("acorn"); -var escodegen = require("escodegen"); -var vm = require("vm"); -var fs = require("fs"); -var path = require("path"); +const acorn = require("acorn"); +const escodegen = require("escodegen"); +const vm = require("vm"); +const fs = require("fs"); +const path = require("path"); -var PDFJS_PREPROCESSOR_NAME = "PDFJSDev"; -var ROOT_PREFIX = "$ROOT/"; +const PDFJS_PREPROCESSOR_NAME = "PDFJSDev"; +const ROOT_PREFIX = "$ROOT/"; const ACORN_ECMA_VERSION = 2021; function isLiteral(obj, value) { @@ -27,21 +27,21 @@ function evalWithDefines(code, defines, loc) { function handlePreprocessorAction(ctx, actionName, args, loc) { try { - var arg; + let arg; switch (actionName) { case "test": arg = args[0]; if (!arg || arg.type !== "Literal" || typeof arg.value !== "string") { throw new Error("No code for testing is given"); } - var isTrue = !!evalWithDefines(arg.value, ctx.defines); + const isTrue = !!evalWithDefines(arg.value, ctx.defines); return { type: "Literal", value: isTrue, loc }; case "eval": arg = args[0]; if (!arg || arg.type !== "Literal" || typeof arg.value !== "string") { throw new Error("No code for eval is given"); } - var result = evalWithDefines(arg.value, ctx.defines); + const result = evalWithDefines(arg.value, ctx.defines); if ( typeof result === "boolean" || typeof result === "string" || @@ -62,14 +62,14 @@ function handlePreprocessorAction(ctx, actionName, args, loc) { if (!arg || arg.type !== "Literal" || typeof arg.value !== "string") { throw new Error("Path to JSON is not provided"); } - var jsonPath = arg.value; + let jsonPath = arg.value; if (jsonPath.indexOf(ROOT_PREFIX) === 0) { jsonPath = path.join( ctx.rootPath, jsonPath.substring(ROOT_PREFIX.length) ); } - var jsonContent = fs.readFileSync(jsonPath).toString(); + const jsonContent = fs.readFileSync(jsonPath).toString(); const parsedJSON = acorn.parse("(" + jsonContent + ")", { ecmaVersion: ACORN_ECMA_VERSION, }); @@ -103,7 +103,7 @@ function postprocessNode(ctx, node) { ctx.map && ctx.map[node.source.value] ) { - var newValue = ctx.map[node.source.value]; + const newValue = ctx.map[node.source.value]; node.source.value = node.source.raw = newValue; } break; @@ -175,7 +175,7 @@ function postprocessNode(ctx, node) { case "string": case "boolean": case "number": - var equal = node.left.value === node.right.value; + const equal = node.left.value === node.right.value; return { type: "Literal", value: (node.operator[0] === "=") === equal, @@ -193,7 +193,7 @@ function postprocessNode(ctx, node) { node.callee.property.type === "Identifier" ) { // PDFJSDev.xxxx(arg1, arg2, ...) => transform - var action = node.callee.property.name; + const action = node.callee.property.name; return handlePreprocessorAction(ctx, action, node.arguments, node.loc); } // require('string') @@ -205,12 +205,12 @@ function postprocessNode(ctx, node) { ctx.map && ctx.map[node.arguments[0].value] ) { - var requireName = node.arguments[0]; + const requireName = node.arguments[0]; requireName.value = requireName.raw = ctx.map[requireName.value]; } break; case "BlockStatement": - var subExpressionIndex = 0; + let subExpressionIndex = 0; while (subExpressionIndex < node.body.length) { switch (node.body[subExpressionIndex].type) { case "EmptyStatement": @@ -219,7 +219,7 @@ function postprocessNode(ctx, node) { continue; case "BlockStatement": // Block statements inside a block are moved to the parent one. - var subChildren = node.body[subExpressionIndex].body; + const subChildren = node.body[subExpressionIndex].body; Array.prototype.splice.apply( node.body, [subExpressionIndex, 1].concat(subChildren) @@ -240,7 +240,7 @@ function postprocessNode(ctx, node) { break; case "FunctionDeclaration": case "FunctionExpression": - var block = node.body; + const block = node.body; if ( block.body.length > 0 && block.body[block.body.length - 1].type === "ReturnStatement" && @@ -262,14 +262,14 @@ function fixComments(ctx, node) { delete node.trailingComments; // Removes ESLint and other service comments. if (node.leadingComments) { - var CopyrightRegExp = /\bcopyright\b/i; - var BlockCommentRegExp = /^\s*(globals|eslint|falls through)\b/; - var LineCommentRegExp = /^\s*eslint\b/; + const CopyrightRegExp = /\bcopyright\b/i; + const BlockCommentRegExp = /^\s*(globals|eslint|falls through)\b/; + const LineCommentRegExp = /^\s*eslint\b/; - var i = 0; + let i = 0; while (i < node.leadingComments.length) { - var type = node.leadingComments[i].type; - var value = node.leadingComments[i].value; + const type = node.leadingComments[i].type; + const value = node.leadingComments[i].value; if (ctx.saveComments === "copyright") { // Remove all comments, except Copyright notices and License headers. @@ -291,8 +291,8 @@ function fixComments(ctx, node) { function traverseTree(ctx, node) { // generic node processing - for (var i in node) { - var child = node[i]; + for (const i in node) { + const child = node[i]; if (typeof child === "object" && child !== null && child.type) { const result = traverseTree(ctx, child); if (result !== child) { @@ -321,18 +321,18 @@ function traverseTree(ctx, node) { } function preprocessPDFJSCode(ctx, code) { - var format = ctx.format || { + const format = ctx.format || { indent: { style: " ", }, }; - var parseOptions = { + const parseOptions = { ecmaVersion: ACORN_ECMA_VERSION, locations: true, sourceFile: ctx.sourceFile, sourceType: "module", }; - var codegenOptions = { + const codegenOptions = { format, parse(input) { return acorn.parse(input, { ecmaVersion: ACORN_ECMA_VERSION }); @@ -340,7 +340,7 @@ function preprocessPDFJSCode(ctx, code) { sourceMap: ctx.sourceMap, sourceMapWithCode: ctx.sourceMap, }; - var syntax = acorn.parse(code, parseOptions); + const syntax = acorn.parse(code, parseOptions); traverseTree(ctx, syntax); return escodegen.generate(syntax, codegenOptions); } diff --git a/external/builder/test-fixtures.js b/external/builder/test-fixtures.js index f23480abf..2cc059beb 100644 --- a/external/builder/test-fixtures.js +++ b/external/builder/test-fixtures.js @@ -1,13 +1,13 @@ "use strict"; -var builder = require("./builder"); -var fs = require("fs"); -var path = require("path"); +const builder = require("./builder"); +const fs = require("fs"); +const path = require("path"); -var errors = 0; +let errors = 0; -var baseDir = path.join(__dirname, "fixtures"); -var files = fs +const baseDir = path.join(__dirname, "fixtures"); +const files = fs .readdirSync(baseDir) .filter(function (name) { return /-expected\./.test(name); @@ -16,22 +16,22 @@ var files = fs return path.join(baseDir, name); }); files.forEach(function (expectationFilename) { - var inFilename = expectationFilename.replace("-expected", ""); - var expectation = fs + const inFilename = expectationFilename.replace("-expected", ""); + const expectation = fs .readFileSync(expectationFilename) .toString() .trim() .replace(/__filename/g, fs.realpathSync(inFilename)); - var outLines = []; + const outLines = []; - var outFilename = function (line) { + const outFilename = function (line) { outLines.push(line); }; - var defines = { + const defines = { TRUE: true, FALSE: false, }; - var out; + let out; try { builder.preprocess(inFilename, outFilename, defines); out = outLines.join("\n").trim(); diff --git a/external/builder/test-fixtures_esprima.js b/external/builder/test-fixtures_esprima.js index 655b965cc..35128aee5 100644 --- a/external/builder/test-fixtures_esprima.js +++ b/external/builder/test-fixtures_esprima.js @@ -1,13 +1,13 @@ "use strict"; -var p2 = require("./preprocessor2.js"); -var fs = require("fs"); -var path = require("path"); +const p2 = require("./preprocessor2.js"); +const fs = require("fs"); +const path = require("path"); -var errors = 0; +let errors = 0; -var baseDir = path.join(__dirname, "fixtures_esprima"); -var files = fs +const baseDir = path.join(__dirname, "fixtures_esprima"); +const files = fs .readdirSync(baseDir) .filter(function (name) { return /-expected\./.test(name); @@ -16,29 +16,29 @@ var files = fs return path.join(baseDir, name); }); files.forEach(function (expectationFilename) { - var inFilename = expectationFilename.replace("-expected", ""); - var expectation = fs + const inFilename = expectationFilename.replace("-expected", ""); + const expectation = fs .readFileSync(expectationFilename) .toString() .trim() .replace(/__filename/g, fs.realpathSync(inFilename)); - var input = fs.readFileSync(inFilename).toString(); + const input = fs.readFileSync(inFilename).toString(); - var defines = { + const defines = { TRUE: true, FALSE: false, OBJ: { obj: { i: 1 }, j: 2 }, TEXT: "text", }; - var map = { + const map = { "import-alias": "import-name", }; - var ctx = { + const ctx = { defines, map, rootPath: __dirname + "/../..", }; - var out; + let out; try { out = p2.preprocessPDFJSCode(ctx, input); } catch (e) {