Files
codeql-action/node_modules/eslint/lib/linter/code-path-analysis/code-path.js
dependabot[bot] dd1128f4f1 Bump the npm group with 11 updates (#1892)
* Bump the npm group with 11 updates

Bumps the npm group with 11 updates:

| Package | From | To |
| --- | --- | --- |
| [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) | `1.1.1` | `1.1.2` |
| [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) | `1.10.0` | `1.10.1` |
| [uuid](https://github.com/uuidjs/uuid) | `9.0.0` | `9.0.1` |
| [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) | `9.0.3` | `9.0.4` |
| [@types/adm-zip](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/adm-zip) | `0.5.0` | `0.5.1` |
| [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) | `4.0.5` | `4.0.6` |
| [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) | `7.5.1` | `7.5.2` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `6.5.0` | `6.7.2` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.6.0` | `6.7.2` |
| [eslint](https://github.com/eslint/eslint) | `8.48.0` | `8.49.0` |
| [sinon](https://github.com/sinonjs/sinon) | `15.2.0` | `16.0.0` |


Updates `@actions/artifact` from 1.1.1 to 1.1.2
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/artifact/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/artifact)

Updates `@actions/core` from 1.10.0 to 1.10.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Updates `uuid` from 9.0.0 to 9.0.1
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1)

Updates `@types/uuid` from 9.0.3 to 9.0.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

Updates `@types/adm-zip` from 0.5.0 to 0.5.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/adm-zip)

Updates `@types/js-yaml` from 4.0.5 to 4.0.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Updates `@types/semver` from 7.5.1 to 7.5.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

Updates `@typescript-eslint/eslint-plugin` from 6.5.0 to 6.7.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.2/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.6.0 to 6.7.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.2/packages/parser)

Updates `eslint` from 8.48.0 to 8.49.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.48.0...v8.49.0)

Updates `sinon` from 15.2.0 to 16.0.0
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.2.0...v16.0.0)

---
updated-dependencies:
- dependency-name: "@actions/artifact"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/uuid"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/adm-zip"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/js-yaml"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/semver"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update checked-in dependencies

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-09-18 20:01:16 +00:00

249 lines
7.3 KiB
JavaScript

/**
* @fileoverview A class of the code path.
* @author Toru Nagashima
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const CodePathState = require("./code-path-state");
const IdGenerator = require("./id-generator");
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
/**
* 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;
/**
* The code path of the upper function scope.
* @type {CodePath|null}
*/
this.upper = upper;
/**
* The code paths of nested function scopes.
* @type {CodePath[]}
*/
this.childCodePaths = [];
// Initializes internal state.
Object.defineProperty(
this,
"internal",
{ value: new CodePathState(new IdGenerator(`${id}_`), onLooped) }
);
// Adds this into `childCodePaths` of `upper`.
if (upper) {
upper.childCodePaths.push(this);
}
}
/**
* 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;
}
/**
* The initial code path segment.
* @type {CodePathSegment}
*/
get initialSegment() {
return this.internal.initialSegment;
}
/**
* Final code path segments.
* This array is a mix of `returnedSegments` and `thrownSegments`.
* @type {CodePathSegment[]}
*/
get finalSegments() {
return this.internal.finalSegments;
}
/**
* Final code path segments which is with `return` statements.
* This array contains the last path segment if it's reachable.
* Since the reachable last path returns `undefined`.
* @type {CodePathSegment[]}
*/
get returnedSegments() {
return this.internal.returnedForkContext;
}
/**
* Final code path segments which is with `throw` statements.
* @type {CodePathSegment[]}
*/
get thrownSegments() {
return this.internal.thrownForkContext;
}
/**
* Current code path segments.
* @type {CodePathSegment[]}
* @deprecated
*/
get currentSegments() {
return this.internal.currentSegments;
}
/**
* Traverses all segments in this code path.
*
* codePath.traverseSegments(function(segment, controller) {
* // do something.
* });
*
* This method enumerates segments in order from the head.
*
* The `controller` object has two methods.
*
* - `controller.skip()` - Skip the following segments in this branch.
* - `controller.break()` - Skip all following segments.
* @param {Object} [options] Omittable.
* @param {CodePathSegment} [options.first] The first segment to traverse.
* @param {CodePathSegment} [options.last] The last segment to traverse.
* @param {Function} callback A callback function.
* @returns {void}
*/
traverseSegments(options, callback) {
let resolvedOptions;
let resolvedCallback;
if (typeof options === "function") {
resolvedCallback = options;
resolvedOptions = {};
} else {
resolvedOptions = options || {};
resolvedCallback = callback;
}
const startSegment = resolvedOptions.first || this.internal.initialSegment;
const lastSegment = resolvedOptions.last;
let item = null;
let index = 0;
let end = 0;
let segment = null;
const visited = Object.create(null);
const stack = [[startSegment, 0]];
let skippedSegment = null;
let broken = false;
const controller = {
skip() {
if (stack.length <= 1) {
broken = true;
} else {
skippedSegment = stack[stack.length - 2][0];
}
},
break() {
broken = true;
}
};
/**
* Checks 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[prevSegment.id] ||
segment.isLoopedPrevSegment(prevSegment)
);
}
while (stack.length > 0) {
item = stack[stack.length - 1];
segment = item[0];
index = item[1];
if (index === 0) {
// Skip if this segment has been visited already.
if (visited[segment.id]) {
stack.pop();
continue;
}
// 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 flag of skipping if all branches have been skipped.
if (skippedSegment && segment.prevSegments.includes(skippedSegment)) {
skippedSegment = null;
}
visited[segment.id] = true;
// Call the callback when the first time.
if (!skippedSegment) {
resolvedCallback.call(this, segment, controller);
if (segment === lastSegment) {
controller.skip();
}
if (broken) {
break;
}
}
}
// Update the stack.
end = segment.nextSegments.length - 1;
if (index < end) {
item[1] += 1;
stack.push([segment.nextSegments[index], 0]);
} else if (index === end) {
item[0] = segment.nextSegments[index];
item[1] = 0;
} else {
stack.pop();
}
}
}
}
module.exports = CodePath;