Spaces:
Runtime error
Runtime error
; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
exports.isStaticValueIdentifier = exports.validateNode = void 0; | |
const errors_1 = require("./errors"); | |
const token_store_1 = require("./token-store"); | |
const utils_1 = require("./utils"); | |
const require_utils_1 = require("./modules/require-utils"); | |
const lineBreakPattern = /\r\n|[\n\r\u2028\u2029]/u; | |
const octalNumericLiteralPattern = /^0[Oo]/u; | |
const legacyOctalNumericLiteralPattern = /^0\d/u; | |
const binaryNumericLiteralPattern = /^0[Bb]/u; | |
let cacheCodePointEscapeMatcher; | |
function getCodePointEscapeMatcher() { | |
if (!cacheCodePointEscapeMatcher) { | |
const utils = (0, require_utils_1.loadNewest)([ | |
{ | |
getPkg() { | |
return (0, require_utils_1.requireFromCwd)("eslint-utils/package.json"); | |
}, | |
get() { | |
return (0, require_utils_1.requireFromCwd)("eslint-utils"); | |
}, | |
}, | |
{ | |
getPkg() { | |
return (0, require_utils_1.requireFromLinter)("eslint-utils/package.json"); | |
}, | |
get() { | |
return (0, require_utils_1.requireFromLinter)("eslint-utils"); | |
}, | |
}, | |
{ | |
getPkg() { | |
return require("eslint-utils/package.json"); | |
}, | |
get() { | |
return require("eslint-utils"); | |
}, | |
}, | |
]); | |
cacheCodePointEscapeMatcher = new utils.PatternMatcher(/\\u\{[\dA-Fa-f]+\}/gu); | |
} | |
return cacheCodePointEscapeMatcher; | |
} | |
function validateNode(node, tokens, ctx) { | |
if (node.type === "ObjectExpression") { | |
validateObjectExpressionNode(node, tokens, ctx); | |
return; | |
} | |
if (node.type === "Property") { | |
validatePropertyNode(node, tokens, ctx); | |
return; | |
} | |
if (node.type === "ArrayExpression") { | |
validateArrayExpressionNode(node, tokens, ctx); | |
return; | |
} | |
if (node.type === "Literal") { | |
validateLiteralNode(node, tokens, ctx); | |
return; | |
} | |
if (node.type === "UnaryExpression") { | |
validateUnaryExpressionNode(node, tokens, ctx); | |
return; | |
} | |
if (node.type === "Identifier") { | |
validateIdentifierNode(node, tokens, ctx); | |
return; | |
} | |
if (node.type === "TemplateLiteral") { | |
validateTemplateLiteralNode(node, tokens, ctx); | |
return; | |
} | |
if (node.type === "TemplateElement") { | |
validateTemplateElementNode(node, tokens); | |
return; | |
} | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
exports.validateNode = validateNode; | |
function validateObjectExpressionNode(node, tokens, ctx) { | |
if (node.type !== "ObjectExpression") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
for (const prop of node.properties) { | |
setParent(prop, node); | |
} | |
if (!ctx.trailingCommas) { | |
const token = tokens.getTokenBefore(tokens.getLastToken(node)); | |
if (token && (0, token_store_1.isComma)(token)) { | |
throw (0, errors_1.throwUnexpectedTokenError)(",", token); | |
} | |
} | |
} | |
function validatePropertyNode(node, tokens, ctx) { | |
if (node.type !== "Property") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
setParent(node.key, node); | |
setParent(node.value, node); | |
if (node.computed) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
if (node.method) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node.value, tokens); | |
} | |
if (node.shorthand) { | |
throw (0, errors_1.throwExpectedTokenError)(":", node); | |
} | |
if (node.kind !== "init") { | |
throw (0, errors_1.throwExpectedTokenError)(":", tokens.getFirstToken(node)); | |
} | |
if (node.key.type === "Literal") { | |
const keyValueType = typeof node.key.value; | |
if (keyValueType === "number") { | |
if (!ctx.numberProperties) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node.key, tokens); | |
} | |
} | |
else if (keyValueType !== "string") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node.key, tokens); | |
} | |
} | |
else if (node.key.type === "Identifier") { | |
if (!ctx.unquoteProperties) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node.key, tokens); | |
} | |
} | |
else { | |
throw (0, errors_1.throwUnexpectedNodeError)(node.key, tokens); | |
} | |
if (node.value.type === "Identifier") { | |
if (!isStaticValueIdentifier(node.value, ctx)) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node.value, tokens); | |
} | |
} | |
} | |
function validateArrayExpressionNode(node, tokens, ctx) { | |
if (node.type !== "ArrayExpression") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
if (!ctx.trailingCommas) { | |
const token = tokens.getTokenBefore(tokens.getLastToken(node)); | |
if (token && (0, token_store_1.isComma)(token)) { | |
throw (0, errors_1.throwUnexpectedTokenError)(",", token); | |
} | |
} | |
node.elements.forEach((child, index) => { | |
if (!child) { | |
if (ctx.sparseArrays) { | |
return; | |
} | |
const beforeIndex = index - 1; | |
const before = beforeIndex >= 0 | |
? tokens.getLastToken(node.elements[beforeIndex]) | |
: tokens.getFirstToken(node); | |
throw (0, errors_1.throwUnexpectedTokenError)(",", tokens.getTokenAfter(before, token_store_1.isComma)); | |
} | |
if (child.type === "Identifier") { | |
if (!isStaticValueIdentifier(child, ctx)) { | |
throw (0, errors_1.throwUnexpectedNodeError)(child, tokens); | |
} | |
} | |
setParent(child, node); | |
}); | |
} | |
function validateLiteralNode(node, tokens, ctx) { | |
if (node.type !== "Literal") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
if ((0, utils_1.isRegExpLiteral)(node)) { | |
if (!ctx.regExpLiterals) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
} | |
else if (node.bigint) { | |
if (!ctx.bigintLiterals) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
} | |
else { | |
validateLiteral(node, ctx); | |
} | |
} | |
function validateLiteral(node, ctx) { | |
const value = node.value; | |
if ((!ctx.invalidJsonNumbers || | |
!ctx.leadingOrTrailingDecimalPoints || | |
!ctx.numericSeparators) && | |
typeof value === "number") { | |
const text = node.raw; | |
if (!ctx.leadingOrTrailingDecimalPoints) { | |
if (text.startsWith(".")) { | |
throw (0, errors_1.throwUnexpectedTokenError)(".", node); | |
} | |
if (text.endsWith(".")) { | |
throw (0, errors_1.throwUnexpectedTokenError)(".", { | |
range: [node.range[1] - 1, node.range[1]], | |
loc: { | |
start: { | |
line: node.loc.end.line, | |
column: node.loc.end.column - 1, | |
}, | |
end: node.loc.end, | |
}, | |
}); | |
} | |
} | |
if (!ctx.numericSeparators) { | |
if (text.includes("_")) { | |
const index = text.indexOf("_"); | |
throw (0, errors_1.throwUnexpectedTokenError)("_", { | |
range: [node.range[0] + index, node.range[0] + index + 1], | |
loc: { | |
start: { | |
line: node.loc.start.line, | |
column: node.loc.start.column + index, | |
}, | |
end: { | |
line: node.loc.start.line, | |
column: node.loc.start.column + index + 1, | |
}, | |
}, | |
}); | |
} | |
} | |
if (!ctx.octalNumericLiterals) { | |
if (octalNumericLiteralPattern.test(text)) { | |
throw (0, errors_1.throwUnexpectedError)("octal numeric literal", node); | |
} | |
} | |
if (!ctx.legacyOctalNumericLiterals) { | |
if (legacyOctalNumericLiteralPattern.test(text)) { | |
throw (0, errors_1.throwUnexpectedError)("legacy octal numeric literal", node); | |
} | |
} | |
if (!ctx.binaryNumericLiterals) { | |
if (binaryNumericLiteralPattern.test(text)) { | |
throw (0, errors_1.throwUnexpectedError)("binary numeric literal", node); | |
} | |
} | |
if (!ctx.invalidJsonNumbers) { | |
try { | |
JSON.parse(text); | |
} | |
catch (_a) { | |
throw (0, errors_1.throwInvalidNumberError)(text, node); | |
} | |
} | |
} | |
if ((!ctx.multilineStrings || | |
!ctx.singleQuotes || | |
!ctx.unicodeCodepointEscapes) && | |
typeof value === "string") { | |
if (!ctx.singleQuotes) { | |
if (node.raw.startsWith("'")) { | |
throw (0, errors_1.throwUnexpectedError)("single quoted", node); | |
} | |
} | |
if (!ctx.multilineStrings) { | |
if (lineBreakPattern.test(node.raw)) { | |
throw (0, errors_1.throwUnexpectedError)("multiline string", node); | |
} | |
} | |
if (!ctx.unicodeCodepointEscapes) { | |
if (getCodePointEscapeMatcher().test(node.raw)) { | |
throw (0, errors_1.throwUnexpectedError)("unicode codepoint escape", node); | |
} | |
} | |
} | |
return undefined; | |
} | |
function validateUnaryExpressionNode(node, tokens, ctx) { | |
if (node.type !== "UnaryExpression") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
const operator = node.operator; | |
if (operator === "+") { | |
if (!ctx.plusSigns) { | |
throw (0, errors_1.throwUnexpectedTokenError)("+", node); | |
} | |
} | |
else if (operator !== "-") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
const argument = node.argument; | |
if (argument.type === "Literal") { | |
if (typeof argument.value !== "number") { | |
throw (0, errors_1.throwUnexpectedNodeError)(argument, tokens); | |
} | |
} | |
else if (argument.type === "Identifier") { | |
if (!isNumberIdentifier(argument, ctx)) { | |
throw (0, errors_1.throwUnexpectedNodeError)(argument, tokens); | |
} | |
} | |
else { | |
throw (0, errors_1.throwUnexpectedNodeError)(argument, tokens); | |
} | |
if (!ctx.spacedSigns) { | |
if (node.range[0] + 1 < argument.range[0]) { | |
throw (0, errors_1.throwUnexpectedSpaceError)(tokens.getFirstToken(node)); | |
} | |
} | |
setParent(argument, node); | |
} | |
function validateIdentifierNode(node, tokens, ctx) { | |
if (node.type !== "Identifier") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
if (!ctx.escapeSequenceInIdentifier) { | |
if (node.name.length < node.range[1] - node.range[0]) { | |
throw (0, errors_1.throwUnexpectedError)("escape sequence", node); | |
} | |
} | |
} | |
function validateTemplateLiteralNode(node, tokens, ctx) { | |
if (node.type !== "TemplateLiteral") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
if (!ctx.templateLiterals) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
if (node.expressions.length) { | |
const token = tokens.getFirstToken(node.quasis[0]); | |
const loc = { | |
loc: { | |
start: { | |
line: token.loc.end.line, | |
column: token.loc.end.column - 2, | |
}, | |
end: token.loc.end, | |
}, | |
range: [token.range[1] - 2, token.range[1]], | |
}; | |
throw (0, errors_1.throwUnexpectedTokenError)("$", loc); | |
} | |
if (!ctx.unicodeCodepointEscapes) { | |
if (getCodePointEscapeMatcher().test(node.quasis[0].value.raw)) { | |
throw (0, errors_1.throwUnexpectedError)("unicode codepoint escape", node); | |
} | |
} | |
for (const q of node.quasis) { | |
setParent(q, node); | |
} | |
} | |
function validateTemplateElementNode(node, tokens) { | |
if (node.type !== "TemplateElement") { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
const { cooked } = node.value; | |
if (cooked == null) { | |
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens); | |
} | |
const startOffset = -1; | |
const endOffset = node.tail ? 1 : 2; | |
node.start += startOffset; | |
node.end += endOffset; | |
node.range[0] += startOffset; | |
node.range[1] += endOffset; | |
node.loc.start.column += startOffset; | |
node.loc.end.column += endOffset; | |
} | |
function isStaticValueIdentifier(node, ctx) { | |
if (isNumberIdentifier(node, ctx)) { | |
return true; | |
} | |
return node.name === "undefined" && ctx.undefinedKeywords; | |
} | |
exports.isStaticValueIdentifier = isStaticValueIdentifier; | |
function isNumberIdentifier(node, ctx) { | |
if (node.name === "Infinity" && ctx.infinities) { | |
return true; | |
} | |
if (node.name === "NaN" && ctx.nans) { | |
return true; | |
} | |
return false; | |
} | |
function setParent(prop, parent) { | |
; | |
prop.parent = parent; | |
} | |