130 lines
3.9 KiB
JavaScript
130 lines
3.9 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
"use strict";
|
|
|
|
/**
|
|
* Build: <srcdir>/tools/@types/generated/tspaths.json, and
|
|
* <srcdir>/tools/@types/generated/lib.gecko.modules.d.ts
|
|
*
|
|
* from: various import forms in all *.js and *.mjs sources.
|
|
*/
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const { fixed } = require("./config/fixed_paths.js");
|
|
|
|
const HEADER = `/**
|
|
* NOTE: Do not modify this file by hand.
|
|
* Content was generated by running "mach ts paths".
|
|
*/
|
|
`;
|
|
|
|
const IGNORE = [/\.git/, /\.hg/, /node_modules/, /^obj.*/, /test262/];
|
|
const IMPORT =
|
|
/(\bimport |import\(|require\(|\.importESModule\(|\.(defineESModuleGetters?|declareLazy|defineLazy)\()[^;]+/gm;
|
|
const URI = /("|')((resource|chrome|moz-src):\/\/[\w\d\/_.-]+\.m?js)\1/gm;
|
|
|
|
function ignore(filePath) {
|
|
return IGNORE.some(re => filePath.match(re));
|
|
}
|
|
|
|
// Scan the root dir for *.js and *.mjs files, recursivelly.
|
|
function scan(root, dir, files) {
|
|
for (let file of fs.readdirSync(`${root}/${dir}`, { withFileTypes: true })) {
|
|
if (file.isDirectory() && !ignore(dir + file.name)) {
|
|
scan(root, `${dir}${file.name}/`, files);
|
|
} else if (file.name.match(/\.(x?html|m?js)$/)) {
|
|
files.push(dir + file.name);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Emit path mapping for all found module URIs.
|
|
function emitPaths(files, uris, modules, relativeBasePath) {
|
|
let paths = {};
|
|
for (let uri of [...uris].sort()) {
|
|
if (uri in fixed) {
|
|
continue;
|
|
}
|
|
let parts = uri.split("/");
|
|
let filePath = "";
|
|
let matches;
|
|
|
|
// Check for a substitution .d.ts file from processed/generated sources.
|
|
let sub = parts.at(-1).replace(/\.(m)?js$/, ".d.$1ts");
|
|
if (fs.existsSync(`${__dirname}/../@types/subs/${sub}`)) {
|
|
paths[uri] = [`tools/@types/subs/${sub}`];
|
|
continue;
|
|
}
|
|
|
|
// Starting with just the file name, add each path part going backwards.
|
|
do {
|
|
filePath = "/" + parts.pop() + filePath;
|
|
matches = files.filter(f => f.endsWith(filePath));
|
|
// While multiple files match, add parts used for filtering.
|
|
} while (matches.length > 1 && parts.length);
|
|
|
|
// Unique match is almost certainy correct.
|
|
if (matches.length === 1) {
|
|
paths[uri] = [matches[0]];
|
|
} else {
|
|
// URI matched more than one, or failed to match any file.
|
|
console.warn("[WARN]", uri);
|
|
modules.delete(uri);
|
|
}
|
|
}
|
|
|
|
Object.assign(paths, fixed);
|
|
let tspaths = { compilerOptions: { baseUrl: relativeBasePath, paths } };
|
|
return JSON.stringify(tspaths, null, 2) + "\n";
|
|
}
|
|
|
|
// Emit type mapping for all modules imported via lazy getters.
|
|
function emitLazy(modules) {
|
|
let lines = [HEADER];
|
|
lines.push("export interface LazyModules {");
|
|
for (let uri of [...modules].sort()) {
|
|
lines.push(` "${uri}": typeof import("${uri}"),`);
|
|
}
|
|
lines.push("}\n");
|
|
return lines.join("\n");
|
|
}
|
|
|
|
function main(root_dir, paths_json, lib_lazy) {
|
|
let files = [];
|
|
scan(root_dir, "", files);
|
|
|
|
let uris = new Set();
|
|
let modules = new Set();
|
|
|
|
for (let file of files) {
|
|
let src = fs.readFileSync(`${root_dir}/${file}`, "utf-8");
|
|
|
|
for (let [exp, , method] of src.matchAll(IMPORT)) {
|
|
for (let [, , uri, proto] of exp.matchAll(URI)) {
|
|
if (proto !== "moz-src") {
|
|
uris.add(uri);
|
|
}
|
|
if (method?.match(/ModuleGetter|Lazy/)) {
|
|
modules.add(uri);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let json = emitPaths(
|
|
files,
|
|
uris,
|
|
modules,
|
|
path.relative(path.dirname(paths_json), root_dir).replaceAll("\\", "/")
|
|
);
|
|
console.log(`[INFO] ${paths_json} (${json.length.toLocaleString()} bytes)`);
|
|
fs.writeFileSync(paths_json, json);
|
|
|
|
let lib = emitLazy(modules);
|
|
console.log(`[INFO] ${lib_lazy} (${lib.length.toLocaleString()} bytes)`);
|
|
fs.writeFileSync(lib_lazy, lib);
|
|
}
|
|
|
|
main(...process.argv.slice(2));
|