routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
+822
@@ -0,0 +1,822 @@
|
||||
'use strict';
|
||||
|
||||
const eslint = require('eslint');
|
||||
const jsoncEslintParser = require('jsonc-eslint-parser');
|
||||
const esquery = require('esquery');
|
||||
|
||||
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
||||
|
||||
const esquery__default = /*#__PURE__*/_interopDefaultCompat(esquery);
|
||||
|
||||
function newProxyWithProperties(target, properties) {
|
||||
return newProxyWithGet(target, (_target, prop) => {
|
||||
if (prop in properties) {
|
||||
return properties[prop];
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
});
|
||||
}
|
||||
function newProxyWithGet(target, get) {
|
||||
return new Proxy(
|
||||
Object.isFrozen(target) ? { __proto__: target } : target,
|
||||
{
|
||||
get(t, p, r) {
|
||||
return proxyReflectValue(get(t, p, r), t, r);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
function proxyReflectValue(value, target, receiver) {
|
||||
if (typeof value === "function") {
|
||||
return function(...args) {
|
||||
const self = this;
|
||||
return value.apply(self === receiver ? target : self, args);
|
||||
};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const MOMOA_NODES = /* @__PURE__ */ new Set([
|
||||
"Array",
|
||||
"Boolean",
|
||||
"Document",
|
||||
"Element",
|
||||
"Identifier",
|
||||
"Infinity",
|
||||
"Member",
|
||||
"NaN",
|
||||
"Null",
|
||||
"Number",
|
||||
"Object",
|
||||
"String"
|
||||
]);
|
||||
function isJSONSourceCode(sourceCode) {
|
||||
var _a, _b, _c;
|
||||
return ((_a = sourceCode.ast) == null ? void 0 : _a.type) === "Document" && ((_c = (_b = sourceCode.ast.loc) == null ? void 0 : _b.start) == null ? void 0 : _c.column) === 1 && sourceCode.ast.body && isMomoaNode(sourceCode.ast.body) && typeof sourceCode.getParent === "function";
|
||||
}
|
||||
function isMomoaNode(node) {
|
||||
return MOMOA_NODES.has(node.type);
|
||||
}
|
||||
|
||||
function convertSourceLocationFromJsonToJsonc(loc) {
|
||||
return {
|
||||
start: convertPositionFromJsonToJsonc(loc.start),
|
||||
end: convertPositionFromJsonToJsonc(loc.end)
|
||||
};
|
||||
}
|
||||
function convertPositionFromJsonToJsonc(position) {
|
||||
return {
|
||||
line: position.line,
|
||||
column: position.column - 1
|
||||
};
|
||||
}
|
||||
function convertSourceLocationFromJsoncToJson(loc) {
|
||||
return {
|
||||
start: convertPositionFromJsoncToJson(loc.start),
|
||||
end: convertPositionFromJsoncToJson(loc.end)
|
||||
};
|
||||
}
|
||||
function convertPositionFromJsoncToJson(position) {
|
||||
return {
|
||||
line: position.line,
|
||||
column: position.column + 1
|
||||
};
|
||||
}
|
||||
|
||||
const TOKEN_CONVERTERS = /* @__PURE__ */ new WeakMap();
|
||||
function getTokenConverter(jsonSourceCode) {
|
||||
const converter = TOKEN_CONVERTERS.get(jsonSourceCode.ast);
|
||||
if (converter) {
|
||||
return converter;
|
||||
}
|
||||
const convertedTokens = /* @__PURE__ */ new Map();
|
||||
const tokenConverters = {
|
||||
BlockComment(token) {
|
||||
return {
|
||||
type: "Block",
|
||||
get value() {
|
||||
return jsonSourceCode.text.slice(
|
||||
token.range[0] + 2,
|
||||
token.range[1] - 2
|
||||
);
|
||||
},
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
},
|
||||
LineComment(token) {
|
||||
return {
|
||||
type: "Line",
|
||||
get value() {
|
||||
return jsonSourceCode.text.slice(
|
||||
token.range[0] + 2,
|
||||
token.range[1]
|
||||
);
|
||||
},
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
},
|
||||
Boolean(token) {
|
||||
return createStandardToken("Keyword", token);
|
||||
},
|
||||
Null(token) {
|
||||
return createStandardToken("Keyword", token);
|
||||
},
|
||||
Identifier(token) {
|
||||
return createStandardToken("Identifier", token);
|
||||
},
|
||||
Infinity(token) {
|
||||
const raw = jsonSourceCode.text.slice(...token.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
return [
|
||||
createPunctuator(raw[0], {
|
||||
range: [token.range[0], token.range[0] + 1],
|
||||
loc: {
|
||||
start: token.loc.start,
|
||||
end: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
}
|
||||
}
|
||||
}),
|
||||
createStandardToken("Identifier", {
|
||||
range: [token.range[0] + 1, token.range[1]],
|
||||
loc: {
|
||||
start: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
},
|
||||
end: token.loc.end
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
return createStandardToken("Identifier", token);
|
||||
},
|
||||
NaN(token) {
|
||||
const raw = jsonSourceCode.text.slice(...token.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
return [
|
||||
createPunctuator(raw[0], {
|
||||
range: [token.range[0], token.range[0] + 1],
|
||||
loc: {
|
||||
start: token.loc.start,
|
||||
end: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
}
|
||||
}
|
||||
}),
|
||||
createStandardToken("Identifier", {
|
||||
range: [token.range[0] + 1, token.range[1]],
|
||||
loc: {
|
||||
start: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
},
|
||||
end: token.loc.end
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
return createStandardToken("Identifier", token);
|
||||
},
|
||||
Number(token) {
|
||||
const raw = jsonSourceCode.text.slice(...token.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
return [
|
||||
createPunctuator(raw[0], {
|
||||
range: [token.range[0], token.range[0] + 1],
|
||||
loc: {
|
||||
start: token.loc.start,
|
||||
end: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
}
|
||||
}
|
||||
}),
|
||||
createStandardToken("Numeric", {
|
||||
range: [token.range[0] + 1, token.range[1]],
|
||||
loc: {
|
||||
start: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
},
|
||||
end: token.loc.end
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
return createStandardToken("Numeric", token);
|
||||
},
|
||||
String(token) {
|
||||
return createStandardToken("String", token);
|
||||
},
|
||||
Colon(token) {
|
||||
return createPunctuator(":", token);
|
||||
},
|
||||
Comma(token) {
|
||||
return createPunctuator(",", token);
|
||||
},
|
||||
LBracket(token) {
|
||||
return createPunctuator("[", token);
|
||||
},
|
||||
LBrace(token) {
|
||||
return createPunctuator("{", token);
|
||||
},
|
||||
RBracket(token) {
|
||||
return createPunctuator("]", token);
|
||||
},
|
||||
RBrace(token) {
|
||||
return createPunctuator("}", token);
|
||||
}
|
||||
};
|
||||
TOKEN_CONVERTERS.set(jsonSourceCode.ast, convertToken);
|
||||
return convertToken;
|
||||
function createStandardToken(type, token) {
|
||||
return {
|
||||
type,
|
||||
get value() {
|
||||
return jsonSourceCode.text.slice(...token.range);
|
||||
},
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
}
|
||||
function createPunctuator(value, token) {
|
||||
return {
|
||||
type: "Punctuator",
|
||||
value,
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
}
|
||||
function convertToken(token) {
|
||||
if (convertedTokens.has(token)) {
|
||||
return convertedTokens.get(token);
|
||||
}
|
||||
const newToken = tokenConverters[token.type](token);
|
||||
convertedTokens.set(token, newToken);
|
||||
return newToken;
|
||||
}
|
||||
}
|
||||
|
||||
const NODE_CONVERTERS = /* @__PURE__ */ new WeakMap();
|
||||
function getNodeConverter(jsonSourceCode) {
|
||||
const converter = NODE_CONVERTERS.get(jsonSourceCode.ast);
|
||||
if (converter) {
|
||||
return converter;
|
||||
}
|
||||
const tokenConverter = getTokenConverter(jsonSourceCode);
|
||||
const convertedNodes = /* @__PURE__ */ new Map();
|
||||
const nodeConverters = {
|
||||
Array(node) {
|
||||
let elements;
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONArrayExpression",
|
||||
get elements() {
|
||||
return elements != null ? elements : elements = node.elements.map((e) => convertNode(e.value));
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Boolean(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: node.value,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Null(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: null,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Number(node) {
|
||||
const raw = jsonSourceCode.text.slice(...node.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
const argumentRange = [node.range[0] + 1, node.range[1]];
|
||||
const rawArgument = jsonSourceCode.text.slice(...argumentRange);
|
||||
const literal = {
|
||||
get parent() {
|
||||
return unaryExpression;
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: Math.abs(node.value),
|
||||
bigint: null,
|
||||
regex: null,
|
||||
raw: rawArgument,
|
||||
range: argumentRange,
|
||||
loc: convertSourceLocationFromJsonToJsonc({
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
},
|
||||
end: node.loc.end
|
||||
})
|
||||
};
|
||||
const unaryExpression = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONUnaryExpression",
|
||||
operator: raw[0],
|
||||
prefix: true,
|
||||
argument: literal,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
return [unaryExpression, literal];
|
||||
}
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: node.value,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
String(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: node.value,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Document(node) {
|
||||
let expression, tokens, comments;
|
||||
const program = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "Program",
|
||||
get body() {
|
||||
return body;
|
||||
},
|
||||
get comments() {
|
||||
return comments != null ? comments : comments = node.tokens.filter(
|
||||
(token) => token.type === "LineComment" || token.type === "BlockComment"
|
||||
).flatMap(tokenConverter);
|
||||
},
|
||||
get tokens() {
|
||||
return tokens != null ? tokens : tokens = node.tokens.filter(
|
||||
(token) => token.type !== "LineComment" && token.type !== "BlockComment"
|
||||
).flatMap(tokenConverter);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
const expr = {
|
||||
parent: program,
|
||||
type: "JSONExpressionStatement",
|
||||
get expression() {
|
||||
return expression != null ? expression : expression = convertNode(node.body);
|
||||
},
|
||||
range: node.body.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.body.loc)
|
||||
};
|
||||
const body = [expr];
|
||||
return [program, expr];
|
||||
},
|
||||
Object(node) {
|
||||
let members;
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONObjectExpression",
|
||||
get properties() {
|
||||
return members != null ? members : members = node.members.map(convertNode);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Member(node) {
|
||||
let keyNode, value;
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONProperty",
|
||||
get key() {
|
||||
return keyNode != null ? keyNode : keyNode = convertNode(node.name);
|
||||
},
|
||||
get value() {
|
||||
return value != null ? value : value = convertNode(node.value);
|
||||
},
|
||||
kind: "init",
|
||||
method: false,
|
||||
shorthand: false,
|
||||
computed: false,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Identifier(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: node.name,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Infinity(node) {
|
||||
const raw = jsonSourceCode.text.slice(...node.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
const argumentRange = [node.range[0] + 1, node.range[1]];
|
||||
const identifier = {
|
||||
get parent() {
|
||||
return unaryExpression;
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "Infinity",
|
||||
range: argumentRange,
|
||||
loc: convertSourceLocationFromJsonToJsonc({
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
},
|
||||
end: node.loc.end
|
||||
})
|
||||
};
|
||||
const unaryExpression = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONUnaryExpression",
|
||||
operator: raw[0],
|
||||
prefix: true,
|
||||
argument: identifier,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
return [unaryExpression, identifier];
|
||||
}
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "Infinity",
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
NaN(node) {
|
||||
const raw = jsonSourceCode.text.slice(...node.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
const argumentRange = [node.range[0] + 1, node.range[1]];
|
||||
const identifier = {
|
||||
get parent() {
|
||||
return unaryExpression;
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "NaN",
|
||||
range: argumentRange,
|
||||
loc: convertSourceLocationFromJsonToJsonc({
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
},
|
||||
end: node.loc.end
|
||||
})
|
||||
};
|
||||
const unaryExpression = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONUnaryExpression",
|
||||
operator: raw[0],
|
||||
prefix: true,
|
||||
argument: identifier,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
return [unaryExpression, identifier];
|
||||
}
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "NaN",
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
}
|
||||
};
|
||||
NODE_CONVERTERS.set(jsonSourceCode.ast, convert);
|
||||
return convert;
|
||||
function convert(node) {
|
||||
if (convertedNodes.has(node)) {
|
||||
return convertedNodes.get(node);
|
||||
}
|
||||
const newNode = nodeConverters[node.type](node);
|
||||
let result;
|
||||
if (Array.isArray(newNode)) {
|
||||
convertedNodes.set(
|
||||
node,
|
||||
result = {
|
||||
node: newNode[0],
|
||||
nodes: newNode
|
||||
}
|
||||
);
|
||||
} else {
|
||||
convertedNodes.set(node, result = { node: newNode });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function getParent(node) {
|
||||
const parent = jsonSourceCode.getParent(node);
|
||||
if (!parent) return null;
|
||||
const parentNode = parent;
|
||||
if (parentNode.type === "Element") {
|
||||
return getParent(parentNode);
|
||||
}
|
||||
const convertedParent = convert(parentNode);
|
||||
if (convertedParent.nodes) {
|
||||
return convertedParent.nodes[convertedParent.nodes.length - 1];
|
||||
}
|
||||
return convertedParent.node;
|
||||
}
|
||||
function convertNode(node) {
|
||||
return convert(node).node;
|
||||
}
|
||||
}
|
||||
|
||||
function convertJsoncSourceCode(jsonSourceCode) {
|
||||
const convert = getNodeConverter(jsonSourceCode);
|
||||
const jsSourceCode = new eslint.SourceCode({
|
||||
text: jsonSourceCode.text,
|
||||
ast: convert(jsonSourceCode.ast).nodes[0],
|
||||
parserServices: { isJSON: true },
|
||||
visitorKeys: jsoncEslintParser.VisitorKeys
|
||||
});
|
||||
const compatSourceCode = newProxyWithGet(
|
||||
jsonSourceCode,
|
||||
(target, prop, receiver) => {
|
||||
const value = proxyReflectValue(
|
||||
Reflect.get(jsSourceCode, prop),
|
||||
jsSourceCode,
|
||||
target
|
||||
);
|
||||
if (value !== void 0) return value;
|
||||
return Reflect.get(jsonSourceCode, prop, receiver);
|
||||
}
|
||||
);
|
||||
return compatSourceCode;
|
||||
}
|
||||
|
||||
const NODE_TYPE_MAP = /* @__PURE__ */ new Map([
|
||||
["Program", ["Document"]],
|
||||
["JSONExpressionStatement", ["Document"]],
|
||||
["JSONLiteral", ["Boolean", "String", "Null", "Number"]],
|
||||
["JSONArrayExpression", ["Array"]],
|
||||
["JSONObjectExpression", ["Object"]],
|
||||
["JSONProperty", ["Member"]],
|
||||
["JSONIdentifier", ["Identifier", "Infinity", "NaN"]],
|
||||
["JSONUnaryExpression", ["Number", "Infinity", "NaN"]]
|
||||
]);
|
||||
const reIsSimpleNodeQuery = /^[a-z]+$/iu;
|
||||
function convertQuery(eslintQuery) {
|
||||
const exit = eslintQuery.endsWith(":exit");
|
||||
const query = exit ? eslintQuery.slice(0, -5) : eslintQuery;
|
||||
const converted = convertRawQuery(query);
|
||||
return converted && (exit ? {
|
||||
query: `${converted.query}:exit`,
|
||||
match: converted.match
|
||||
} : converted);
|
||||
}
|
||||
function convertRawQuery(query) {
|
||||
const queries = query.split(",").map((q) => q.trim());
|
||||
if (queries.every((q) => reIsSimpleNodeQuery.test(q))) {
|
||||
const convertTargetNodes = new Set(queries);
|
||||
const convertedQueries = [];
|
||||
for (const node of queries) {
|
||||
const converted = NODE_TYPE_MAP.get(node);
|
||||
if (converted) {
|
||||
convertedQueries.push(...converted);
|
||||
} else {
|
||||
convertTargetNodes.delete(node);
|
||||
}
|
||||
}
|
||||
return convertedQueries.length ? {
|
||||
query: convertedQueries.join(","),
|
||||
match: (node) => convertTargetNodes.has(node.type)
|
||||
} : null;
|
||||
}
|
||||
if (query === "*") {
|
||||
return {
|
||||
query: "*",
|
||||
match: () => true
|
||||
};
|
||||
}
|
||||
const selector = esquery__default.parse(query);
|
||||
const match = (node) => {
|
||||
let target = node;
|
||||
const ancestors = [];
|
||||
while (target.parent) {
|
||||
ancestors.push(target.parent);
|
||||
target = target.parent;
|
||||
}
|
||||
return esquery__default.matches(node, selector, ancestors, {
|
||||
visitorKeys: jsoncEslintParser.VisitorKeys
|
||||
});
|
||||
};
|
||||
return { query: "*", match };
|
||||
}
|
||||
|
||||
function toCompatRuleListener(ruleListener, jsonSourceCode) {
|
||||
const convert = getNodeConverter(jsonSourceCode);
|
||||
const jsoncNodeVisitors = /* @__PURE__ */ new Map();
|
||||
const queries = /* @__PURE__ */ new Set();
|
||||
for (const [key, fn] of Object.entries(ruleListener)) {
|
||||
if (!fn) continue;
|
||||
queries.add(key);
|
||||
const convertedQuery = convertQuery(key);
|
||||
if (!convertedQuery) continue;
|
||||
const { query, match } = convertedQuery;
|
||||
queries.add(query);
|
||||
let jsoncNodeVisitorList = jsoncNodeVisitors.get(query);
|
||||
if (!jsoncNodeVisitorList) {
|
||||
jsoncNodeVisitorList = [];
|
||||
jsoncNodeVisitors.set(query, jsoncNodeVisitorList);
|
||||
}
|
||||
jsoncNodeVisitorList.push((node) => {
|
||||
if (match(node)) {
|
||||
fn(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
const result = {};
|
||||
for (const query of queries) {
|
||||
result[query] = (node) => {
|
||||
var _a;
|
||||
if (isMomoaNode(node)) {
|
||||
if (node.type !== "Element") {
|
||||
const jsoncNodeVisitorList = jsoncNodeVisitors.get(query);
|
||||
if (!jsoncNodeVisitorList) return;
|
||||
const invoke = query.endsWith(":exit") ? invokeWithReverseConvertedNode : invokeWithConvertedNode;
|
||||
invoke(node, (n) => {
|
||||
jsoncNodeVisitorList.forEach((cb) => cb(n));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
(_a = ruleListener[query]) == null ? void 0 : _a.call(ruleListener, node);
|
||||
}
|
||||
};
|
||||
}
|
||||
return result;
|
||||
function invokeWithConvertedNode(node, cb) {
|
||||
const jsonNodeData = convert(node);
|
||||
if (jsonNodeData.nodes) {
|
||||
for (const n of jsonNodeData.nodes) {
|
||||
cb(n);
|
||||
}
|
||||
} else {
|
||||
cb(jsonNodeData.node);
|
||||
}
|
||||
}
|
||||
function invokeWithReverseConvertedNode(node, cb) {
|
||||
const jsonNodeData = convert(node);
|
||||
if (jsonNodeData.nodes) {
|
||||
for (let index = jsonNodeData.nodes.length - 1; index >= 0; index--) {
|
||||
const n = jsonNodeData.nodes[index];
|
||||
cb(n);
|
||||
}
|
||||
} else {
|
||||
cb(jsonNodeData.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CONVERTED$2 = /* @__PURE__ */ new WeakMap();
|
||||
function toCompatCreate(create) {
|
||||
if (CONVERTED$2.has(create)) {
|
||||
return CONVERTED$2.get(create);
|
||||
}
|
||||
const result = (context, ...args) => {
|
||||
const originalSourceCode = context.sourceCode;
|
||||
if (!originalSourceCode || !isJSONSourceCode(originalSourceCode)) {
|
||||
return create(context, ...args);
|
||||
}
|
||||
let sourceCode;
|
||||
const compatContext = newProxyWithProperties(context, {
|
||||
get sourceCode() {
|
||||
return sourceCode != null ? sourceCode : sourceCode = convertJsoncSourceCode(originalSourceCode);
|
||||
},
|
||||
report(descriptor) {
|
||||
const momoaDescriptor = {
|
||||
...descriptor
|
||||
};
|
||||
if ("loc" in momoaDescriptor && momoaDescriptor.loc) {
|
||||
if ("line" in momoaDescriptor.loc) {
|
||||
momoaDescriptor.loc = convertPositionFromJsoncToJson(
|
||||
momoaDescriptor.loc
|
||||
);
|
||||
} else {
|
||||
momoaDescriptor.loc = convertSourceLocationFromJsoncToJson(
|
||||
momoaDescriptor.loc
|
||||
);
|
||||
}
|
||||
}
|
||||
if ("node" in momoaDescriptor && momoaDescriptor.node) {
|
||||
momoaDescriptor.node = {
|
||||
...momoaDescriptor.node,
|
||||
loc: convertSourceLocationFromJsoncToJson(
|
||||
momoaDescriptor.node.loc
|
||||
)
|
||||
};
|
||||
}
|
||||
context.report(momoaDescriptor);
|
||||
}
|
||||
});
|
||||
return toCompatRuleListener(
|
||||
create(compatContext, ...args),
|
||||
originalSourceCode
|
||||
);
|
||||
};
|
||||
CONVERTED$2.set(create, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
const CONVERTED$1 = /* @__PURE__ */ new WeakMap();
|
||||
function toCompatRule(rule) {
|
||||
if (CONVERTED$1.has(rule)) {
|
||||
return CONVERTED$1.get(rule);
|
||||
}
|
||||
const result = {
|
||||
...rule,
|
||||
create: toCompatCreate(rule.create)
|
||||
};
|
||||
CONVERTED$1.set(rule, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
const CONVERTED = /* @__PURE__ */ new WeakMap();
|
||||
function toCompatPlugin(plugin) {
|
||||
if (!plugin.rules) {
|
||||
return plugin;
|
||||
}
|
||||
if (CONVERTED.has(plugin)) {
|
||||
return CONVERTED.get(plugin);
|
||||
}
|
||||
const rules = newProxyWithGet(plugin.rules, (target, prop) => {
|
||||
const rule = Reflect.get(target, prop);
|
||||
return rule && toCompatRule(rule);
|
||||
});
|
||||
const result = newProxyWithProperties(plugin, {
|
||||
rules
|
||||
});
|
||||
CONVERTED.set(plugin, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.toCompatCreate = toCompatCreate;
|
||||
exports.toCompatPlugin = toCompatPlugin;
|
||||
exports.toCompatRule = toCompatRule;
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { Rule } from 'eslint';
|
||||
|
||||
type LazyCreate = (context: any, ...args: any[]) => any;
|
||||
/**
|
||||
* This is a helper function that converts the given create function into `@eslint/json` compatible create function.
|
||||
*/
|
||||
declare function toCompatCreate<F extends LazyCreate>(create: F): F;
|
||||
|
||||
type LazyRuleModule = {
|
||||
create: LazyCreate;
|
||||
meta?: Rule.RuleMetaData;
|
||||
};
|
||||
/**
|
||||
* This is a helper function that converts the given rule object into `@eslint/json` compatible rule.
|
||||
*/
|
||||
declare function toCompatRule<R extends LazyRuleModule>(rule: R): R;
|
||||
|
||||
type LazyPlugin = {
|
||||
rules?: Record<string, LazyRuleModule> | undefined;
|
||||
};
|
||||
/**
|
||||
* This is a helper function that converts the given rule object into `@eslint/json` compatible rule.
|
||||
*/
|
||||
declare function toCompatPlugin<P extends LazyPlugin>(plugin: P): P;
|
||||
|
||||
export { toCompatCreate, toCompatPlugin, toCompatRule };
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { Rule } from 'eslint';
|
||||
|
||||
type LazyCreate = (context: any, ...args: any[]) => any;
|
||||
/**
|
||||
* This is a helper function that converts the given create function into `@eslint/json` compatible create function.
|
||||
*/
|
||||
declare function toCompatCreate<F extends LazyCreate>(create: F): F;
|
||||
|
||||
type LazyRuleModule = {
|
||||
create: LazyCreate;
|
||||
meta?: Rule.RuleMetaData;
|
||||
};
|
||||
/**
|
||||
* This is a helper function that converts the given rule object into `@eslint/json` compatible rule.
|
||||
*/
|
||||
declare function toCompatRule<R extends LazyRuleModule>(rule: R): R;
|
||||
|
||||
type LazyPlugin = {
|
||||
rules?: Record<string, LazyRuleModule> | undefined;
|
||||
};
|
||||
/**
|
||||
* This is a helper function that converts the given rule object into `@eslint/json` compatible rule.
|
||||
*/
|
||||
declare function toCompatPlugin<P extends LazyPlugin>(plugin: P): P;
|
||||
|
||||
export { toCompatCreate, toCompatPlugin, toCompatRule };
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { Rule } from 'eslint';
|
||||
|
||||
type LazyCreate = (context: any, ...args: any[]) => any;
|
||||
/**
|
||||
* This is a helper function that converts the given create function into `@eslint/json` compatible create function.
|
||||
*/
|
||||
declare function toCompatCreate<F extends LazyCreate>(create: F): F;
|
||||
|
||||
type LazyRuleModule = {
|
||||
create: LazyCreate;
|
||||
meta?: Rule.RuleMetaData;
|
||||
};
|
||||
/**
|
||||
* This is a helper function that converts the given rule object into `@eslint/json` compatible rule.
|
||||
*/
|
||||
declare function toCompatRule<R extends LazyRuleModule>(rule: R): R;
|
||||
|
||||
type LazyPlugin = {
|
||||
rules?: Record<string, LazyRuleModule> | undefined;
|
||||
};
|
||||
/**
|
||||
* This is a helper function that converts the given rule object into `@eslint/json` compatible rule.
|
||||
*/
|
||||
declare function toCompatPlugin<P extends LazyPlugin>(plugin: P): P;
|
||||
|
||||
export { toCompatCreate, toCompatPlugin, toCompatRule };
|
||||
+814
@@ -0,0 +1,814 @@
|
||||
import { SourceCode } from 'eslint';
|
||||
import { VisitorKeys } from 'jsonc-eslint-parser';
|
||||
import esquery from 'esquery';
|
||||
|
||||
function newProxyWithProperties(target, properties) {
|
||||
return newProxyWithGet(target, (_target, prop) => {
|
||||
if (prop in properties) {
|
||||
return properties[prop];
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
});
|
||||
}
|
||||
function newProxyWithGet(target, get) {
|
||||
return new Proxy(
|
||||
Object.isFrozen(target) ? { __proto__: target } : target,
|
||||
{
|
||||
get(t, p, r) {
|
||||
return proxyReflectValue(get(t, p, r), t, r);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
function proxyReflectValue(value, target, receiver) {
|
||||
if (typeof value === "function") {
|
||||
return function(...args) {
|
||||
const self = this;
|
||||
return value.apply(self === receiver ? target : self, args);
|
||||
};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const MOMOA_NODES = /* @__PURE__ */ new Set([
|
||||
"Array",
|
||||
"Boolean",
|
||||
"Document",
|
||||
"Element",
|
||||
"Identifier",
|
||||
"Infinity",
|
||||
"Member",
|
||||
"NaN",
|
||||
"Null",
|
||||
"Number",
|
||||
"Object",
|
||||
"String"
|
||||
]);
|
||||
function isJSONSourceCode(sourceCode) {
|
||||
var _a, _b, _c;
|
||||
return ((_a = sourceCode.ast) == null ? void 0 : _a.type) === "Document" && ((_c = (_b = sourceCode.ast.loc) == null ? void 0 : _b.start) == null ? void 0 : _c.column) === 1 && sourceCode.ast.body && isMomoaNode(sourceCode.ast.body) && typeof sourceCode.getParent === "function";
|
||||
}
|
||||
function isMomoaNode(node) {
|
||||
return MOMOA_NODES.has(node.type);
|
||||
}
|
||||
|
||||
function convertSourceLocationFromJsonToJsonc(loc) {
|
||||
return {
|
||||
start: convertPositionFromJsonToJsonc(loc.start),
|
||||
end: convertPositionFromJsonToJsonc(loc.end)
|
||||
};
|
||||
}
|
||||
function convertPositionFromJsonToJsonc(position) {
|
||||
return {
|
||||
line: position.line,
|
||||
column: position.column - 1
|
||||
};
|
||||
}
|
||||
function convertSourceLocationFromJsoncToJson(loc) {
|
||||
return {
|
||||
start: convertPositionFromJsoncToJson(loc.start),
|
||||
end: convertPositionFromJsoncToJson(loc.end)
|
||||
};
|
||||
}
|
||||
function convertPositionFromJsoncToJson(position) {
|
||||
return {
|
||||
line: position.line,
|
||||
column: position.column + 1
|
||||
};
|
||||
}
|
||||
|
||||
const TOKEN_CONVERTERS = /* @__PURE__ */ new WeakMap();
|
||||
function getTokenConverter(jsonSourceCode) {
|
||||
const converter = TOKEN_CONVERTERS.get(jsonSourceCode.ast);
|
||||
if (converter) {
|
||||
return converter;
|
||||
}
|
||||
const convertedTokens = /* @__PURE__ */ new Map();
|
||||
const tokenConverters = {
|
||||
BlockComment(token) {
|
||||
return {
|
||||
type: "Block",
|
||||
get value() {
|
||||
return jsonSourceCode.text.slice(
|
||||
token.range[0] + 2,
|
||||
token.range[1] - 2
|
||||
);
|
||||
},
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
},
|
||||
LineComment(token) {
|
||||
return {
|
||||
type: "Line",
|
||||
get value() {
|
||||
return jsonSourceCode.text.slice(
|
||||
token.range[0] + 2,
|
||||
token.range[1]
|
||||
);
|
||||
},
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
},
|
||||
Boolean(token) {
|
||||
return createStandardToken("Keyword", token);
|
||||
},
|
||||
Null(token) {
|
||||
return createStandardToken("Keyword", token);
|
||||
},
|
||||
Identifier(token) {
|
||||
return createStandardToken("Identifier", token);
|
||||
},
|
||||
Infinity(token) {
|
||||
const raw = jsonSourceCode.text.slice(...token.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
return [
|
||||
createPunctuator(raw[0], {
|
||||
range: [token.range[0], token.range[0] + 1],
|
||||
loc: {
|
||||
start: token.loc.start,
|
||||
end: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
}
|
||||
}
|
||||
}),
|
||||
createStandardToken("Identifier", {
|
||||
range: [token.range[0] + 1, token.range[1]],
|
||||
loc: {
|
||||
start: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
},
|
||||
end: token.loc.end
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
return createStandardToken("Identifier", token);
|
||||
},
|
||||
NaN(token) {
|
||||
const raw = jsonSourceCode.text.slice(...token.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
return [
|
||||
createPunctuator(raw[0], {
|
||||
range: [token.range[0], token.range[0] + 1],
|
||||
loc: {
|
||||
start: token.loc.start,
|
||||
end: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
}
|
||||
}
|
||||
}),
|
||||
createStandardToken("Identifier", {
|
||||
range: [token.range[0] + 1, token.range[1]],
|
||||
loc: {
|
||||
start: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
},
|
||||
end: token.loc.end
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
return createStandardToken("Identifier", token);
|
||||
},
|
||||
Number(token) {
|
||||
const raw = jsonSourceCode.text.slice(...token.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
return [
|
||||
createPunctuator(raw[0], {
|
||||
range: [token.range[0], token.range[0] + 1],
|
||||
loc: {
|
||||
start: token.loc.start,
|
||||
end: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
}
|
||||
}
|
||||
}),
|
||||
createStandardToken("Numeric", {
|
||||
range: [token.range[0] + 1, token.range[1]],
|
||||
loc: {
|
||||
start: {
|
||||
line: token.loc.start.line,
|
||||
column: token.loc.start.column + 1
|
||||
},
|
||||
end: token.loc.end
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
return createStandardToken("Numeric", token);
|
||||
},
|
||||
String(token) {
|
||||
return createStandardToken("String", token);
|
||||
},
|
||||
Colon(token) {
|
||||
return createPunctuator(":", token);
|
||||
},
|
||||
Comma(token) {
|
||||
return createPunctuator(",", token);
|
||||
},
|
||||
LBracket(token) {
|
||||
return createPunctuator("[", token);
|
||||
},
|
||||
LBrace(token) {
|
||||
return createPunctuator("{", token);
|
||||
},
|
||||
RBracket(token) {
|
||||
return createPunctuator("]", token);
|
||||
},
|
||||
RBrace(token) {
|
||||
return createPunctuator("}", token);
|
||||
}
|
||||
};
|
||||
TOKEN_CONVERTERS.set(jsonSourceCode.ast, convertToken);
|
||||
return convertToken;
|
||||
function createStandardToken(type, token) {
|
||||
return {
|
||||
type,
|
||||
get value() {
|
||||
return jsonSourceCode.text.slice(...token.range);
|
||||
},
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
}
|
||||
function createPunctuator(value, token) {
|
||||
return {
|
||||
type: "Punctuator",
|
||||
value,
|
||||
range: token.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(token.loc)
|
||||
};
|
||||
}
|
||||
function convertToken(token) {
|
||||
if (convertedTokens.has(token)) {
|
||||
return convertedTokens.get(token);
|
||||
}
|
||||
const newToken = tokenConverters[token.type](token);
|
||||
convertedTokens.set(token, newToken);
|
||||
return newToken;
|
||||
}
|
||||
}
|
||||
|
||||
const NODE_CONVERTERS = /* @__PURE__ */ new WeakMap();
|
||||
function getNodeConverter(jsonSourceCode) {
|
||||
const converter = NODE_CONVERTERS.get(jsonSourceCode.ast);
|
||||
if (converter) {
|
||||
return converter;
|
||||
}
|
||||
const tokenConverter = getTokenConverter(jsonSourceCode);
|
||||
const convertedNodes = /* @__PURE__ */ new Map();
|
||||
const nodeConverters = {
|
||||
Array(node) {
|
||||
let elements;
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONArrayExpression",
|
||||
get elements() {
|
||||
return elements != null ? elements : elements = node.elements.map((e) => convertNode(e.value));
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Boolean(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: node.value,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Null(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: null,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Number(node) {
|
||||
const raw = jsonSourceCode.text.slice(...node.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
const argumentRange = [node.range[0] + 1, node.range[1]];
|
||||
const rawArgument = jsonSourceCode.text.slice(...argumentRange);
|
||||
const literal = {
|
||||
get parent() {
|
||||
return unaryExpression;
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: Math.abs(node.value),
|
||||
bigint: null,
|
||||
regex: null,
|
||||
raw: rawArgument,
|
||||
range: argumentRange,
|
||||
loc: convertSourceLocationFromJsonToJsonc({
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
},
|
||||
end: node.loc.end
|
||||
})
|
||||
};
|
||||
const unaryExpression = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONUnaryExpression",
|
||||
operator: raw[0],
|
||||
prefix: true,
|
||||
argument: literal,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
return [unaryExpression, literal];
|
||||
}
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: node.value,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
String(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONLiteral",
|
||||
value: node.value,
|
||||
bigint: null,
|
||||
regex: null,
|
||||
get raw() {
|
||||
return jsonSourceCode.text.slice(...node.range);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Document(node) {
|
||||
let expression, tokens, comments;
|
||||
const program = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "Program",
|
||||
get body() {
|
||||
return body;
|
||||
},
|
||||
get comments() {
|
||||
return comments != null ? comments : comments = node.tokens.filter(
|
||||
(token) => token.type === "LineComment" || token.type === "BlockComment"
|
||||
).flatMap(tokenConverter);
|
||||
},
|
||||
get tokens() {
|
||||
return tokens != null ? tokens : tokens = node.tokens.filter(
|
||||
(token) => token.type !== "LineComment" && token.type !== "BlockComment"
|
||||
).flatMap(tokenConverter);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
const expr = {
|
||||
parent: program,
|
||||
type: "JSONExpressionStatement",
|
||||
get expression() {
|
||||
return expression != null ? expression : expression = convertNode(node.body);
|
||||
},
|
||||
range: node.body.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.body.loc)
|
||||
};
|
||||
const body = [expr];
|
||||
return [program, expr];
|
||||
},
|
||||
Object(node) {
|
||||
let members;
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONObjectExpression",
|
||||
get properties() {
|
||||
return members != null ? members : members = node.members.map(convertNode);
|
||||
},
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Member(node) {
|
||||
let keyNode, value;
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONProperty",
|
||||
get key() {
|
||||
return keyNode != null ? keyNode : keyNode = convertNode(node.name);
|
||||
},
|
||||
get value() {
|
||||
return value != null ? value : value = convertNode(node.value);
|
||||
},
|
||||
kind: "init",
|
||||
method: false,
|
||||
shorthand: false,
|
||||
computed: false,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Identifier(node) {
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: node.name,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
Infinity(node) {
|
||||
const raw = jsonSourceCode.text.slice(...node.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
const argumentRange = [node.range[0] + 1, node.range[1]];
|
||||
const identifier = {
|
||||
get parent() {
|
||||
return unaryExpression;
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "Infinity",
|
||||
range: argumentRange,
|
||||
loc: convertSourceLocationFromJsonToJsonc({
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
},
|
||||
end: node.loc.end
|
||||
})
|
||||
};
|
||||
const unaryExpression = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONUnaryExpression",
|
||||
operator: raw[0],
|
||||
prefix: true,
|
||||
argument: identifier,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
return [unaryExpression, identifier];
|
||||
}
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "Infinity",
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
},
|
||||
NaN(node) {
|
||||
const raw = jsonSourceCode.text.slice(...node.range);
|
||||
if (raw.startsWith("-") || raw.startsWith("+")) {
|
||||
const argumentRange = [node.range[0] + 1, node.range[1]];
|
||||
const identifier = {
|
||||
get parent() {
|
||||
return unaryExpression;
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "NaN",
|
||||
range: argumentRange,
|
||||
loc: convertSourceLocationFromJsonToJsonc({
|
||||
start: {
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column + 1
|
||||
},
|
||||
end: node.loc.end
|
||||
})
|
||||
};
|
||||
const unaryExpression = {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONUnaryExpression",
|
||||
operator: raw[0],
|
||||
prefix: true,
|
||||
argument: identifier,
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
return [unaryExpression, identifier];
|
||||
}
|
||||
return {
|
||||
get parent() {
|
||||
return getParent(node);
|
||||
},
|
||||
type: "JSONIdentifier",
|
||||
name: "NaN",
|
||||
range: node.range,
|
||||
loc: convertSourceLocationFromJsonToJsonc(node.loc)
|
||||
};
|
||||
}
|
||||
};
|
||||
NODE_CONVERTERS.set(jsonSourceCode.ast, convert);
|
||||
return convert;
|
||||
function convert(node) {
|
||||
if (convertedNodes.has(node)) {
|
||||
return convertedNodes.get(node);
|
||||
}
|
||||
const newNode = nodeConverters[node.type](node);
|
||||
let result;
|
||||
if (Array.isArray(newNode)) {
|
||||
convertedNodes.set(
|
||||
node,
|
||||
result = {
|
||||
node: newNode[0],
|
||||
nodes: newNode
|
||||
}
|
||||
);
|
||||
} else {
|
||||
convertedNodes.set(node, result = { node: newNode });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function getParent(node) {
|
||||
const parent = jsonSourceCode.getParent(node);
|
||||
if (!parent) return null;
|
||||
const parentNode = parent;
|
||||
if (parentNode.type === "Element") {
|
||||
return getParent(parentNode);
|
||||
}
|
||||
const convertedParent = convert(parentNode);
|
||||
if (convertedParent.nodes) {
|
||||
return convertedParent.nodes[convertedParent.nodes.length - 1];
|
||||
}
|
||||
return convertedParent.node;
|
||||
}
|
||||
function convertNode(node) {
|
||||
return convert(node).node;
|
||||
}
|
||||
}
|
||||
|
||||
function convertJsoncSourceCode(jsonSourceCode) {
|
||||
const convert = getNodeConverter(jsonSourceCode);
|
||||
const jsSourceCode = new SourceCode({
|
||||
text: jsonSourceCode.text,
|
||||
ast: convert(jsonSourceCode.ast).nodes[0],
|
||||
parserServices: { isJSON: true },
|
||||
visitorKeys: VisitorKeys
|
||||
});
|
||||
const compatSourceCode = newProxyWithGet(
|
||||
jsonSourceCode,
|
||||
(target, prop, receiver) => {
|
||||
const value = proxyReflectValue(
|
||||
Reflect.get(jsSourceCode, prop),
|
||||
jsSourceCode,
|
||||
target
|
||||
);
|
||||
if (value !== void 0) return value;
|
||||
return Reflect.get(jsonSourceCode, prop, receiver);
|
||||
}
|
||||
);
|
||||
return compatSourceCode;
|
||||
}
|
||||
|
||||
const NODE_TYPE_MAP = /* @__PURE__ */ new Map([
|
||||
["Program", ["Document"]],
|
||||
["JSONExpressionStatement", ["Document"]],
|
||||
["JSONLiteral", ["Boolean", "String", "Null", "Number"]],
|
||||
["JSONArrayExpression", ["Array"]],
|
||||
["JSONObjectExpression", ["Object"]],
|
||||
["JSONProperty", ["Member"]],
|
||||
["JSONIdentifier", ["Identifier", "Infinity", "NaN"]],
|
||||
["JSONUnaryExpression", ["Number", "Infinity", "NaN"]]
|
||||
]);
|
||||
const reIsSimpleNodeQuery = /^[a-z]+$/iu;
|
||||
function convertQuery(eslintQuery) {
|
||||
const exit = eslintQuery.endsWith(":exit");
|
||||
const query = exit ? eslintQuery.slice(0, -5) : eslintQuery;
|
||||
const converted = convertRawQuery(query);
|
||||
return converted && (exit ? {
|
||||
query: `${converted.query}:exit`,
|
||||
match: converted.match
|
||||
} : converted);
|
||||
}
|
||||
function convertRawQuery(query) {
|
||||
const queries = query.split(",").map((q) => q.trim());
|
||||
if (queries.every((q) => reIsSimpleNodeQuery.test(q))) {
|
||||
const convertTargetNodes = new Set(queries);
|
||||
const convertedQueries = [];
|
||||
for (const node of queries) {
|
||||
const converted = NODE_TYPE_MAP.get(node);
|
||||
if (converted) {
|
||||
convertedQueries.push(...converted);
|
||||
} else {
|
||||
convertTargetNodes.delete(node);
|
||||
}
|
||||
}
|
||||
return convertedQueries.length ? {
|
||||
query: convertedQueries.join(","),
|
||||
match: (node) => convertTargetNodes.has(node.type)
|
||||
} : null;
|
||||
}
|
||||
if (query === "*") {
|
||||
return {
|
||||
query: "*",
|
||||
match: () => true
|
||||
};
|
||||
}
|
||||
const selector = esquery.parse(query);
|
||||
const match = (node) => {
|
||||
let target = node;
|
||||
const ancestors = [];
|
||||
while (target.parent) {
|
||||
ancestors.push(target.parent);
|
||||
target = target.parent;
|
||||
}
|
||||
return esquery.matches(node, selector, ancestors, {
|
||||
visitorKeys: VisitorKeys
|
||||
});
|
||||
};
|
||||
return { query: "*", match };
|
||||
}
|
||||
|
||||
function toCompatRuleListener(ruleListener, jsonSourceCode) {
|
||||
const convert = getNodeConverter(jsonSourceCode);
|
||||
const jsoncNodeVisitors = /* @__PURE__ */ new Map();
|
||||
const queries = /* @__PURE__ */ new Set();
|
||||
for (const [key, fn] of Object.entries(ruleListener)) {
|
||||
if (!fn) continue;
|
||||
queries.add(key);
|
||||
const convertedQuery = convertQuery(key);
|
||||
if (!convertedQuery) continue;
|
||||
const { query, match } = convertedQuery;
|
||||
queries.add(query);
|
||||
let jsoncNodeVisitorList = jsoncNodeVisitors.get(query);
|
||||
if (!jsoncNodeVisitorList) {
|
||||
jsoncNodeVisitorList = [];
|
||||
jsoncNodeVisitors.set(query, jsoncNodeVisitorList);
|
||||
}
|
||||
jsoncNodeVisitorList.push((node) => {
|
||||
if (match(node)) {
|
||||
fn(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
const result = {};
|
||||
for (const query of queries) {
|
||||
result[query] = (node) => {
|
||||
var _a;
|
||||
if (isMomoaNode(node)) {
|
||||
if (node.type !== "Element") {
|
||||
const jsoncNodeVisitorList = jsoncNodeVisitors.get(query);
|
||||
if (!jsoncNodeVisitorList) return;
|
||||
const invoke = query.endsWith(":exit") ? invokeWithReverseConvertedNode : invokeWithConvertedNode;
|
||||
invoke(node, (n) => {
|
||||
jsoncNodeVisitorList.forEach((cb) => cb(n));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
(_a = ruleListener[query]) == null ? void 0 : _a.call(ruleListener, node);
|
||||
}
|
||||
};
|
||||
}
|
||||
return result;
|
||||
function invokeWithConvertedNode(node, cb) {
|
||||
const jsonNodeData = convert(node);
|
||||
if (jsonNodeData.nodes) {
|
||||
for (const n of jsonNodeData.nodes) {
|
||||
cb(n);
|
||||
}
|
||||
} else {
|
||||
cb(jsonNodeData.node);
|
||||
}
|
||||
}
|
||||
function invokeWithReverseConvertedNode(node, cb) {
|
||||
const jsonNodeData = convert(node);
|
||||
if (jsonNodeData.nodes) {
|
||||
for (let index = jsonNodeData.nodes.length - 1; index >= 0; index--) {
|
||||
const n = jsonNodeData.nodes[index];
|
||||
cb(n);
|
||||
}
|
||||
} else {
|
||||
cb(jsonNodeData.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CONVERTED$2 = /* @__PURE__ */ new WeakMap();
|
||||
function toCompatCreate(create) {
|
||||
if (CONVERTED$2.has(create)) {
|
||||
return CONVERTED$2.get(create);
|
||||
}
|
||||
const result = (context, ...args) => {
|
||||
const originalSourceCode = context.sourceCode;
|
||||
if (!originalSourceCode || !isJSONSourceCode(originalSourceCode)) {
|
||||
return create(context, ...args);
|
||||
}
|
||||
let sourceCode;
|
||||
const compatContext = newProxyWithProperties(context, {
|
||||
get sourceCode() {
|
||||
return sourceCode != null ? sourceCode : sourceCode = convertJsoncSourceCode(originalSourceCode);
|
||||
},
|
||||
report(descriptor) {
|
||||
const momoaDescriptor = {
|
||||
...descriptor
|
||||
};
|
||||
if ("loc" in momoaDescriptor && momoaDescriptor.loc) {
|
||||
if ("line" in momoaDescriptor.loc) {
|
||||
momoaDescriptor.loc = convertPositionFromJsoncToJson(
|
||||
momoaDescriptor.loc
|
||||
);
|
||||
} else {
|
||||
momoaDescriptor.loc = convertSourceLocationFromJsoncToJson(
|
||||
momoaDescriptor.loc
|
||||
);
|
||||
}
|
||||
}
|
||||
if ("node" in momoaDescriptor && momoaDescriptor.node) {
|
||||
momoaDescriptor.node = {
|
||||
...momoaDescriptor.node,
|
||||
loc: convertSourceLocationFromJsoncToJson(
|
||||
momoaDescriptor.node.loc
|
||||
)
|
||||
};
|
||||
}
|
||||
context.report(momoaDescriptor);
|
||||
}
|
||||
});
|
||||
return toCompatRuleListener(
|
||||
create(compatContext, ...args),
|
||||
originalSourceCode
|
||||
);
|
||||
};
|
||||
CONVERTED$2.set(create, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
const CONVERTED$1 = /* @__PURE__ */ new WeakMap();
|
||||
function toCompatRule(rule) {
|
||||
if (CONVERTED$1.has(rule)) {
|
||||
return CONVERTED$1.get(rule);
|
||||
}
|
||||
const result = {
|
||||
...rule,
|
||||
create: toCompatCreate(rule.create)
|
||||
};
|
||||
CONVERTED$1.set(rule, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
const CONVERTED = /* @__PURE__ */ new WeakMap();
|
||||
function toCompatPlugin(plugin) {
|
||||
if (!plugin.rules) {
|
||||
return plugin;
|
||||
}
|
||||
if (CONVERTED.has(plugin)) {
|
||||
return CONVERTED.get(plugin);
|
||||
}
|
||||
const rules = newProxyWithGet(plugin.rules, (target, prop) => {
|
||||
const rule = Reflect.get(target, prop);
|
||||
return rule && toCompatRule(rule);
|
||||
});
|
||||
const result = newProxyWithProperties(plugin, {
|
||||
rules
|
||||
});
|
||||
CONVERTED.set(plugin, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
export { toCompatCreate, toCompatPlugin, toCompatRule };
|
||||
Reference in New Issue
Block a user