Permalink
Cannot retrieve contributors at this time
211 lines (186 sloc)
6.41 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/eslint-plugin-eslint-comments/lib/internal/disabled-area.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Toru Nagashima <https://github.com/mysticatea> | |
* See LICENSE file in root directory for full license. | |
*/ | |
"use strict" | |
const utils = require("./utils") | |
const DELIMITER = /[\s,]+/gu | |
const pool = new WeakMap() | |
module.exports = class DisabledArea { | |
/** | |
* Get singleton instance for the given source code. | |
* | |
* @param {eslint.SourceCode} sourceCode - The source code to get. | |
* @returns {DisabledArea} The singleton object for the source code. | |
*/ | |
static get(sourceCode) { | |
let retv = pool.get(sourceCode.ast) | |
if (retv == null) { | |
retv = new DisabledArea() | |
retv._scan(sourceCode) | |
pool.set(sourceCode.ast, retv) | |
} | |
return retv | |
} | |
/** | |
* Constructor. | |
*/ | |
constructor() { | |
this.areas = [] | |
this.duplicateDisableDirectives = [] | |
this.unusedEnableDirectives = [] | |
this.numberOfRelatedDisableDirectives = new Map() | |
} | |
/** | |
* Make disabled area. | |
* | |
* @param {Token} comment - The comment token to disable. | |
* @param {object} location - The start location to disable. | |
* @param {string[]|null} ruleIds - The ruleId names to disable. | |
* @param {string} kind - The kind of disable-comments. | |
* @returns {void} | |
* @private | |
*/ | |
_disable(comment, location, ruleIds, kind) { | |
if (ruleIds) { | |
for (const ruleId of ruleIds) { | |
if (this._getArea(ruleId, location) != null) { | |
this.duplicateDisableDirectives.push({ comment, ruleId }) | |
} | |
this.areas.push({ | |
comment, | |
ruleId, | |
kind, | |
start: location, | |
end: null, | |
}) | |
} | |
} else { | |
if (this._getArea(null, location) != null) { | |
this.duplicateDisableDirectives.push({ comment, ruleId: null }) | |
} | |
this.areas.push({ | |
comment, | |
ruleId: null, | |
kind, | |
start: location, | |
end: null, | |
}) | |
} | |
} | |
/** | |
* Close disabled area. | |
* | |
* @param {Token} comment - The comment token to enable. | |
* @param {object} location - The start location to enable. | |
* @param {string[]|null} ruleIds - The ruleId names to enable. | |
* @param {string} kind - The kind of disable-comments. | |
* @returns {void} | |
* @private | |
*/ | |
_enable(comment, location, ruleIds, kind) { | |
const relatedDisableDirectives = new Set() | |
if (ruleIds) { | |
for (const ruleId of ruleIds) { | |
let used = false | |
for (let i = this.areas.length - 1; i >= 0; --i) { | |
const area = this.areas[i] | |
if ( | |
area.end === null && | |
area.kind === kind && | |
area.ruleId === ruleId | |
) { | |
relatedDisableDirectives.add(area.comment) | |
area.end = location | |
used = true | |
} | |
} | |
if (!used) { | |
this.unusedEnableDirectives.push({ comment, ruleId }) | |
} | |
} | |
} else { | |
let used = false | |
for (let i = this.areas.length - 1; i >= 0; --i) { | |
const area = this.areas[i] | |
if (area.end === null && area.kind === kind) { | |
relatedDisableDirectives.add(area.comment) | |
area.end = location | |
used = true | |
} | |
} | |
if (!used) { | |
this.unusedEnableDirectives.push({ comment, ruleId: null }) | |
} | |
} | |
this.numberOfRelatedDisableDirectives.set( | |
comment, | |
relatedDisableDirectives.size | |
) | |
} | |
/** | |
* Gets the area of the given ruleId and location. | |
* | |
* @param {string|null} ruleId - The ruleId name to get. | |
* @param {object} location - The location to get. | |
* @returns {object|null} The area of the given ruleId and location. | |
* @private | |
*/ | |
_getArea(ruleId, location) { | |
for (let i = this.areas.length - 1; i >= 0; --i) { | |
const area = this.areas[i] | |
if ( | |
(area.ruleId === null || area.ruleId === ruleId) && | |
utils.lte(area.start, location) && | |
(area.end === null || utils.lte(location, area.end)) | |
) { | |
return area | |
} | |
} | |
return null | |
} | |
/** | |
* Scan the source code and setup disabled area list. | |
* | |
* @param {eslint.SourceCode} sourceCode - The source code to scan. | |
* @returns {void} | |
* @private | |
*/ | |
_scan(sourceCode) { | |
for (const comment of sourceCode.getAllComments()) { | |
const directiveComment = utils.parseDirectiveComment(comment) | |
if (directiveComment == null) { | |
continue | |
} | |
const kind = directiveComment.kind | |
if ( | |
kind !== "eslint-disable" && | |
kind !== "eslint-enable" && | |
kind !== "eslint-disable-line" && | |
kind !== "eslint-disable-next-line" | |
) { | |
continue | |
} | |
const ruleIds = directiveComment.value | |
? directiveComment.value.split(DELIMITER) | |
: null | |
if (kind === "eslint-disable") { | |
this._disable(comment, comment.loc.start, ruleIds, "block") | |
} else if (kind === "eslint-enable") { | |
this._enable(comment, comment.loc.start, ruleIds, "block") | |
} else if (kind === "eslint-disable-line") { | |
const line = comment.loc.start.line | |
const start = { line, column: 0 } | |
const end = { line: line + 1, column: -1 } | |
this._disable(comment, start, ruleIds, "line") | |
this._enable(comment, end, ruleIds, "line") | |
} else if (kind === "eslint-disable-next-line") { | |
const line = comment.loc.start.line | |
const start = { line: line + 1, column: 0 } | |
const end = { line: line + 2, column: -1 } | |
this._disable(comment, start, ruleIds, "line") | |
this._enable(comment, end, ruleIds, "line") | |
} | |
} | |
} | |
} |