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:
+119
-124
@@ -9,13 +9,7 @@
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const allLoopTypes = [
|
||||
"WhileStatement",
|
||||
"DoWhileStatement",
|
||||
"ForStatement",
|
||||
"ForInStatement",
|
||||
"ForOfStatement",
|
||||
];
|
||||
const allLoopTypes = ["WhileStatement", "DoWhileStatement", "ForStatement", "ForInStatement", "ForOfStatement"];
|
||||
|
||||
/**
|
||||
* Checks all segments in a set and returns true if any are reachable.
|
||||
@@ -23,13 +17,14 @@ const allLoopTypes = [
|
||||
* @returns {boolean} True if any segment is reachable; false otherwise.
|
||||
*/
|
||||
function isAnySegmentReachable(segments) {
|
||||
for (const segment of segments) {
|
||||
if (segment.reachable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
for (const segment of segments) {
|
||||
if (segment.reachable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,25 +34,25 @@ function isAnySegmentReachable(segments) {
|
||||
* @returns {boolean} `true` if the node is a looping target.
|
||||
*/
|
||||
function isLoopingTarget(node) {
|
||||
const parent = node.parent;
|
||||
const parent = node.parent;
|
||||
|
||||
if (parent) {
|
||||
switch (parent.type) {
|
||||
case "WhileStatement":
|
||||
return node === parent.test;
|
||||
case "DoWhileStatement":
|
||||
return node === parent.body;
|
||||
case "ForStatement":
|
||||
return node === (parent.update || parent.test || parent.body);
|
||||
case "ForInStatement":
|
||||
case "ForOfStatement":
|
||||
return node === parent.left;
|
||||
if (parent) {
|
||||
switch (parent.type) {
|
||||
case "WhileStatement":
|
||||
return node === parent.test;
|
||||
case "DoWhileStatement":
|
||||
return node === parent.body;
|
||||
case "ForStatement":
|
||||
return node === (parent.update || parent.test || parent.body);
|
||||
case "ForInStatement":
|
||||
case "ForOfStatement":
|
||||
return node === parent.left;
|
||||
|
||||
// no default
|
||||
}
|
||||
}
|
||||
// no default
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,124 +62,124 @@ function isLoopingTarget(node) {
|
||||
* @returns {Array} a new array that represents `arrA \ arrB`.
|
||||
*/
|
||||
function getDifference(arrA, arrB) {
|
||||
return arrA.filter(a => !arrB.includes(a));
|
||||
return arrA.filter(a => !arrB.includes(a));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
meta: {
|
||||
type: "problem",
|
||||
|
||||
defaultOptions: [{ ignore: [] }],
|
||||
docs: {
|
||||
description: "Disallow loops with a body that allows only one iteration",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-unreachable-loop"
|
||||
},
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow loops with a body that allows only one iteration",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-unreachable-loop",
|
||||
},
|
||||
schema: [{
|
||||
type: "object",
|
||||
properties: {
|
||||
ignore: {
|
||||
type: "array",
|
||||
items: {
|
||||
enum: allLoopTypes
|
||||
},
|
||||
uniqueItems: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}],
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
ignore: {
|
||||
type: "array",
|
||||
items: {
|
||||
enum: allLoopTypes,
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
invalid: "Invalid loop. Its body allows only one iteration."
|
||||
}
|
||||
},
|
||||
|
||||
messages: {
|
||||
invalid: "Invalid loop. Its body allows only one iteration.",
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
const ignoredLoopTypes = context.options[0] && context.options[0].ignore || [],
|
||||
loopTypesToCheck = getDifference(allLoopTypes, ignoredLoopTypes),
|
||||
loopSelector = loopTypesToCheck.join(","),
|
||||
loopsByTargetSegments = new Map(),
|
||||
loopsToReport = new Set();
|
||||
|
||||
create(context) {
|
||||
const [{ ignore: ignoredLoopTypes }] = context.options;
|
||||
const loopTypesToCheck = getDifference(allLoopTypes, ignoredLoopTypes),
|
||||
loopSelector = loopTypesToCheck.join(","),
|
||||
loopsByTargetSegments = new Map(),
|
||||
loopsToReport = new Set();
|
||||
const codePathSegments = [];
|
||||
let currentCodePathSegments = new Set();
|
||||
|
||||
const codePathSegments = [];
|
||||
let currentCodePathSegments = new Set();
|
||||
return {
|
||||
|
||||
return {
|
||||
onCodePathStart() {
|
||||
codePathSegments.push(currentCodePathSegments);
|
||||
currentCodePathSegments = new Set();
|
||||
},
|
||||
onCodePathStart() {
|
||||
codePathSegments.push(currentCodePathSegments);
|
||||
currentCodePathSegments = new Set();
|
||||
},
|
||||
|
||||
onCodePathEnd() {
|
||||
currentCodePathSegments = codePathSegments.pop();
|
||||
},
|
||||
onCodePathEnd() {
|
||||
currentCodePathSegments = codePathSegments.pop();
|
||||
},
|
||||
|
||||
onUnreachableCodePathSegmentStart(segment) {
|
||||
currentCodePathSegments.add(segment);
|
||||
},
|
||||
onUnreachableCodePathSegmentStart(segment) {
|
||||
currentCodePathSegments.add(segment);
|
||||
},
|
||||
|
||||
onUnreachableCodePathSegmentEnd(segment) {
|
||||
currentCodePathSegments.delete(segment);
|
||||
},
|
||||
onUnreachableCodePathSegmentEnd(segment) {
|
||||
currentCodePathSegments.delete(segment);
|
||||
},
|
||||
|
||||
onCodePathSegmentEnd(segment) {
|
||||
currentCodePathSegments.delete(segment);
|
||||
},
|
||||
onCodePathSegmentEnd(segment) {
|
||||
currentCodePathSegments.delete(segment);
|
||||
},
|
||||
|
||||
onCodePathSegmentStart(segment, node) {
|
||||
currentCodePathSegments.add(segment);
|
||||
onCodePathSegmentStart(segment, node) {
|
||||
|
||||
if (isLoopingTarget(node)) {
|
||||
const loop = node.parent;
|
||||
currentCodePathSegments.add(segment);
|
||||
|
||||
loopsByTargetSegments.set(segment, loop);
|
||||
}
|
||||
},
|
||||
if (isLoopingTarget(node)) {
|
||||
const loop = node.parent;
|
||||
|
||||
onCodePathSegmentLoop(_, toSegment, node) {
|
||||
const loop = loopsByTargetSegments.get(toSegment);
|
||||
loopsByTargetSegments.set(segment, loop);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The second iteration is reachable, meaning that the loop is valid by the logic of this rule,
|
||||
* only if there is at least one loop event with the appropriate target (which has been already
|
||||
* determined in the `loopsByTargetSegments` map), raised from either:
|
||||
*
|
||||
* - the end of the loop's body (in which case `node === loop`)
|
||||
* - a `continue` statement
|
||||
*
|
||||
* This condition skips loop events raised from `ForInStatement > .right` and `ForOfStatement > .right` nodes.
|
||||
*/
|
||||
if (node === loop || node.type === "ContinueStatement") {
|
||||
// Removes loop if it exists in the set. Otherwise, `Set#delete` has no effect and doesn't throw.
|
||||
loopsToReport.delete(loop);
|
||||
}
|
||||
},
|
||||
onCodePathSegmentLoop(_, toSegment, node) {
|
||||
const loop = loopsByTargetSegments.get(toSegment);
|
||||
|
||||
[loopSelector](node) {
|
||||
/**
|
||||
* Ignore unreachable loop statements to avoid unnecessary complexity in the implementation, or false positives otherwise.
|
||||
* For unreachable segments, the code path analysis does not raise events required for this implementation.
|
||||
*/
|
||||
if (isAnySegmentReachable(currentCodePathSegments)) {
|
||||
loopsToReport.add(node);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The second iteration is reachable, meaning that the loop is valid by the logic of this rule,
|
||||
* only if there is at least one loop event with the appropriate target (which has been already
|
||||
* determined in the `loopsByTargetSegments` map), raised from either:
|
||||
*
|
||||
* - the end of the loop's body (in which case `node === loop`)
|
||||
* - a `continue` statement
|
||||
*
|
||||
* This condition skips loop events raised from `ForInStatement > .right` and `ForOfStatement > .right` nodes.
|
||||
*/
|
||||
if (node === loop || node.type === "ContinueStatement") {
|
||||
|
||||
"Program:exit"() {
|
||||
loopsToReport.forEach(node =>
|
||||
context.report({ node, messageId: "invalid" }),
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
// Removes loop if it exists in the set. Otherwise, `Set#delete` has no effect and doesn't throw.
|
||||
loopsToReport.delete(loop);
|
||||
}
|
||||
},
|
||||
|
||||
[loopSelector](node) {
|
||||
|
||||
/**
|
||||
* Ignore unreachable loop statements to avoid unnecessary complexity in the implementation, or false positives otherwise.
|
||||
* For unreachable segments, the code path analysis does not raise events required for this implementation.
|
||||
*/
|
||||
if (isAnySegmentReachable(currentCodePathSegments)) {
|
||||
loopsToReport.add(node);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"Program:exit"() {
|
||||
loopsToReport.forEach(
|
||||
node => context.report({ node, messageId: "invalid" })
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user