build: update npm install command to use --legacy-peer-deps

This change modifies the build scripts to use --legacy-peer-deps flag when installing npm dependencies to resolve potential peer dependency conflicts during the build process. The change is applied to both bash (build.sh) and batch (build.bat) build scripts.
This commit is contained in:
Luiz Costa
2025-11-18 10:23:55 -03:00
parent 20129a1ac7
commit ac4f232e5e
787 changed files with 82341 additions and 121690 deletions
+286 -276
View File
@@ -20,313 +20,323 @@ const IdGenerator = require("./id-generator");
* A code path.
*/
class CodePath {
/**
* Creates a new instance.
* @param {Object} options Options for the function (see below).
* @param {string} options.id An identifier.
* @param {string} options.origin The type of code path origin.
* @param {CodePath|null} options.upper The code path of the upper function scope.
* @param {Function} options.onLooped A callback function to notify looping.
*/
constructor({ id, origin, upper, onLooped }) {
/**
* The identifier of this code path.
* Rules use it to store additional information of each rule.
* @type {string}
*/
this.id = id;
/**
* The reason that this code path was started. May be "program",
* "function", "class-field-initializer", or "class-static-block".
* @type {string}
*/
this.origin = origin;
/**
* Creates a new instance.
* @param {Object} options Options for the function (see below).
* @param {string} options.id An identifier.
* @param {string} options.origin The type of code path origin.
* @param {CodePath|null} options.upper The code path of the upper function scope.
* @param {Function} options.onLooped A callback function to notify looping.
*/
constructor({ id, origin, upper, onLooped }) {
/**
* The code path of the upper function scope.
* @type {CodePath|null}
*/
this.upper = upper;
/**
* The identifier of this code path.
* Rules use it to store additional information of each rule.
* @type {string}
*/
this.id = id;
/**
* The code paths of nested function scopes.
* @type {CodePath[]}
*/
this.childCodePaths = [];
/**
* The reason that this code path was started. May be "program",
* "function", "class-field-initializer", or "class-static-block".
* @type {string}
*/
this.origin = origin;
// Initializes internal state.
Object.defineProperty(this, "internal", {
value: new CodePathState(new IdGenerator(`${id}_`), onLooped),
});
/**
* The code path of the upper function scope.
* @type {CodePath|null}
*/
this.upper = upper;
// Adds this into `childCodePaths` of `upper`.
if (upper) {
upper.childCodePaths.push(this);
}
}
/**
* The code paths of nested function scopes.
* @type {CodePath[]}
*/
this.childCodePaths = [];
/**
* Gets the state of a given code path.
* @param {CodePath} codePath A code path to get.
* @returns {CodePathState} The state of the code path.
*/
static getState(codePath) {
return codePath.internal;
}
// Initializes internal state.
Object.defineProperty(
this,
"internal",
{ value: new CodePathState(new IdGenerator(`${id}_`), onLooped) }
);
/**
* The initial code path segment. This is the segment that is at the head
* of the code path.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment}
*/
get initialSegment() {
return this.internal.initialSegment;
}
// Adds this into `childCodePaths` of `upper`.
if (upper) {
upper.childCodePaths.push(this);
}
}
/**
* Final code path segments. These are the terminal (tail) segments in the
* code path, which is the combination of `returnedSegments` and `thrownSegments`.
* All segments in this array are reachable.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment[]}
*/
get finalSegments() {
return this.internal.finalSegments;
}
/**
* Gets the state of a given code path.
* @param {CodePath} codePath A code path to get.
* @returns {CodePathState} The state of the code path.
*/
static getState(codePath) {
return codePath.internal;
}
/**
* Final code path segments that represent normal completion of the code path.
* For functions, this means both explicit `return` statements and implicit returns,
* such as the last reachable segment in a function that does not have an
* explicit `return` as this implicitly returns `undefined`. For scripts,
* modules, class field initializers, and class static blocks, this means
* all lines of code have been executed.
* These segments are also present in `finalSegments`.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment[]}
*/
get returnedSegments() {
return this.internal.returnedForkContext;
}
/**
* The initial code path segment. This is the segment that is at the head
* of the code path.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment}
*/
get initialSegment() {
return this.internal.initialSegment;
}
/**
* Final code path segments that represent `throw` statements.
* This is a passthrough to the underlying `CodePathState`.
* These segments are also present in `finalSegments`.
* @type {CodePathSegment[]}
*/
get thrownSegments() {
return this.internal.thrownForkContext;
}
/**
* Final code path segments. These are the terminal (tail) segments in the
* code path, which is the combination of `returnedSegments` and `thrownSegments`.
* All segments in this array are reachable.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment[]}
*/
get finalSegments() {
return this.internal.finalSegments;
}
/**
* Traverses all segments in this code path.
*
* codePath.traverseSegments((segment, controller) => {
* // do something.
* });
*
* This method enumerates segments in order from the head.
*
* The `controller` argument has two methods:
*
* - `skip()` - skips the following segments in this branch
* - `break()` - skips all following segments in the traversal
*
* A note on the parameters: the `options` argument is optional. This means
* the first argument might be an options object or the callback function.
* @param {Object} [optionsOrCallback] Optional first and last segments to traverse.
* @param {CodePathSegment} [optionsOrCallback.first] The first segment to traverse.
* @param {CodePathSegment} [optionsOrCallback.last] The last segment to traverse.
* @param {Function} callback A callback function.
* @returns {void}
*/
traverseSegments(optionsOrCallback, callback) {
// normalize the arguments into a callback and options
let resolvedOptions;
let resolvedCallback;
/**
* Final code path segments that represent normal completion of the code path.
* For functions, this means both explicit `return` statements and implicit returns,
* such as the last reachable segment in a function that does not have an
* explicit `return` as this implicitly returns `undefined`. For scripts,
* modules, class field initializers, and class static blocks, this means
* all lines of code have been executed.
* These segments are also present in `finalSegments`.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment[]}
*/
get returnedSegments() {
return this.internal.returnedForkContext;
}
if (typeof optionsOrCallback === "function") {
resolvedCallback = optionsOrCallback;
resolvedOptions = {};
} else {
resolvedOptions = optionsOrCallback || {};
resolvedCallback = callback;
}
/**
* Final code path segments that represent `throw` statements.
* This is a passthrough to the underlying `CodePathState`.
* These segments are also present in `finalSegments`.
* @type {CodePathSegment[]}
*/
get thrownSegments() {
return this.internal.thrownForkContext;
}
// determine where to start traversing from based on the options
const startSegment =
resolvedOptions.first || this.internal.initialSegment;
const lastSegment = resolvedOptions.last;
/**
* Tracks the traversal of the code path through each segment. This array
* starts empty and segments are added or removed as the code path is
* traversed. This array always ends up empty at the end of a code path
* traversal. The `CodePathState` uses this to track its progress through
* the code path.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment[]}
* @deprecated
*/
get currentSegments() {
return this.internal.currentSegments;
}
// set up initial location information
let record;
let index;
let end;
let segment = null;
/**
* Traverses all segments in this code path.
*
* codePath.traverseSegments((segment, controller) => {
* // do something.
* });
*
* This method enumerates segments in order from the head.
*
* The `controller` argument has two methods:
*
* - `skip()` - skips the following segments in this branch
* - `break()` - skips all following segments in the traversal
*
* A note on the parameters: the `options` argument is optional. This means
* the first argument might be an options object or the callback function.
* @param {Object} [optionsOrCallback] Optional first and last segments to traverse.
* @param {CodePathSegment} [optionsOrCallback.first] The first segment to traverse.
* @param {CodePathSegment} [optionsOrCallback.last] The last segment to traverse.
* @param {Function} callback A callback function.
* @returns {void}
*/
traverseSegments(optionsOrCallback, callback) {
// segments that have already been visited during traversal
const visited = new Set();
// normalize the arguments into a callback and options
let resolvedOptions;
let resolvedCallback;
// tracks the traversal steps
const stack = [[startSegment, 0]];
if (typeof optionsOrCallback === "function") {
resolvedCallback = optionsOrCallback;
resolvedOptions = {};
} else {
resolvedOptions = optionsOrCallback || {};
resolvedCallback = callback;
}
// segments that have been skipped during traversal
const skipped = new Set();
// determine where to start traversing from based on the options
const startSegment = resolvedOptions.first || this.internal.initialSegment;
const lastSegment = resolvedOptions.last;
// indicates if we exited early from the traversal
let broken = false;
// set up initial location information
let record = null;
let index = 0;
let end = 0;
let segment = null;
/**
* Maintains traversal state.
*/
const controller = {
/**
* Skip the following segments in this branch.
* @returns {void}
*/
skip() {
skipped.add(segment);
},
// segments that have already been visited during traversal
const visited = new Set();
/**
* Stop traversal completely - do not traverse to any
* other segments.
* @returns {void}
*/
break() {
broken = true;
},
};
// tracks the traversal steps
const stack = [[startSegment, 0]];
/**
* Checks if a given previous segment has been visited.
* @param {CodePathSegment} prevSegment A previous segment to check.
* @returns {boolean} `true` if the segment has been visited.
*/
function isVisited(prevSegment) {
return (
visited.has(prevSegment) ||
segment.isLoopedPrevSegment(prevSegment)
);
}
// tracks the last skipped segment during traversal
let skippedSegment = null;
/**
* Checks if a given previous segment has been skipped.
* @param {CodePathSegment} prevSegment A previous segment to check.
* @returns {boolean} `true` if the segment has been skipped.
*/
function isSkipped(prevSegment) {
return (
skipped.has(prevSegment) ||
segment.isLoopedPrevSegment(prevSegment)
);
}
// indicates if we exited early from the traversal
let broken = false;
// the traversal
while (stack.length > 0) {
/*
* This isn't a pure stack. We use the top record all the time
* but don't always pop it off. The record is popped only if
* one of the following is true:
*
* 1) We have already visited the segment.
* 2) We have not visited *all* of the previous segments.
* 3) We have traversed past the available next segments.
*
* Otherwise, we just read the value and sometimes modify the
* record as we traverse.
*/
record = stack.at(-1);
segment = record[0];
index = record[1];
/**
* Maintains traversal state.
*/
const controller = {
if (index === 0) {
// Skip if this segment has been visited already.
if (visited.has(segment)) {
stack.pop();
continue;
}
/**
* Skip the following segments in this branch.
* @returns {void}
*/
skip() {
if (stack.length <= 1) {
broken = true;
} else {
skippedSegment = stack[stack.length - 2][0];
}
},
// Skip if all previous segments have not been visited.
if (
segment !== startSegment &&
segment.prevSegments.length > 0 &&
!segment.prevSegments.every(isVisited)
) {
stack.pop();
continue;
}
/**
* Stop traversal completely - do not traverse to any
* other segments.
* @returns {void}
*/
break() {
broken = true;
}
};
visited.add(segment);
/**
* Checks if a given previous segment has been visited.
* @param {CodePathSegment} prevSegment A previous segment to check.
* @returns {boolean} `true` if the segment has been visited.
*/
function isVisited(prevSegment) {
return (
visited.has(prevSegment) ||
segment.isLoopedPrevSegment(prevSegment)
);
}
// Skips the segment if all previous segments have been skipped.
const shouldSkip =
skipped.size > 0 &&
segment.prevSegments.length > 0 &&
segment.prevSegments.every(isSkipped);
// the traversal
while (stack.length > 0) {
/*
* If the most recent segment hasn't been skipped, then we call
* the callback, passing in the segment and the controller.
*/
if (!shouldSkip) {
resolvedCallback.call(this, segment, controller);
/*
* This isn't a pure stack. We use the top record all the time
* but don't always pop it off. The record is popped only if
* one of the following is true:
*
* 1) We have already visited the segment.
* 2) We have not visited *all* of the previous segments.
* 3) We have traversed past the available next segments.
*
* Otherwise, we just read the value and sometimes modify the
* record as we traverse.
*/
record = stack[stack.length - 1];
segment = record[0];
index = record[1];
// exit if we're at the last segment
if (segment === lastSegment) {
controller.skip();
}
if (index === 0) {
/*
* If the previous statement was executed, or if the callback
* called a method on the controller, we might need to exit the
* loop, so check for that and break accordingly.
*/
if (broken) {
break;
}
} else {
// If the most recent segment has been skipped, then mark it as skipped.
skipped.add(segment);
}
}
// Skip if this segment has been visited already.
if (visited.has(segment)) {
stack.pop();
continue;
}
// Update the stack.
end = segment.nextSegments.length - 1;
if (index < end) {
/*
* If we haven't yet visited all of the next segments, update
* the current top record on the stack to the next index to visit
* and then push a record for the current segment on top.
*
* Setting the current top record's index lets us know how many
* times we've been here and ensures that the segment won't be
* reprocessed (because we only process segments with an index
* of 0).
*/
record[1] += 1;
stack.push([segment.nextSegments[index], 0]);
} else if (index === end) {
/*
* If we are at the last next segment, then reset the top record
* in the stack to next segment and set its index to 0 so it will
* be processed next.
*/
record[0] = segment.nextSegments[index];
record[1] = 0;
} else {
/*
* If index > end, that means we have no more segments that need
* processing. So, we pop that record off of the stack in order to
* continue traversing at the next level up.
*/
stack.pop();
}
}
}
// Skip if all previous segments have not been visited.
if (segment !== startSegment &&
segment.prevSegments.length > 0 &&
!segment.prevSegments.every(isVisited)
) {
stack.pop();
continue;
}
// Reset the skipping flag if all branches have been skipped.
if (skippedSegment && segment.prevSegments.includes(skippedSegment)) {
skippedSegment = null;
}
visited.add(segment);
/*
* If the most recent segment hasn't been skipped, then we call
* the callback, passing in the segment and the controller.
*/
if (!skippedSegment) {
resolvedCallback.call(this, segment, controller);
// exit if we're at the last segment
if (segment === lastSegment) {
controller.skip();
}
/*
* If the previous statement was executed, or if the callback
* called a method on the controller, we might need to exit the
* loop, so check for that and break accordingly.
*/
if (broken) {
break;
}
}
}
// Update the stack.
end = segment.nextSegments.length - 1;
if (index < end) {
/*
* If we haven't yet visited all of the next segments, update
* the current top record on the stack to the next index to visit
* and then push a record for the current segment on top.
*
* Setting the current top record's index lets us know how many
* times we've been here and ensures that the segment won't be
* reprocessed (because we only process segments with an index
* of 0).
*/
record[1] += 1;
stack.push([segment.nextSegments[index], 0]);
} else if (index === end) {
/*
* If we are at the last next segment, then reset the top record
* in the stack to next segment and set its index to 0 so it will
* be processed next.
*/
record[0] = segment.nextSegments[index];
record[1] = 0;
} else {
/*
* If index > end, that means we have no more segments that need
* processing. So, we pop that record off of the stack in order to
* continue traversing at the next level up.
*/
stack.pop();
}
}
}
}
module.exports = CodePath;