new changes

This commit is contained in:
Niranjan
2026-04-07 05:05:28 +05:30
parent 7c070224bd
commit a18bba15f2
29975 changed files with 3247495 additions and 2761 deletions

View File

@@ -0,0 +1,12 @@
import { parseForESLint } from "./parser/parser";
import { traverseNodes } from "./parser/traverse";
import { getStaticJSONValue, isExpression, isNumberIdentifier, isUndefinedIdentifier } from "./utils/ast";
import type * as AST from "./parser/ast";
export * as meta from "./meta";
export { name } from "./meta";
export type * from "./types";
export { parseForESLint };
export declare const VisitorKeys: import("eslint").SourceCode.VisitorKeys;
export { traverseNodes, getStaticJSONValue, isExpression, isNumberIdentifier, isUndefinedIdentifier, };
export declare function parseJSON(code: string, options?: any): AST.JSONProgram;
export { AST };

View File

@@ -0,0 +1,44 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseJSON = exports.isUndefinedIdentifier = exports.isNumberIdentifier = exports.isExpression = exports.getStaticJSONValue = exports.traverseNodes = exports.VisitorKeys = exports.parseForESLint = exports.name = exports.meta = void 0;
const parser_1 = require("./parser/parser");
Object.defineProperty(exports, "parseForESLint", { enumerable: true, get: function () { return parser_1.parseForESLint; } });
const traverse_1 = require("./parser/traverse");
Object.defineProperty(exports, "traverseNodes", { enumerable: true, get: function () { return traverse_1.traverseNodes; } });
const ast_1 = require("./utils/ast");
Object.defineProperty(exports, "getStaticJSONValue", { enumerable: true, get: function () { return ast_1.getStaticJSONValue; } });
Object.defineProperty(exports, "isExpression", { enumerable: true, get: function () { return ast_1.isExpression; } });
Object.defineProperty(exports, "isNumberIdentifier", { enumerable: true, get: function () { return ast_1.isNumberIdentifier; } });
Object.defineProperty(exports, "isUndefinedIdentifier", { enumerable: true, get: function () { return ast_1.isUndefinedIdentifier; } });
const visitor_keys_1 = require("./parser/visitor-keys");
exports.meta = __importStar(require("./meta"));
var meta_1 = require("./meta");
Object.defineProperty(exports, "name", { enumerable: true, get: function () { return meta_1.name; } });
exports.VisitorKeys = (0, visitor_keys_1.getVisitorKeys)();
function parseJSON(code, options) {
return (0, parser_1.parseForESLint)(code, options).ast;
}
exports.parseJSON = parseJSON;

View File

@@ -0,0 +1,2 @@
export declare const name: "jsonc-eslint-parser";
export declare const version: "2.4.2";

View File

@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.version = exports.name = void 0;
exports.name = "jsonc-eslint-parser";
exports.version = "2.4.2";

View File

@@ -0,0 +1,126 @@
import type { AST as ESLintAST } from "eslint";
import type { Comment } from "estree";
export interface Locations {
loc: SourceLocation;
range: [number, number];
}
interface BaseJSONNode extends Locations {
type: string;
}
export interface SourceLocation {
start: Position;
end: Position;
}
export interface Position {
line: number;
column: number;
}
export type JSONNode = JSONProgram | JSONExpressionStatement | JSONExpression | JSONProperty | JSONIdentifier | JSONTemplateLiteral | JSONTemplateElement;
export interface JSONProgram extends BaseJSONNode {
type: "Program";
body: [JSONExpressionStatement];
comments: Comment[];
tokens: ESLintAST.Token[];
parent: null;
}
export interface JSONExpressionStatement extends BaseJSONNode {
type: "JSONExpressionStatement";
expression: JSONExpression;
parent: JSONProgram;
}
export type JSONExpression = JSONArrayExpression | JSONObjectExpression | JSONLiteral | JSONUnaryExpression | JSONNumberIdentifier | JSONUndefinedIdentifier | JSONTemplateLiteral | JSONBinaryExpression;
export interface JSONArrayExpression extends BaseJSONNode {
type: "JSONArrayExpression";
elements: (JSONExpression | null)[];
parent: JSONArrayExpression | JSONProperty | JSONExpressionStatement;
}
export interface JSONObjectExpression extends BaseJSONNode {
type: "JSONObjectExpression";
properties: JSONProperty[];
parent: JSONArrayExpression | JSONProperty | JSONExpressionStatement;
}
export interface JSONProperty extends BaseJSONNode {
type: "JSONProperty";
key: JSONIdentifier | JSONStringLiteral | JSONNumberLiteral;
value: JSONExpression;
kind: "init";
method: false;
shorthand: false;
computed: false;
parent: JSONObjectExpression;
}
export interface JSONIdentifier extends BaseJSONNode {
type: "JSONIdentifier";
name: string;
parent?: JSONArrayExpression | JSONProperty | JSONExpressionStatement | JSONUnaryExpression;
}
export interface JSONNumberIdentifier extends JSONIdentifier {
name: "Infinity" | "NaN";
}
export interface JSONUndefinedIdentifier extends JSONIdentifier {
name: "undefined";
}
interface JSONLiteralBase extends BaseJSONNode {
type: "JSONLiteral";
raw: string;
parent?: JSONArrayExpression | JSONProperty | JSONExpressionStatement | JSONUnaryExpression | JSONBinaryExpression;
}
export interface JSONStringLiteral extends JSONLiteralBase {
value: string;
regex: null;
bigint: null;
}
export interface JSONNumberLiteral extends JSONLiteralBase {
value: number;
regex: null;
bigint: null;
}
export interface JSONKeywordLiteral extends JSONLiteralBase {
value: boolean | null;
regex: null;
bigint: null;
}
export interface JSONRegExpLiteral extends JSONLiteralBase {
value: null;
regex: {
pattern: string;
flags: string;
};
bigint: null;
}
export interface JSONBigIntLiteral extends JSONLiteralBase {
value: null;
regex: null;
bigint: string;
}
export type JSONLiteral = JSONStringLiteral | JSONNumberLiteral | JSONKeywordLiteral | JSONRegExpLiteral | JSONBigIntLiteral;
export interface JSONUnaryExpression extends BaseJSONNode {
type: "JSONUnaryExpression";
operator: "-" | "+";
prefix: true;
argument: JSONNumberLiteral | JSONNumberIdentifier;
parent: JSONArrayExpression | JSONProperty | JSONExpressionStatement;
}
export interface JSONTemplateLiteral extends BaseJSONNode {
type: "JSONTemplateLiteral";
quasis: [JSONTemplateElement];
expressions: [];
parent: JSONArrayExpression | JSONProperty | JSONExpressionStatement;
}
export interface JSONTemplateElement extends BaseJSONNode {
type: "JSONTemplateElement";
tail: boolean;
value: {
cooked: string;
raw: string;
};
parent: JSONTemplateLiteral;
}
export interface JSONBinaryExpression extends BaseJSONNode {
type: "JSONBinaryExpression";
operator: "-" | "+" | "*" | "/" | "%" | "**";
left: JSONNumberLiteral | JSONUnaryExpression | JSONBinaryExpression;
right: JSONNumberLiteral | JSONUnaryExpression | JSONBinaryExpression;
parent: JSONArrayExpression | JSONProperty | JSONExpressionStatement | JSONUnaryExpression | JSONBinaryExpression;
}
export {};

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,17 @@
import type { Node } from "estree";
import type { AST } from "eslint";
import type { JSONNode, JSONProgram } from "./ast";
import type { TokenStore } from "./token-store";
import type { Token as AcornToken } from "acorn";
import type { JSONSyntaxContext } from "./syntax-context";
export declare class TokenConvertor {
private readonly ctx;
private readonly code;
private readonly templateBuffer;
private readonly tokTypes;
constructor(ctx: JSONSyntaxContext, code: string);
convertToken(token: AcornToken & {
value: any;
}): AST.Token | null;
}
export declare function convertProgramNode(node: Node | JSONNode, tokens: TokenStore, ctx: JSONSyntaxContext, code: string): JSONProgram;

View File

@@ -0,0 +1,170 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertProgramNode = exports.TokenConvertor = void 0;
const validate_1 = require("./validate");
const errors_1 = require("./errors");
const acorn_1 = require("./modules/acorn");
class TokenConvertor {
constructor(ctx, code) {
this.templateBuffer = [];
this.ctx = ctx;
this.code = code;
this.tokTypes = (0, acorn_1.getAcorn)().tokTypes;
}
convertToken(token) {
const { tokTypes } = this;
let type, value;
const additional = {};
if (token.type === tokTypes.string) {
type = "String";
value = this.code.slice(...token.range);
}
else if (token.type === tokTypes.num) {
type = "Numeric";
value = this.code.slice(...token.range);
}
else if (token.type.keyword) {
if (token.type.keyword === "true" || token.type.keyword === "false") {
type = "Boolean";
}
else if (token.type.keyword === "null") {
type = "Null";
}
else {
type = "Keyword";
}
value = token.value;
}
else if (token.type === tokTypes.braceL ||
token.type === tokTypes.braceR ||
token.type === tokTypes.bracketL ||
token.type === tokTypes.bracketR ||
token.type === tokTypes.colon ||
token.type === tokTypes.comma ||
token.type === tokTypes.plusMin) {
type = "Punctuator";
value = this.code.slice(...token.range);
}
else if (token.type === tokTypes.name) {
type = "Identifier";
value = token.value;
}
else if (token.type === tokTypes.backQuote) {
if (this.templateBuffer.length > 0) {
const first = this.templateBuffer[0];
this.templateBuffer.length = 0;
return {
type: "Template",
value: this.code.slice(first.start, token.end),
range: [first.start, token.end],
loc: {
start: first.loc.start,
end: token.loc.end,
},
};
}
this.templateBuffer.push(token);
return null;
}
else if (token.type === tokTypes.template) {
if (this.templateBuffer.length === 0) {
return (0, errors_1.throwUnexpectedTokenError)(this.code.slice(...token.range), token);
}
this.templateBuffer.push(token);
return null;
}
else if (token.type === tokTypes.regexp) {
const reValue = token.value;
type = "RegularExpression";
additional.regex = {
flags: reValue.flags,
pattern: reValue.pattern,
};
value = `/${reValue.pattern}/${reValue.flags}`;
}
else if (this.ctx.parentheses &&
(token.type === tokTypes.parenL || token.type === tokTypes.parenR)) {
type = "Punctuator";
value = this.code.slice(...token.range);
}
else if (this.ctx.staticExpressions &&
(token.type === tokTypes.star ||
token.type === tokTypes.slash ||
token.type === tokTypes.modulo ||
token.type === tokTypes.starstar)) {
type = "Punctuator";
value = this.code.slice(...token.range);
}
else {
return (0, errors_1.throwUnexpectedTokenError)(this.code.slice(...token.range), token);
}
token.type = type;
token.value = value;
for (const k in additional) {
token[k] = additional[k];
}
return token;
}
}
exports.TokenConvertor = TokenConvertor;
function convertProgramNode(node, tokens, ctx, code) {
if (node.type !== "JSONObjectExpression" &&
node.type !== "JSONArrayExpression" &&
node.type !== "JSONLiteral" &&
node.type !== "JSONUnaryExpression" &&
node.type !== "JSONIdentifier" &&
node.type !== "JSONTemplateLiteral" &&
node.type !== "JSONBinaryExpression") {
return (0, errors_1.throwUnexpectedNodeError)(node, tokens);
}
if (node.type === "JSONIdentifier") {
if (!(0, validate_1.isStaticValueIdentifier)(node, ctx)) {
return (0, errors_1.throwUnexpectedNodeError)(node, tokens);
}
}
const body = Object.assign(Object.assign({ type: "JSONExpressionStatement", expression: node }, cloneLocation(node)), { parent: null });
setParent(node, body);
const end = code.length;
const endLoc = (0, acorn_1.getAcorn)().getLineInfo(code, end);
const nn = {
type: "Program",
body: [body],
comments: [],
tokens: [],
range: [0, end],
loc: {
start: {
line: 1,
column: 0,
},
end: {
line: endLoc.line,
column: endLoc.column,
},
},
parent: null,
};
setParent(body, nn);
return nn;
}
exports.convertProgramNode = convertProgramNode;
function cloneLocation(node) {
const range = node.range;
const loc = node.loc;
return {
range: [range[0], range[1]],
loc: {
start: {
line: loc.start.line,
column: loc.start.column,
},
end: {
line: loc.end.line,
column: loc.end.column,
},
},
};
}
function setParent(prop, parent) {
prop.parent = parent;
}

View File

@@ -0,0 +1,16 @@
import type { Comment, Node } from "estree";
import type { TokenStore, MaybeNodeOrToken } from "./token-store";
import type { JSONNode } from "./ast";
export declare class ParseError extends SyntaxError {
index: number;
lineNumber: number;
column: number;
constructor(message: string, offset: number, line: number, column: number);
}
export declare function throwExpectedTokenError(name: string, beforeToken: MaybeNodeOrToken): never;
export declare function throwUnexpectedError(name: string, token: MaybeNodeOrToken): never;
export declare function throwUnexpectedTokenError(name: string, token: MaybeNodeOrToken): never;
export declare function throwUnexpectedCommentError(token: Comment): never;
export declare function throwUnexpectedSpaceError(beforeToken: MaybeNodeOrToken): never;
export declare function throwInvalidNumberError(text: string, token: MaybeNodeOrToken): never;
export declare function throwUnexpectedNodeError(node: Node | JSONNode, tokens: TokenStore, offset?: number): never;

View File

@@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.throwUnexpectedNodeError = exports.throwInvalidNumberError = exports.throwUnexpectedSpaceError = exports.throwUnexpectedCommentError = exports.throwUnexpectedTokenError = exports.throwUnexpectedError = exports.throwExpectedTokenError = exports.ParseError = void 0;
const utils_1 = require("./utils");
class ParseError extends SyntaxError {
constructor(message, offset, line, column) {
super(message);
this.index = offset;
this.lineNumber = line;
this.column = column;
}
}
exports.ParseError = ParseError;
function throwExpectedTokenError(name, beforeToken) {
const locs = getLocation(beforeToken);
const err = new ParseError(`Expected token '${name}'.`, locs.end, locs.loc.end.line, locs.loc.end.column + 1);
throw err;
}
exports.throwExpectedTokenError = throwExpectedTokenError;
function throwUnexpectedError(name, token) {
const locs = getLocation(token);
const err = new ParseError(`Unexpected ${name}.`, locs.start, locs.loc.start.line, locs.loc.start.column + 1);
throw err;
}
exports.throwUnexpectedError = throwUnexpectedError;
function throwUnexpectedTokenError(name, token) {
return throwUnexpectedError(`token '${name}'`, token);
}
exports.throwUnexpectedTokenError = throwUnexpectedTokenError;
function throwUnexpectedCommentError(token) {
return throwUnexpectedError("comment", token);
}
exports.throwUnexpectedCommentError = throwUnexpectedCommentError;
function throwUnexpectedSpaceError(beforeToken) {
const locs = getLocation(beforeToken);
const err = new ParseError("Unexpected whitespace.", locs.end, locs.loc.end.line, locs.loc.end.column + 1);
throw err;
}
exports.throwUnexpectedSpaceError = throwUnexpectedSpaceError;
function throwInvalidNumberError(text, token) {
const locs = getLocation(token);
const err = new ParseError(`Invalid number ${text}.`, locs.start, locs.loc.start.line, locs.loc.start.column + 1);
throw err;
}
exports.throwInvalidNumberError = throwInvalidNumberError;
function throwUnexpectedNodeError(node, tokens, offset) {
if (node.type === "Identifier" || node.type === "JSONIdentifier") {
const locs = getLocation(node);
const err = new ParseError(`Unexpected identifier '${node.name}'.`, locs.start, locs.loc.start.line, locs.loc.start.column + 1);
throw err;
}
if (node.type === "Literal" || node.type === "JSONLiteral") {
const type = node.bigint
? "bigint"
: (0, utils_1.isRegExpLiteral)(node)
? "regex"
: node.value === null
? "null"
: typeof node.value;
const locs = getLocation(node);
const err = new ParseError(`Unexpected ${type} literal.`, locs.start, locs.loc.start.line, locs.loc.start.column + 1);
throw err;
}
if (node.type === "TemplateLiteral" || node.type === "JSONTemplateLiteral") {
const locs = getLocation(node);
const err = new ParseError("Unexpected template literal.", locs.start, locs.loc.start.line, locs.loc.start.column + 1);
throw err;
}
if (node.type.endsWith("Expression") && node.type !== "FunctionExpression") {
const name = node.type
.replace(/^JSON/u, "")
.replace(/\B([A-Z])/gu, " $1")
.toLowerCase();
const locs = getLocation(node);
const err = new ParseError(`Unexpected ${name}.`, locs.start, locs.loc.start.line, locs.loc.start.column + 1);
throw err;
}
const index = node.range[0] + (offset || 0);
const t = tokens.findTokenByOffset(index);
const name = (t === null || t === void 0 ? void 0 : t.value) || "unknown";
const locs = getLocation(t || node);
const err = new ParseError(`Unexpected token '${name}'.`, locs.start, locs.loc.start.line, locs.loc.start.column + 1);
throw err;
}
exports.throwUnexpectedNodeError = throwUnexpectedNodeError;
function getLocation(token) {
var _a, _b, _c, _d;
const start = (_b = (_a = token.range) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : token.start;
const end = (_d = (_c = token.range) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : token.end;
const loc = token.loc;
return { start, end, loc };
}

View File

@@ -0,0 +1,3 @@
import type { Parser } from "acorn";
export declare function getParser(): typeof Parser;
export declare function getAnyTokenErrorParser(): typeof Parser;

View File

@@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAnyTokenErrorParser = exports.getParser = void 0;
const validate_1 = require("./validate");
const acorn_1 = require("./modules/acorn");
const errors_1 = require("./errors");
const convert_1 = require("./convert");
let parserCache;
const PRIVATE = Symbol("ExtendParser#private");
const PRIVATE_PROCESS_NODE = Symbol("ExtendParser#processNode");
function getParser() {
if (parserCache) {
return parserCache;
}
parserCache = class ExtendParser extends (0, acorn_1.getAcorn)().Parser {
constructor(options, code, pos) {
super((() => {
const tokenConvertor = new convert_1.TokenConvertor(options.ctx, code);
const onToken = options.onToken ||
((token) => {
const t = tokenConvertor.convertToken(token);
if (t) {
this[PRIVATE].tokenStore.add(t);
}
});
return {
ecmaVersion: options.ecmaVersion,
sourceType: options.sourceType,
ranges: true,
locations: true,
allowReserved: true,
onToken,
onComment: (block, text, start, end, startLoc, endLoc) => {
const comment = {
type: block ? "Block" : "Line",
value: text,
range: [start, end],
loc: {
start: startLoc,
end: endLoc,
},
};
if (!this[PRIVATE].ctx.comments) {
throw (0, errors_1.throwUnexpectedCommentError)(comment);
}
this[PRIVATE].comments.push(comment);
},
};
})(), code, pos);
this[PRIVATE] = {
code,
ctx: options.ctx,
tokenStore: options.tokenStore,
comments: options.comments,
nodes: options.nodes,
};
}
finishNode(...args) {
const result = super.finishNode(...args);
return this[PRIVATE_PROCESS_NODE](result);
}
finishNodeAt(...args) {
const result = super.finishNodeAt(...args);
return this[PRIVATE_PROCESS_NODE](result);
}
[PRIVATE_PROCESS_NODE](node) {
const { tokenStore, ctx, nodes } = this[PRIVATE];
(0, validate_1.validateNode)(node, tokenStore, ctx);
nodes.push(node);
return node;
}
raise(pos, message) {
const loc = (0, acorn_1.getAcorn)().getLineInfo(this[PRIVATE].code, pos);
const err = new errors_1.ParseError(message, pos, loc.line, loc.column + 1);
throw err;
}
raiseRecoverable(pos, message) {
this.raise(pos, message);
}
unexpected(pos) {
if (pos != null) {
this.raise(pos, "Unexpected token.");
return;
}
const start = this.start;
const end = this.end;
const token = this[PRIVATE].code.slice(start, end);
if (token) {
const message = `Unexpected token '${token}'.`;
this.raise(start, message);
}
else {
if (!this[PRIVATE].nodes.length) {
this.raise(0, "Expected to be an expression, but got empty.");
}
if (this[PRIVATE].tokenStore.tokens.length) {
const last = this[PRIVATE].tokenStore.tokens[this[PRIVATE].tokenStore.tokens.length - 1];
this.raise(last.range[0], `Unexpected token '${last.value}'.`);
}
this.raise(start, "Unexpected token.");
}
}
};
return parserCache;
}
exports.getParser = getParser;
function getAnyTokenErrorParser() {
const parser = class ExtendParser extends getParser() {
constructor(options, code, pos) {
super(Object.assign(Object.assign({}, options), { onToken: (token) => {
return (0, errors_1.throwUnexpectedTokenError)(code.slice(...token.range), token);
} }), code, pos);
}
};
return parser;
}
exports.getAnyTokenErrorParser = getAnyTokenErrorParser;

View File

@@ -0,0 +1,2 @@
import type * as acorn from "acorn";
export declare function getAcorn(): typeof acorn;

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAcorn = void 0;
const module_1 = require("module");
const require_utils_1 = require("./require-utils");
let acornCache;
function getAcorn() {
if (!acornCache) {
acornCache = (0, require_utils_1.loadNewest)([
{
getPkg() {
return (0, require_utils_1.requireFromCwd)("acorn/package.json");
},
get() {
return (0, require_utils_1.requireFromCwd)("acorn");
},
},
{
getPkg() {
return requireFromEspree("acorn/package.json");
},
get() {
return requireFromEspree("acorn");
},
},
{
getPkg() {
return require("acorn/package.json");
},
get() {
return require("acorn");
},
},
]);
}
return acornCache;
}
exports.getAcorn = getAcorn;
function requireFromEspree(module) {
try {
return (0, module_1.createRequire)(getEspreePath())(module);
}
catch (_a) {
}
return null;
}
function getEspreePath() {
return (0, require_utils_1.loadNewest)([
{
getPkg() {
return (0, require_utils_1.requireFromCwd)("espree/package.json");
},
get() {
return (0, require_utils_1.getRequireFromCwd)().resolve("espree");
},
},
{
getPkg() {
return (0, require_utils_1.requireFromLinter)("espree/package.json");
},
get() {
return (0, require_utils_1.getRequireFromLinter)().resolve("espree");
},
},
{
getPkg() {
return require("espree/package.json");
},
get() {
return require.resolve("espree");
},
},
]);
}

View File

@@ -0,0 +1,8 @@
export interface ESPree {
latestEcmaVersion?: number;
version: string;
}
export declare function getEspree(): ESPree;
type NewestKind = "cwd" | "linter" | "self";
export declare function getNewestEspreeKind(): NewestKind;
export {};

View File

@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNewestEspreeKind = exports.getEspree = void 0;
const require_utils_1 = require("./require-utils");
const semver_1 = require("semver");
let espreeCache = null;
function getEspree() {
if (!espreeCache) {
espreeCache = (0, require_utils_1.loadNewest)([
{
getPkg() {
return (0, require_utils_1.requireFromCwd)("espree/package.json");
},
get() {
return (0, require_utils_1.requireFromCwd)("espree");
},
},
{
getPkg() {
return (0, require_utils_1.requireFromLinter)("espree/package.json");
},
get() {
return (0, require_utils_1.requireFromLinter)("espree");
},
},
{
getPkg() {
return require("espree/package.json");
},
get() {
return require("espree");
},
},
]);
}
return espreeCache;
}
exports.getEspree = getEspree;
let kindCache = null;
function getNewestEspreeKind() {
if (kindCache) {
return kindCache;
}
const cwdPkg = (0, require_utils_1.requireFromCwd)("espree/package.json");
const linterPkg = (0, require_utils_1.requireFromLinter)("espree/package.json");
const self = require("espree/package.json");
let target = {
kind: "self",
version: self.version,
};
if (cwdPkg != null && (0, semver_1.lte)(target.version, cwdPkg.version)) {
target = { kind: "cwd", version: cwdPkg.version };
}
if (linterPkg != null && (0, semver_1.lte)(target.version, linterPkg.version)) {
target = { kind: "linter", version: linterPkg.version };
}
return (kindCache = target.kind);
}
exports.getNewestEspreeKind = getNewestEspreeKind;

View File

@@ -0,0 +1,13 @@
/// <reference types="node" />
import type ModuleClass from "module";
export declare function createRequire(filename: string): ReturnType<typeof ModuleClass.createRequire>;
export declare function getRequireFromLinter(): NodeRequire | null;
export declare function getRequireFromCwd(): NodeRequire | null;
export declare function requireFromLinter<T>(module: string): T | null;
export declare function requireFromCwd<T>(module: string): T | null;
export declare function loadNewest<T>(items: {
getPkg: () => {
version: string;
} | null;
get: () => T | null;
}[]): T;

View File

@@ -0,0 +1,80 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadNewest = exports.requireFromCwd = exports.requireFromLinter = exports.getRequireFromCwd = exports.getRequireFromLinter = exports.createRequire = void 0;
const path_1 = __importDefault(require("path"));
const semver_1 = require("semver");
function createRequire(filename) {
const Module = require("module");
const fn = Module.createRequire ||
Module.createRequireFromPath ||
((filename2) => {
const mod = new Module(filename2);
mod.filename = filename2;
mod.paths = Module._nodeModulePaths(path_1.default.dirname(filename2));
mod._compile("module.exports = require;", filename2);
return mod.exports;
});
return fn(filename);
}
exports.createRequire = createRequire;
function isLinterPath(p) {
return (p.includes(`eslint${path_1.default.sep}lib${path_1.default.sep}linter${path_1.default.sep}linter.js`) ||
p.includes(`eslint${path_1.default.sep}lib${path_1.default.sep}linter.js`));
}
function getRequireFromLinter() {
const linterPath = Object.keys(require.cache).find(isLinterPath);
if (linterPath) {
try {
return createRequire(linterPath);
}
catch (_a) {
}
}
return null;
}
exports.getRequireFromLinter = getRequireFromLinter;
function getRequireFromCwd() {
try {
const cwd = process.cwd();
const relativeTo = path_1.default.join(cwd, "__placeholder__.js");
return createRequire(relativeTo);
}
catch (_a) {
}
return null;
}
exports.getRequireFromCwd = getRequireFromCwd;
function requireFromLinter(module) {
var _a;
try {
return (_a = getRequireFromLinter()) === null || _a === void 0 ? void 0 : _a(module);
}
catch (_b) {
}
return null;
}
exports.requireFromLinter = requireFromLinter;
function requireFromCwd(module) {
var _a;
try {
return (_a = getRequireFromCwd()) === null || _a === void 0 ? void 0 : _a(module);
}
catch (_b) {
}
return null;
}
exports.requireFromCwd = requireFromCwd;
function loadNewest(items) {
let target = null;
for (const item of items) {
const pkg = item.getPkg();
if (pkg != null && (!target || (0, semver_1.lte)(target.version, pkg.version))) {
target = { version: pkg.version, get: item.get };
}
}
return target.get();
}
exports.loadNewest = loadNewest;

View File

@@ -0,0 +1,9 @@
import type { SourceCode } from "eslint";
import type { JSONProgram } from "./ast";
export declare function parseForESLint(code: string, options?: any): {
ast: JSONProgram;
visitorKeys: SourceCode.VisitorKeys;
services: {
isJSON: boolean;
};
};

View File

@@ -0,0 +1,201 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseForESLint = void 0;
const espree_1 = require("./modules/espree");
const visitor_keys_1 = require("./visitor-keys");
const convert_1 = require("./convert");
const token_store_1 = require("./token-store");
const semver_1 = require("semver");
const extend_parser_1 = require("./extend-parser");
const DEFAULT_ECMA_VERSION = "latest";
function parseForESLint(code, options) {
var _a, _b, _c, _d;
const parserOptions = Object.assign({ filePath: "<input>", ecmaVersion: DEFAULT_ECMA_VERSION }, options || {}, {
loc: true,
range: true,
raw: true,
tokens: true,
comment: true,
eslintVisitorKeys: true,
eslintScopeManager: true,
});
parserOptions.ecmaVersion = normalizeEcmaVersion(parserOptions.ecmaVersion);
const ctx = getJSONSyntaxContext(parserOptions.jsonSyntax);
const tokens = [];
const comments = [];
const tokenStore = new token_store_1.TokenStore(tokens);
const nodes = [];
parserOptions.ctx = ctx;
parserOptions.tokenStore = tokenStore;
parserOptions.comments = comments;
parserOptions.nodes = nodes;
const baseAst = (0, extend_parser_1.getParser)().parseExpressionAt(code, 0, parserOptions);
for (const node of nodes) {
node.type = `JSON${node.type}`;
}
const ast = (0, convert_1.convertProgramNode)(baseAst, tokenStore, ctx, code);
let lastIndex = Math.max(baseAst.range[1], (_b = (_a = tokens[tokens.length - 1]) === null || _a === void 0 ? void 0 : _a.range[1]) !== null && _b !== void 0 ? _b : 0, (_d = (_c = comments[comments.length - 1]) === null || _c === void 0 ? void 0 : _c.range[1]) !== null && _d !== void 0 ? _d : 0);
let lastChar = code[lastIndex];
while (lastChar === "\n" ||
lastChar === "\r" ||
lastChar === " " ||
lastChar === "\t") {
lastIndex++;
lastChar = code[lastIndex];
}
if (lastIndex < code.length) {
(0, extend_parser_1.getAnyTokenErrorParser)().parseExpressionAt(code, lastIndex, parserOptions);
}
ast.tokens = tokens;
ast.comments = comments;
return {
ast,
visitorKeys: (0, visitor_keys_1.getVisitorKeys)(),
services: {
isJSON: true,
},
};
}
exports.parseForESLint = parseForESLint;
function getJSONSyntaxContext(str) {
const upperCase = str === null || str === void 0 ? void 0 : str.toUpperCase();
if (upperCase === "JSON") {
return {
trailingCommas: false,
comments: false,
plusSigns: false,
spacedSigns: false,
leadingOrTrailingDecimalPoints: false,
infinities: false,
nans: false,
numericSeparators: false,
binaryNumericLiterals: false,
octalNumericLiterals: false,
legacyOctalNumericLiterals: false,
invalidJsonNumbers: false,
multilineStrings: false,
unquoteProperties: false,
singleQuotes: false,
numberProperties: false,
undefinedKeywords: false,
sparseArrays: false,
regExpLiterals: false,
templateLiterals: false,
bigintLiterals: false,
unicodeCodepointEscapes: false,
escapeSequenceInIdentifier: false,
parentheses: false,
staticExpressions: false,
};
}
if (upperCase === "JSONC") {
return {
trailingCommas: true,
comments: true,
plusSigns: false,
spacedSigns: false,
leadingOrTrailingDecimalPoints: false,
infinities: false,
nans: false,
numericSeparators: false,
binaryNumericLiterals: false,
octalNumericLiterals: false,
legacyOctalNumericLiterals: false,
invalidJsonNumbers: false,
multilineStrings: false,
unquoteProperties: false,
singleQuotes: false,
numberProperties: false,
undefinedKeywords: false,
sparseArrays: false,
regExpLiterals: false,
templateLiterals: false,
bigintLiterals: false,
unicodeCodepointEscapes: false,
escapeSequenceInIdentifier: false,
parentheses: false,
staticExpressions: false,
};
}
if (upperCase === "JSON5") {
return {
trailingCommas: true,
comments: true,
plusSigns: true,
spacedSigns: true,
leadingOrTrailingDecimalPoints: true,
infinities: true,
nans: true,
numericSeparators: false,
binaryNumericLiterals: false,
octalNumericLiterals: false,
legacyOctalNumericLiterals: false,
invalidJsonNumbers: true,
multilineStrings: true,
unquoteProperties: true,
singleQuotes: true,
numberProperties: false,
undefinedKeywords: false,
sparseArrays: false,
regExpLiterals: false,
templateLiterals: false,
bigintLiterals: false,
unicodeCodepointEscapes: false,
escapeSequenceInIdentifier: false,
parentheses: false,
staticExpressions: false,
};
}
return {
trailingCommas: true,
comments: true,
plusSigns: true,
spacedSigns: true,
leadingOrTrailingDecimalPoints: true,
infinities: true,
nans: true,
numericSeparators: true,
binaryNumericLiterals: true,
octalNumericLiterals: true,
legacyOctalNumericLiterals: true,
invalidJsonNumbers: true,
multilineStrings: true,
unquoteProperties: true,
singleQuotes: true,
numberProperties: true,
undefinedKeywords: true,
sparseArrays: true,
regExpLiterals: true,
templateLiterals: true,
bigintLiterals: true,
unicodeCodepointEscapes: true,
escapeSequenceInIdentifier: true,
parentheses: true,
staticExpressions: true,
};
}
function normalizeEcmaVersion(version) {
const espree = (0, espree_1.getEspree)();
const latestEcmaVersion = getLatestEcmaVersion(espree);
if (version == null || version === "latest") {
return latestEcmaVersion;
}
return Math.min(getEcmaVersionYear(version), latestEcmaVersion);
}
function getLatestEcmaVersion(espree) {
if (espree.latestEcmaVersion == null) {
for (const { v, latest } of [
{ v: "6.1.0", latest: 2020 },
{ v: "4.0.0", latest: 2019 },
]) {
if ((0, semver_1.lte)(v, espree.version)) {
return latest;
}
}
return 2018;
}
return getEcmaVersionYear(espree.latestEcmaVersion);
}
function getEcmaVersionYear(version) {
return version > 5 && version < 2015 ? version + 2009 : version;
}

View File

@@ -0,0 +1,27 @@
export type JSONSyntaxContext = {
trailingCommas: boolean;
comments: boolean;
plusSigns: boolean;
spacedSigns: boolean;
leadingOrTrailingDecimalPoints: boolean;
infinities: boolean;
nans: boolean;
numericSeparators: boolean;
binaryNumericLiterals: boolean;
octalNumericLiterals: boolean;
legacyOctalNumericLiterals: boolean;
invalidJsonNumbers: boolean;
multilineStrings: boolean;
unquoteProperties: boolean;
singleQuotes: boolean;
numberProperties: boolean;
undefinedKeywords: boolean;
sparseArrays: boolean;
regExpLiterals: boolean;
templateLiterals: boolean;
bigintLiterals: boolean;
unicodeCodepointEscapes: boolean;
escapeSequenceInIdentifier: boolean;
parentheses: boolean;
staticExpressions: boolean;
};

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,21 @@
import type { AST } from "eslint";
import type { SourceLocation } from "./ast";
export type MaybeNodeOrToken = {
range?: [number, number];
loc?: SourceLocation | null;
};
export declare class TokenStore {
readonly tokens: AST.Token[];
constructor(tokens: AST.Token[]);
add(token: AST.Token): void;
private findIndexByOffset;
findTokenByOffset(offset: number): AST.Token | null;
getFirstToken(nodeOrToken: MaybeNodeOrToken): AST.Token;
getLastToken(nodeOrToken: MaybeNodeOrToken): AST.Token;
getTokenBefore(nodeOrToken: MaybeNodeOrToken, filter?: (token: AST.Token) => boolean): AST.Token | null;
getTokenAfter(nodeOrToken: MaybeNodeOrToken, filter?: (token: AST.Token) => boolean): AST.Token | null;
}
export declare function isComma(token: AST.Token): token is AST.Token & {
type: "Punctuator";
value: ",";
};

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isComma = exports.TokenStore = void 0;
class TokenStore {
constructor(tokens) {
this.tokens = tokens;
}
add(token) {
this.tokens.push(token);
}
findIndexByOffset(offset) {
return this.tokens.findIndex((token) => token.range[0] <= offset && offset < token.range[1]);
}
findTokenByOffset(offset) {
return this.tokens[this.findIndexByOffset(offset)];
}
getFirstToken(nodeOrToken) {
return this.findTokenByOffset(nodeOrToken.range[0]);
}
getLastToken(nodeOrToken) {
return this.findTokenByOffset(nodeOrToken.range[1] - 1);
}
getTokenBefore(nodeOrToken, filter) {
const tokenIndex = this.findIndexByOffset(nodeOrToken.range[0]);
for (let index = tokenIndex - 1; index >= 0; index--) {
const token = this.tokens[index];
if (!filter || filter(token)) {
return token;
}
}
return null;
}
getTokenAfter(nodeOrToken, filter) {
const tokenIndex = this.findIndexByOffset(nodeOrToken.range[0]);
for (let index = tokenIndex + 1; index < this.tokens.length; index++) {
const token = this.tokens[index];
if (!filter || filter(token)) {
return token;
}
}
return null;
}
}
exports.TokenStore = TokenStore;
function isComma(token) {
return token.type === "Punctuator" && token.value === ",";
}
exports.isComma = isComma;

View File

@@ -0,0 +1,11 @@
import type { VisitorKeys } from "eslint-visitor-keys";
import type { JSONNode } from "./ast";
export declare function getFallbackKeys(node: JSONNode): string[];
export declare function getKeys(node: JSONNode, visitorKeys?: VisitorKeys): string[];
export declare function getNodes(node: any, key: string): IterableIterator<JSONNode>;
export interface Visitor<N> {
visitorKeys?: VisitorKeys;
enterNode(node: N, parent: N | null): void;
leaveNode(node: N, parent: N | null): void;
}
export declare function traverseNodes(node: JSONNode, visitor: Visitor<JSONNode>): void;

View File

@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.traverseNodes = exports.getNodes = exports.getKeys = exports.getFallbackKeys = void 0;
const visitor_keys_1 = require("./visitor-keys");
function fallbackKeysFilter(key) {
let value = null;
return (key !== "comments" &&
key !== "leadingComments" &&
key !== "loc" &&
key !== "parent" &&
key !== "range" &&
key !== "tokens" &&
key !== "trailingComments" &&
(value = this[key]) !== null &&
typeof value === "object" &&
(typeof value.type === "string" || Array.isArray(value)));
}
function getFallbackKeys(node) {
return Object.keys(node).filter(fallbackKeysFilter, node);
}
exports.getFallbackKeys = getFallbackKeys;
function getKeys(node, visitorKeys) {
const keys = (visitorKeys || (0, visitor_keys_1.getVisitorKeys)())[node.type] || getFallbackKeys(node);
return keys.filter((key) => !getNodes(node, key).next().done);
}
exports.getKeys = getKeys;
function* getNodes(node, key) {
const child = node[key];
if (Array.isArray(child)) {
for (const c of child) {
if (isNode(c)) {
yield c;
}
}
}
else if (isNode(child)) {
yield child;
}
}
exports.getNodes = getNodes;
function isNode(x) {
return x !== null && typeof x === "object" && typeof x.type === "string";
}
function traverse(node, parent, visitor) {
visitor.enterNode(node, parent);
const keys = getKeys(node, visitor.visitorKeys);
for (const key of keys) {
for (const child of getNodes(node, key)) {
traverse(child, node, visitor);
}
}
visitor.leaveNode(node, parent);
}
function traverseNodes(node, visitor) {
traverse(node, null, visitor);
}
exports.traverseNodes = traverseNodes;

View File

@@ -0,0 +1,5 @@
import type { Literal, RegExpLiteral } from "estree";
import type { JSONLiteral, JSONRegExpLiteral } from "./ast";
export declare function isRegExpLiteral(node: JSONLiteral): node is JSONRegExpLiteral;
export declare function isRegExpLiteral(node: Literal): node is RegExpLiteral;
export declare function isRegExpLiteral(node: JSONLiteral | Literal): node is JSONRegExpLiteral | RegExpLiteral;

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isRegExpLiteral = void 0;
function isRegExpLiteral(node) {
return (Boolean(node.regex) ||
node.raw.startsWith("/"));
}
exports.isRegExpLiteral = isRegExpLiteral;

View File

@@ -0,0 +1,8 @@
import type { Node, Identifier } from "estree";
import type { TokenStore } from "./token-store";
import type { JSONIdentifier } from "./ast";
import type { JSONSyntaxContext } from "./syntax-context";
export declare function validateNode(node: Node, tokens: TokenStore, ctx: JSONSyntaxContext): void;
export declare function isStaticValueIdentifier<I extends Identifier | JSONIdentifier>(node: I, ctx: JSONSyntaxContext): node is I & {
name: "NaN" | "Infinity" | "undefined";
};

View File

@@ -0,0 +1,408 @@
"use strict";
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 lineBreakPattern = /\r\n|[\n\r\u2028\u2029]/u;
const octalNumericLiteralPattern = /^0o/iu;
const legacyOctalNumericLiteralPattern = /^0\d/u;
const binaryNumericLiteralPattern = /^0b/iu;
const unicodeCodepointEscapePattern = /\\u\{[\dA-Fa-f]+\}/uy;
function hasUnicodeCodepointEscapes(code) {
let escaped = false;
for (let index = 0; index < code.length - 4; index++) {
if (escaped) {
escaped = false;
continue;
}
const char = code[index];
if (char === "\\") {
unicodeCodepointEscapePattern.lastIndex = index;
if (unicodeCodepointEscapePattern.test(code)) {
return true;
}
escaped = true;
}
}
return false;
}
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;
}
if (node.type === "BinaryExpression") {
validateBinaryExpressionNode(node, tokens, ctx);
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 (hasUnicodeCodepointEscapes(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 (hasUnicodeCodepointEscapes(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 validateBinaryExpressionNode(node, tokens, ctx) {
if (node.type !== "BinaryExpression") {
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens);
}
if (!ctx.staticExpressions) {
throw (0, errors_1.throwUnexpectedNodeError)(node, tokens);
}
const { operator, left, right } = node;
if (operator !== "+" &&
operator !== "-" &&
operator !== "*" &&
operator !== "/" &&
operator !== "%" &&
operator !== "**") {
throw throwOperatorError();
}
if (left.type === "PrivateIdentifier") {
throw (0, errors_1.throwUnexpectedNodeError)(left, tokens);
}
validateExpr(left, throwOperatorError);
validateExpr(right, () => (0, errors_1.throwUnexpectedNodeError)(right, tokens));
function validateExpr(expr, throwError) {
if (expr.type === "Literal") {
if (typeof expr.value !== "number") {
throw throwError();
}
}
else if (expr.type !== "BinaryExpression" &&
expr.type !== "UnaryExpression") {
throw throwError();
}
setParent(expr, node);
}
function throwOperatorError() {
throw (0, errors_1.throwUnexpectedTokenError)(operator, tokens.getTokenAfter(tokens.getFirstToken(node), (t) => t.value === operator) || node);
}
}
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;
}

View File

@@ -0,0 +1,2 @@
import type { SourceCode } from "eslint";
export declare function getVisitorKeys(): SourceCode.VisitorKeys;

View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getVisitorKeys = void 0;
const require_utils_1 = require("./modules/require-utils");
const jsonKeys = {
Program: ["body"],
JSONExpressionStatement: ["expression"],
JSONArrayExpression: ["elements"],
JSONObjectExpression: ["properties"],
JSONProperty: ["key", "value"],
JSONIdentifier: [],
JSONLiteral: [],
JSONUnaryExpression: ["argument"],
JSONTemplateLiteral: ["quasis", "expressions"],
JSONTemplateElement: [],
JSONBinaryExpression: ["left", "right"],
};
let cache = null;
function getVisitorKeys() {
if (!cache) {
const vk = (0, require_utils_1.loadNewest)([
{
getPkg() {
return (0, require_utils_1.requireFromCwd)("eslint-visitor-keys/package.json");
},
get() {
return (0, require_utils_1.requireFromCwd)("eslint-visitor-keys");
},
},
{
getPkg() {
return (0, require_utils_1.requireFromLinter)("eslint-visitor-keys/package.json");
},
get() {
return (0, require_utils_1.requireFromLinter)("eslint-visitor-keys");
},
},
{
getPkg() {
return require("eslint-visitor-keys/package.json");
},
get() {
return require("eslint-visitor-keys");
},
},
]);
cache = vk.unionWith(jsonKeys);
}
return cache;
}
exports.getVisitorKeys = getVisitorKeys;

View File

@@ -0,0 +1,15 @@
import type { AST } from "jsonc-eslint-parser";
export type JSONSyntax = "JSON" | "JSONC" | "JSON5" | null;
export interface JSONParserOptions {
jsonSyntax?: JSONSyntax;
}
export type RuleFunction<Node extends AST.JSONNode = any> = (node: Node) => void;
export type BuiltInRuleListeners = {
[Node in AST.JSONNode as Node["type"]]?: RuleFunction<Node>;
};
export type BuiltInRuleListenerExits = {
[Node in AST.JSONNode as `${Node["type"]}:exit`]?: RuleFunction<Node>;
};
export interface RuleListener extends BuiltInRuleListeners, BuiltInRuleListenerExits {
[key: string]: RuleFunction | undefined;
}

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,19 @@
import type { JSONNode, JSONExpression, JSONNumberIdentifier, JSONIdentifier, JSONObjectExpression, JSONArrayExpression, JSONUnaryExpression, JSONNumberLiteral, JSONExpressionStatement, JSONProgram, JSONUndefinedIdentifier, JSONTemplateLiteral, JSONTemplateElement, JSONStringLiteral, JSONKeywordLiteral, JSONRegExpLiteral, JSONBigIntLiteral, JSONLiteral, JSONBinaryExpression } from "../parser/ast";
export declare function isExpression<N extends JSONNode>(node: N): node is N & JSONExpression;
export declare function isNumberIdentifier(node: JSONIdentifier): node is JSONNumberIdentifier;
export declare function isUndefinedIdentifier(node: JSONIdentifier): node is JSONUndefinedIdentifier;
export type JSONValue = string | number | boolean | null | undefined | JSONObjectValue | JSONValue[] | RegExp | bigint;
export type JSONObjectValue = {
[key: string]: JSONValue;
};
export declare function getStaticJSONValue(node: JSONUnaryExpression | JSONNumberIdentifier | JSONNumberLiteral | JSONBinaryExpression): number;
export declare function getStaticJSONValue(node: JSONUndefinedIdentifier): undefined;
export declare function getStaticJSONValue(node: JSONTemplateLiteral | JSONTemplateElement | JSONStringLiteral): string;
export declare function getStaticJSONValue(node: JSONKeywordLiteral): boolean | null;
export declare function getStaticJSONValue(node: JSONRegExpLiteral): RegExp;
export declare function getStaticJSONValue(node: JSONBigIntLiteral): bigint;
export declare function getStaticJSONValue(node: JSONLiteral): string | number | boolean | RegExp | bigint | null;
export declare function getStaticJSONValue(node: Exclude<JSONExpression, JSONObjectExpression | JSONArrayExpression>): Exclude<JSONValue, JSONObjectValue | JSONValue[]>;
export declare function getStaticJSONValue(node: JSONObjectExpression): JSONObjectValue;
export declare function getStaticJSONValue(node: JSONArrayExpression): JSONValue[];
export declare function getStaticJSONValue(node: JSONExpression | JSONExpressionStatement | JSONProgram | JSONNode): JSONValue;

View File

@@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStaticJSONValue = exports.isUndefinedIdentifier = exports.isNumberIdentifier = exports.isExpression = void 0;
function isExpression(node) {
if (node.type === "JSONIdentifier" || node.type === "JSONLiteral") {
const parent = node.parent;
if (parent.type === "JSONProperty" && parent.key === node) {
return false;
}
return true;
}
if (node.type === "JSONObjectExpression" ||
node.type === "JSONArrayExpression" ||
node.type === "JSONUnaryExpression" ||
node.type === "JSONTemplateLiteral" ||
node.type === "JSONBinaryExpression") {
return true;
}
return false;
}
exports.isExpression = isExpression;
function isNumberIdentifier(node) {
return (isExpression(node) && (node.name === "Infinity" || node.name === "NaN"));
}
exports.isNumberIdentifier = isNumberIdentifier;
function isUndefinedIdentifier(node) {
return isExpression(node) && node.name === "undefined";
}
exports.isUndefinedIdentifier = isUndefinedIdentifier;
const resolver = {
Program(node) {
if (node.body.length !== 1 ||
node.body[0].type !== "JSONExpressionStatement") {
throw new Error("Illegal argument");
}
return getStaticJSONValue(node.body[0]);
},
JSONExpressionStatement(node) {
return getStaticJSONValue(node.expression);
},
JSONObjectExpression(node) {
const object = {};
for (const prop of node.properties) {
Object.assign(object, getStaticJSONValue(prop));
}
return object;
},
JSONProperty(node) {
const keyName = node.key.type === "JSONLiteral" ? `${node.key.value}` : node.key.name;
return {
[keyName]: getStaticJSONValue(node.value),
};
},
JSONArrayExpression(node) {
const array = [];
for (let index = 0; index < node.elements.length; index++) {
const element = node.elements[index];
if (element) {
array[index] = getStaticJSONValue(element);
}
}
return array;
},
JSONLiteral(node) {
if (node.regex) {
try {
return new RegExp(node.regex.pattern, node.regex.flags);
}
catch (_a) {
return `/${node.regex.pattern}/${node.regex.flags}`;
}
}
if (node.bigint != null) {
try {
return BigInt(node.bigint);
}
catch (_b) {
return `${node.bigint}`;
}
}
return node.value;
},
JSONUnaryExpression(node) {
const value = getStaticJSONValue(node.argument);
return node.operator === "-" ? -value : value;
},
JSONBinaryExpression(node) {
const left = getStaticJSONValue(node.left);
const right = getStaticJSONValue(node.right);
return node.operator === "+"
? left + right
: node.operator === "-"
? left - right
: node.operator === "*"
? left * right
: node.operator === "/"
? left / right
: node.operator === "%"
? left % right
: node.operator === "**"
? Math.pow(left, right)
: (() => {
throw new Error(`Unknown operator: ${node.operator}`);
})();
},
JSONIdentifier(node) {
if (node.name === "Infinity") {
return Infinity;
}
if (node.name === "NaN") {
return NaN;
}
if (node.name === "undefined") {
return undefined;
}
throw new Error("Illegal argument");
},
JSONTemplateLiteral(node) {
return getStaticJSONValue(node.quasis[0]);
},
JSONTemplateElement(node) {
return node.value.cooked;
},
};
function getStaticJSONValue(node) {
return resolver[node.type](node);
}
exports.getStaticJSONValue = getStaticJSONValue;