mirror of
https://github.com/joelwmale/webhook-action.git
synced 2024-11-29 19:05:22 +01:00
153 lines
4.8 KiB
JavaScript
153 lines
4.8 KiB
JavaScript
|
/**
|
||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||
|
* See LICENSE file in root directory for full license.
|
||
|
*/
|
||
|
"use strict"
|
||
|
|
||
|
const escapeStringRegexp = require("escape-string-regexp")
|
||
|
const LINE_PATTERN = /[^\r\n\u2028\u2029]*(?:\r\n|[\r\n\u2028\u2029]|$)/gu
|
||
|
|
||
|
const DIRECTIVE_PATTERN = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u
|
||
|
const LINE_COMMENT_PATTERN = /^eslint-disable-(next-)?line$/u
|
||
|
|
||
|
module.exports = {
|
||
|
/**
|
||
|
* Make the location ignoring `eslint-disable` comments.
|
||
|
*
|
||
|
* @param {object} location - The location to convert.
|
||
|
* @returns {object} Converted location.
|
||
|
*/
|
||
|
toForceLocation(location) {
|
||
|
return {
|
||
|
start: {
|
||
|
line: location.start.line,
|
||
|
column: -1,
|
||
|
},
|
||
|
end: location.end,
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Calculate the location of the given rule in the given comment token.
|
||
|
*
|
||
|
* @param {Token} comment - The comment token to calculate.
|
||
|
* @param {string|null} ruleId - The rule name to calculate.
|
||
|
* @returns {object} The location of the given information.
|
||
|
*/
|
||
|
toRuleIdLocation(comment, ruleId) {
|
||
|
if (ruleId == null) {
|
||
|
return module.exports.toForceLocation(comment.loc)
|
||
|
}
|
||
|
|
||
|
const lines = comment.value.match(LINE_PATTERN)
|
||
|
//eslint-disable-next-line require-unicode-regexp
|
||
|
const ruleIdPattern = new RegExp(
|
||
|
`([\\s,]|^)${escapeStringRegexp(ruleId)}(?:[\\s,]|$)`
|
||
|
)
|
||
|
|
||
|
{
|
||
|
const m = ruleIdPattern.exec(lines[0])
|
||
|
if (m != null) {
|
||
|
const start = comment.loc.start
|
||
|
return {
|
||
|
start: {
|
||
|
line: start.line,
|
||
|
column: 2 + start.column + m.index + m[1].length,
|
||
|
},
|
||
|
end: {
|
||
|
line: start.line,
|
||
|
column:
|
||
|
2 +
|
||
|
start.column +
|
||
|
m.index +
|
||
|
m[1].length +
|
||
|
ruleId.length,
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (let i = 1; i < lines.length; ++i) {
|
||
|
const m = ruleIdPattern.exec(lines[i])
|
||
|
if (m != null) {
|
||
|
const start = comment.loc.start
|
||
|
return {
|
||
|
start: {
|
||
|
line: start.line + i,
|
||
|
column: m.index + m[1].length,
|
||
|
},
|
||
|
end: {
|
||
|
line: start.line + i,
|
||
|
column: m.index + m[1].length + ruleId.length,
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*istanbul ignore next : foolproof */
|
||
|
return comment.loc
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks `a` is less than `b` or `a` equals `b`.
|
||
|
*
|
||
|
* @param {{line: number, column: number}} a - A location to compare.
|
||
|
* @param {{line: number, column: number}} b - Another location to compare.
|
||
|
* @returns {boolean} `true` if `a` is less than `b` or `a` equals `b`.
|
||
|
*/
|
||
|
lte(a, b) {
|
||
|
return a.line < b.line || (a.line === b.line && a.column <= b.column)
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Parse the given comment token as a directive comment.
|
||
|
*
|
||
|
* @param {Token} comment - The comment token to parse.
|
||
|
* @returns {{kind: string, value: string, description: string | null}|null} The parsed data of the given comment. If `null`, it is not a directive comment.
|
||
|
*/
|
||
|
parseDirectiveComment(comment) {
|
||
|
const { text, description } = divideDirectiveComment(comment.value)
|
||
|
const match = DIRECTIVE_PATTERN.exec(text)
|
||
|
|
||
|
if (!match) {
|
||
|
return null
|
||
|
}
|
||
|
const directiveText = match[1]
|
||
|
const lineCommentSupported = LINE_COMMENT_PATTERN.test(directiveText)
|
||
|
|
||
|
if (comment.type === "Line" && !lineCommentSupported) {
|
||
|
return null
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
lineCommentSupported &&
|
||
|
comment.loc.start.line !== comment.loc.end.line
|
||
|
) {
|
||
|
// disable-line comment should not span multiple lines.
|
||
|
return null
|
||
|
}
|
||
|
|
||
|
const directiveValue = text.slice(match.index + directiveText.length)
|
||
|
|
||
|
return {
|
||
|
kind: directiveText,
|
||
|
value: directiveValue.trim(),
|
||
|
description,
|
||
|
}
|
||
|
},
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Divides and trims description text and directive comments.
|
||
|
* @param {string} value The comment text to strip.
|
||
|
* @returns {{text: string, description: string | null}} The stripped text.
|
||
|
*/
|
||
|
function divideDirectiveComment(value) {
|
||
|
const divided = value.split(/\s-{2,}\s/u)
|
||
|
const text = divided[0].trim()
|
||
|
return {
|
||
|
text,
|
||
|
description: divided.length > 1 ? divided[1].trim() : null,
|
||
|
}
|
||
|
}
|