corsa-oxlint 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checker.js +83 -10
- package/dist/checker.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/oxlint_utils.d.ts +6 -5
- package/dist/oxlint_utils.js.map +1 -1
- package/dist/parser_services.js +144 -2
- package/dist/parser_services.js.map +1 -1
- package/dist/plugin.d.ts +10 -8
- package/dist/plugin.js.map +1 -1
- package/dist/rule_tester.d.ts +9 -2
- package/dist/rule_tester.js.map +1 -1
- package/dist/rules/await_thenable.d.ts +2 -12
- package/dist/rules/index.d.ts +88 -1423
- package/dist/rules/index.js +27 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/native_bridge.d.ts +2 -12
- package/dist/rules/no_array_delete.d.ts +2 -12
- package/dist/rules/no_base_to_string.d.ts +2 -12
- package/dist/rules/no_floating_promises.d.ts +2 -12
- package/dist/rules/no_for_in_array.d.ts +2 -12
- package/dist/rules/no_implied_eval.d.ts +2 -12
- package/dist/rules/no_meaningless_void_operator.d.ts +2 -12
- package/dist/rules/no_mixed_enums.d.ts +2 -12
- package/dist/rules/no_unsafe_assignment.d.ts +2 -12
- package/dist/rules/no_unsafe_call.d.ts +2 -12
- package/dist/rules/no_unsafe_member_access.d.ts +2 -12
- package/dist/rules/no_unsafe_return.d.ts +2 -12
- package/dist/rules/no_unsafe_type_assertion.d.ts +2 -12
- package/dist/rules/no_unsafe_unary_minus.d.ts +2 -12
- package/dist/rules/only_throw_error.d.ts +2 -12
- package/dist/rules/pending_parity.d.ts +35 -408
- package/dist/rules/prefer_find.d.ts +2 -12
- package/dist/rules/prefer_includes.d.ts +2 -12
- package/dist/rules/prefer_promise_reject_errors.d.ts +2 -12
- package/dist/rules/prefer_reduce_type_parameter.d.ts +2 -12
- package/dist/rules/prefer_regexp_exec.d.ts +2 -12
- package/dist/rules/prefer_string_starts_ends_with.d.ts +2 -12
- package/dist/rules/require_array_sort_compare.d.ts +2 -12
- package/dist/rules/restrict_plus_operands.d.ts +2 -12
- package/dist/rules/restrict_template_expressions.d.ts +2 -12
- package/dist/rules/rule_creator.d.ts +2 -12
- package/dist/rules/use_unknown_in_catch_callback_variable.d.ts +2 -12
- package/dist/session.d.ts +1 -0
- package/dist/session.js +59 -15
- package/dist/session.js.map +1 -1
- package/dist/ts_eslint.d.ts +2 -2
- package/dist/ts_eslint.js.map +1 -1
- package/package.json +2 -2
package/dist/checker.js
CHANGED
|
@@ -200,18 +200,21 @@ function implementedTypesFromCorsaNode(context, node, checker) {
|
|
|
200
200
|
function implementedTypesFromSourceText(node, sourceText, checker) {
|
|
201
201
|
if (node.pos < 0 || node.end > sourceText.length || node.pos >= node.end) return [];
|
|
202
202
|
const classText = sourceText.slice(node.pos, node.end);
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
const
|
|
203
|
+
const classStart = findKeywordOutsideTrivia(classText, "class");
|
|
204
|
+
const headerStart = classStart >= 0 ? classStart : 0;
|
|
205
|
+
const bodyOpen = findClassBodyOpen(classText, headerStart);
|
|
206
|
+
const headerText = classText.slice(headerStart, bodyOpen >= 0 ? bodyOpen : classText.length);
|
|
207
|
+
const implementsIndex = findKeywordOutsideTrivia(headerText, "implements");
|
|
206
208
|
if (implementsIndex < 0) return [];
|
|
207
209
|
const clauseText = headerText.slice(implementsIndex + 10);
|
|
210
|
+
const clauseStart = node.pos + headerStart + implementsIndex + 10;
|
|
208
211
|
return splitTopLevelRanges(clauseText, ",").map((range) => {
|
|
209
212
|
const raw = clauseText.slice(range.start, range.end);
|
|
210
213
|
const leading = raw.search(/\S/);
|
|
211
214
|
if (leading < 0) return;
|
|
212
215
|
const trailing = raw.match(/\s*$/)?.[0].length ?? 0;
|
|
213
|
-
const pos =
|
|
214
|
-
const end =
|
|
216
|
+
const pos = clauseStart + range.start + leading;
|
|
217
|
+
const end = clauseStart + range.end - trailing;
|
|
215
218
|
const lookupNode = {
|
|
216
219
|
fileName: node.fileName,
|
|
217
220
|
pos,
|
|
@@ -222,6 +225,49 @@ function implementedTypesFromSourceText(node, sourceText, checker) {
|
|
|
222
225
|
return symbol ? checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol) : checker.getTypeAtLocation(lookupNode);
|
|
223
226
|
}).filter((type) => type !== void 0);
|
|
224
227
|
}
|
|
228
|
+
function findClassBodyOpen(text, start) {
|
|
229
|
+
const scanner = createScanner();
|
|
230
|
+
let angleDepth = 0;
|
|
231
|
+
let parenDepth = 0;
|
|
232
|
+
let bracketDepth = 0;
|
|
233
|
+
let braceDepth = 0;
|
|
234
|
+
for (let index = start; index < text.length; index += 1) {
|
|
235
|
+
const nextIndex = scanner.skip(text, index);
|
|
236
|
+
if (nextIndex > index) {
|
|
237
|
+
index = nextIndex - 1;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const char = text[index];
|
|
241
|
+
if (char === "<") angleDepth += 1;
|
|
242
|
+
else if (char === ">") angleDepth = Math.max(0, angleDepth - 1);
|
|
243
|
+
else if (char === "(") parenDepth += 1;
|
|
244
|
+
else if (char === ")") parenDepth = Math.max(0, parenDepth - 1);
|
|
245
|
+
else if (char === "[") bracketDepth += 1;
|
|
246
|
+
else if (char === "]") bracketDepth = Math.max(0, bracketDepth - 1);
|
|
247
|
+
else if (char === "{" && angleDepth === 0 && parenDepth === 0 && bracketDepth === 0 && braceDepth === 0) return index;
|
|
248
|
+
else if (char === "{") braceDepth += 1;
|
|
249
|
+
else if (char === "}") braceDepth = Math.max(0, braceDepth - 1);
|
|
250
|
+
}
|
|
251
|
+
return -1;
|
|
252
|
+
}
|
|
253
|
+
function findKeywordOutsideTrivia(text, keyword) {
|
|
254
|
+
const scanner = createScanner();
|
|
255
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
256
|
+
const nextIndex = scanner.skip(text, index);
|
|
257
|
+
if (nextIndex > index) {
|
|
258
|
+
index = nextIndex - 1;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (matchesKeyword(text, keyword, index)) return index;
|
|
262
|
+
}
|
|
263
|
+
return -1;
|
|
264
|
+
}
|
|
265
|
+
function matchesKeyword(text, keyword, index) {
|
|
266
|
+
return text.startsWith(keyword, index) && !isIdentifierPart(text[index - 1]) && !isIdentifierPart(text[index + keyword.length]);
|
|
267
|
+
}
|
|
268
|
+
function isIdentifierPart(char) {
|
|
269
|
+
return char !== void 0 && /[A-Za-z0-9_$]/.test(char);
|
|
270
|
+
}
|
|
225
271
|
function splitTopLevelRanges(text, delimiter) {
|
|
226
272
|
const ranges = [];
|
|
227
273
|
const scanner = createScanner();
|
|
@@ -232,7 +278,11 @@ function splitTopLevelRanges(text, delimiter) {
|
|
|
232
278
|
let braceDepth = 0;
|
|
233
279
|
for (let index = 0; index < text.length; index += 1) {
|
|
234
280
|
const char = text[index];
|
|
235
|
-
|
|
281
|
+
const nextIndex = scanner.skip(text, index);
|
|
282
|
+
if (nextIndex > index) {
|
|
283
|
+
index = nextIndex - 1;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
236
286
|
if (char === "<") angleDepth += 1;
|
|
237
287
|
else if (char === ">") angleDepth = Math.max(0, angleDepth - 1);
|
|
238
288
|
else if (char === "(") parenDepth += 1;
|
|
@@ -258,18 +308,41 @@ function splitTopLevelRanges(text, delimiter) {
|
|
|
258
308
|
function createScanner() {
|
|
259
309
|
let quote;
|
|
260
310
|
let escaped = false;
|
|
261
|
-
|
|
311
|
+
let inLineComment = false;
|
|
312
|
+
let inBlockComment = false;
|
|
313
|
+
return { skip(text, index) {
|
|
314
|
+
const char = text[index];
|
|
315
|
+
const next = text[index + 1];
|
|
316
|
+
if (inLineComment) {
|
|
317
|
+
if (char === "\n" || char === "\r") inLineComment = false;
|
|
318
|
+
return index + 1;
|
|
319
|
+
}
|
|
320
|
+
if (inBlockComment) {
|
|
321
|
+
if (char === "*" && next === "/") {
|
|
322
|
+
inBlockComment = false;
|
|
323
|
+
return index + 2;
|
|
324
|
+
}
|
|
325
|
+
return index + 1;
|
|
326
|
+
}
|
|
262
327
|
if (quote) {
|
|
263
328
|
if (escaped) escaped = false;
|
|
264
329
|
else if (char === "\\") escaped = true;
|
|
265
330
|
else if (char === quote) quote = void 0;
|
|
266
|
-
return
|
|
331
|
+
return index + 1;
|
|
332
|
+
}
|
|
333
|
+
if (char === "/" && next === "/") {
|
|
334
|
+
inLineComment = true;
|
|
335
|
+
return index + 2;
|
|
336
|
+
}
|
|
337
|
+
if (char === "/" && next === "*") {
|
|
338
|
+
inBlockComment = true;
|
|
339
|
+
return index + 2;
|
|
267
340
|
}
|
|
268
341
|
if (char === "\"" || char === "'" || char === "`") {
|
|
269
342
|
quote = char;
|
|
270
|
-
return
|
|
343
|
+
return index + 1;
|
|
271
344
|
}
|
|
272
|
-
return
|
|
345
|
+
return index;
|
|
273
346
|
} };
|
|
274
347
|
}
|
|
275
348
|
function isNode(value) {
|
package/dist/checker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checker.js","names":[],"sources":["../ts/checker.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport { createNodeMaps, toPosition } from \"./node_map\";\nimport { sessionForContext } from \"./registry\";\nimport type {\n ContextWithParserOptions,\n CorsaNode,\n CorsaProgramShape,\n CorsaSignature,\n CorsaSymbol,\n CorsaType,\n CorsaTypeCheckerShape,\n} from \"./types\";\n\nexport function createProgram(\n context: ContextWithParserOptions,\n): CorsaProgramShape & { readonly nodeMaps: ReturnType<typeof createNodeMaps> } {\n const nodeMaps = createNodeMaps(context);\n return {\n nodeMaps,\n getCompilerOptions() {\n return sessionForContext(context).session.getCompilerOptions();\n },\n getCurrentDirectory() {\n return sessionForContext(context).project.rootDir;\n },\n getRootFileNames() {\n return sessionForContext(context).session.getRootFileNames();\n },\n getSourceFile(fileName = context.filename) {\n return { fileName, text: context.sourceCode.text };\n },\n getTypeChecker() {\n return createTypeChecker(context);\n },\n };\n}\n\nexport function createTypeChecker(context: ContextWithParserOptions): CorsaTypeCheckerShape {\n return {\n getTypeAtLocation(node) {\n if ((node as { readonly type?: string }).type === \"NewExpression\") {\n return typeOfNewExpression(node as Node, this);\n }\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getTypeAtPosition(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n );\n },\n getContextualType(node) {\n return this.getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getSymbolAtPosition(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n );\n },\n getSymbol(symbol) {\n return sessionForContext(context).session.getSymbol(symbol);\n },\n getSymbolById(id) {\n return sessionForContext(context).session.getSymbol(id);\n },\n getNode(node) {\n return sessionForContext(context).session.getNode(node);\n },\n getNodeById(id) {\n return sessionForContext(context).session.getNode(id);\n },\n getTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getTypeOfSymbol(symbol);\n },\n getDeclaredTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getDeclaredTypeOfSymbol(symbol);\n },\n getTypeOfSymbolAtLocation(symbol, node) {\n return (\n this.getTypeOfSymbol(symbol) ??\n this.getDeclaredTypeOfSymbol(symbol) ??\n this.getTypeAtLocation(node)\n );\n },\n typeToString(type, enclosingDeclaration, flags) {\n void enclosingDeclaration;\n return sessionForContext(context).session.typeToString(type, flags);\n },\n getBaseTypeOfLiteralType(type) {\n return sessionForContext(context).session.getBaseTypeOfLiteralType(type);\n },\n getPropertiesOfType(type) {\n return sessionForContext(context).session.getPropertiesOfType(type);\n },\n getSignaturesOfType(type, kind) {\n return sessionForContext(context).session.getSignaturesOfType(type, kind);\n },\n getReturnTypeOfSignature(signature) {\n return sessionForContext(context).session.getReturnTypeOfSignature(signature);\n },\n getTypePredicateOfSignature(signature) {\n return sessionForContext(context).session.getTypePredicateOfSignature(signature);\n },\n getBaseTypes(type) {\n return sessionForContext(context).session.getBaseTypes(type);\n },\n getImplementedTypes(node) {\n if (\"pos\" in node) {\n return implementedTypesFromCorsaNode(context, node, this);\n }\n return implementedClauseNodes(node)\n .map((clause) => {\n const expression = implementedClauseChildNode(clause, \"expression\") ?? clause;\n const symbol = this.getSymbolAtLocation(expression) ?? this.getSymbolAtLocation(clause);\n return symbol\n ? (this.getDeclaredTypeOfSymbol(symbol) ?? this.getTypeOfSymbol(symbol))\n : (this.getTypeAtLocation(expression) ?? this.getTypeAtLocation(clause));\n })\n .filter((type): type is CorsaType => type !== undefined);\n },\n getImplementedTypesOfType(type) {\n const session = sessionForContext(context).session;\n const symbol = type.symbol ? session.getSymbol(type.symbol) : undefined;\n const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];\n const declarationNode = declaration ? session.getNode(declaration) : undefined;\n const sourceText = declarationNode\n ? sourceTextForPath(context, declarationNode.fileName)\n : undefined;\n return declarationNode && sourceText\n ? implementedTypesFromSourceText(declarationNode, sourceText, this)\n : [];\n },\n getTypeArguments(type) {\n return sessionForContext(context).session.getTypeArguments(type);\n },\n getTypesOfType(type) {\n return sessionForContext(context).session.getTypesOfType(type);\n },\n getTargetOfType(type) {\n return sessionForContext(context).session.getTargetOfType(type);\n },\n getTypeParametersOfType(type) {\n return sessionForContext(context).session.getTypeParametersOfType(type);\n },\n getOuterTypeParametersOfType(type) {\n return sessionForContext(context).session.getOuterTypeParametersOfType(type);\n },\n getLocalTypeParametersOfType(type) {\n return sessionForContext(context).session.getLocalTypeParametersOfType(type);\n },\n getObjectTypeOfType(type) {\n return sessionForContext(context).session.getObjectTypeOfType(type);\n },\n getIndexTypeOfType(type) {\n return sessionForContext(context).session.getIndexTypeOfType(type);\n },\n getCheckTypeOfType(type) {\n return sessionForContext(context).session.getCheckTypeOfType(type);\n },\n getExtendsTypeOfType(type) {\n return sessionForContext(context).session.getExtendsTypeOfType(type);\n },\n getBaseTypeOfType(type) {\n return sessionForContext(context).session.getBaseTypeOfType(type);\n },\n getConstraintOfType(type) {\n return sessionForContext(context).session.getConstraintOfType(type);\n },\n isUnionType(type) {\n return (type.flags & typeFlags.union) !== 0;\n },\n isIntersectionType(type) {\n return (type.flags & typeFlags.intersection) !== 0;\n },\n };\n}\n\nconst typeFlags = {\n union: 1 << 27,\n intersection: 1 << 28,\n} as const;\n\nfunction sourceTextFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string | undefined {\n return sourceTextForPath(context, filenameFor(context, node));\n}\n\nfunction sourceTextForPath(\n context: ContextWithParserOptions,\n fileName: string,\n): string | undefined {\n const normalizedFileName = fileName.toLowerCase();\n const normalizedContextFilename = context.filename.toLowerCase();\n return normalizedFileName === normalizedContextFilename ||\n normalizedFileName.endsWith(normalizedContextFilename) ||\n normalizedContextFilename.endsWith(normalizedFileName)\n ? context.sourceCode.text\n : sessionForContext(context).session.getSourceTextForPath(fileName);\n}\n\nfunction typeOfNewExpression(node: Node, checker: CorsaTypeCheckerShape): CorsaType | undefined {\n const callee = childNode(node, \"callee\");\n if (!callee) {\n return undefined;\n }\n const calleeType = checker.getTypeAtLocation(callee);\n if (!calleeType) {\n return undefined;\n }\n const constructSignature = checker.getSignaturesOfType(calleeType, 1)[0];\n return constructSignature\n ? (checker.getReturnTypeOfSignature(constructSignature) ?? calleeType)\n : calleeType;\n}\n\nfunction nodeForTypeLookup(node: Node | CorsaNode): Node | CorsaNode {\n if (\"pos\" in node) {\n return node;\n }\n switch ((node as { readonly type?: string }).type) {\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n return childNode(node, \"id\") ?? node;\n case \"TSPropertySignature\":\n return childNode(node, \"key\") ?? node;\n default:\n return node;\n }\n}\n\nfunction childNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedClauseNodes(node: Node | CorsaNode): readonly Node[] {\n if (\"pos\" in node) {\n return [];\n }\n const clauses = (node as unknown as { readonly implements?: unknown }).implements;\n if (!Array.isArray(clauses)) {\n return [];\n }\n return clauses.filter(isNode);\n}\n\nfunction implementedClauseChildNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedTypesFromCorsaNode(\n context: ContextWithParserOptions,\n node: CorsaNode,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n const symbol = checker.getSymbolAtLocation(node);\n if (symbol) {\n const declaredType = checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol);\n if (declaredType) {\n const implemented = checker.getImplementedTypesOfType(declaredType);\n if (implemented.length > 0) {\n return implemented;\n }\n }\n }\n const sourceText = sourceTextFor(context, node);\n if (sourceText) {\n return implementedTypesFromSourceText(node, sourceText, checker);\n }\n const type = checker.getTypeAtLocation(node);\n return type ? checker.getImplementedTypesOfType(type) : [];\n}\n\nfunction implementedTypesFromSourceText(\n node: CorsaNode,\n sourceText: string,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n if (node.pos < 0 || node.end > sourceText.length || node.pos >= node.end) {\n return [];\n }\n const classText = sourceText.slice(node.pos, node.end);\n const bodyOpen = classText.indexOf(\"{\");\n const headerText = bodyOpen >= 0 ? classText.slice(0, bodyOpen) : classText;\n const implementsIndex = headerText.indexOf(\"implements\");\n if (implementsIndex < 0) {\n return [];\n }\n const clauseText = headerText.slice(implementsIndex + \"implements\".length);\n return splitTopLevelRanges(clauseText, \",\")\n .map((range) => {\n const raw = clauseText.slice(range.start, range.end);\n const leading = raw.search(/\\S/);\n if (leading < 0) {\n return undefined;\n }\n const trailing = raw.match(/\\s*$/)?.[0].length ?? 0;\n const pos = node.pos + implementsIndex + \"implements\".length + range.start + leading;\n const end = node.pos + implementsIndex + \"implements\".length + range.end - trailing;\n const lookupNode: CorsaNode = {\n fileName: node.fileName,\n pos,\n end,\n range: [pos, end] as const,\n };\n const symbol = checker.getSymbolAtLocation(lookupNode);\n return symbol\n ? (checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol))\n : checker.getTypeAtLocation(lookupNode);\n })\n .filter((type): type is CorsaType => type !== undefined);\n}\n\nfunction splitTopLevelRanges(\n text: string,\n delimiter: string,\n): readonly { readonly start: number; readonly end: number }[] {\n const ranges: { start: number; end: number }[] = [];\n const scanner = createScanner();\n let start = 0;\n let angleDepth = 0;\n let parenDepth = 0;\n let bracketDepth = 0;\n let braceDepth = 0;\n for (let index = 0; index < text.length; index += 1) {\n const char = text[index];\n if (scanner.inQuote(char)) {\n continue;\n }\n if (char === \"<\") angleDepth += 1;\n else if (char === \">\") angleDepth = Math.max(0, angleDepth - 1);\n else if (char === \"(\") parenDepth += 1;\n else if (char === \")\") parenDepth = Math.max(0, parenDepth - 1);\n else if (char === \"[\") bracketDepth += 1;\n else if (char === \"]\") bracketDepth = Math.max(0, bracketDepth - 1);\n else if (char === \"{\") braceDepth += 1;\n else if (char === \"}\") braceDepth = Math.max(0, braceDepth - 1);\n else if (\n char === delimiter &&\n angleDepth === 0 &&\n parenDepth === 0 &&\n bracketDepth === 0 &&\n braceDepth === 0\n ) {\n ranges.push({ start, end: index });\n start = index + 1;\n }\n }\n ranges.push({ start, end: text.length });\n return ranges;\n}\n\nfunction createScanner(): {\n inQuote(char: string): boolean;\n} {\n let quote: string | undefined;\n let escaped = false;\n return {\n inQuote(char) {\n if (quote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === quote) {\n quote = undefined;\n }\n return true;\n }\n if (char === '\"' || char === \"'\" || char === \"`\") {\n quote = char;\n return true;\n }\n return false;\n },\n };\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof value === \"object\" && value !== null && \"type\" in value && \"range\" in value;\n}\n\nfunction filenameFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string {\n if (\"fileName\" in node) {\n return node.fileName;\n }\n return context.filename;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"checker.js","names":[],"sources":["../ts/checker.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport { createNodeMaps, toPosition } from \"./node_map\";\nimport { sessionForContext } from \"./registry\";\nimport type {\n ContextWithParserOptions,\n CorsaNode,\n CorsaProgramShape,\n CorsaSignature,\n CorsaSymbol,\n CorsaType,\n CorsaTypeCheckerShape,\n} from \"./types\";\n\nexport function createProgram(\n context: ContextWithParserOptions,\n): CorsaProgramShape & { readonly nodeMaps: ReturnType<typeof createNodeMaps> } {\n const nodeMaps = createNodeMaps(context);\n return {\n nodeMaps,\n getCompilerOptions() {\n return sessionForContext(context).session.getCompilerOptions();\n },\n getCurrentDirectory() {\n return sessionForContext(context).project.rootDir;\n },\n getRootFileNames() {\n return sessionForContext(context).session.getRootFileNames();\n },\n getSourceFile(fileName = context.filename) {\n return { fileName, text: context.sourceCode.text };\n },\n getTypeChecker() {\n return createTypeChecker(context);\n },\n };\n}\n\nexport function createTypeChecker(context: ContextWithParserOptions): CorsaTypeCheckerShape {\n return {\n getTypeAtLocation(node) {\n if ((node as { readonly type?: string }).type === \"NewExpression\") {\n return typeOfNewExpression(node as Node, this);\n }\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getTypeAtPosition(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n );\n },\n getContextualType(node) {\n return this.getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getSymbolAtPosition(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n );\n },\n getSymbol(symbol) {\n return sessionForContext(context).session.getSymbol(symbol);\n },\n getSymbolById(id) {\n return sessionForContext(context).session.getSymbol(id);\n },\n getNode(node) {\n return sessionForContext(context).session.getNode(node);\n },\n getNodeById(id) {\n return sessionForContext(context).session.getNode(id);\n },\n getTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getTypeOfSymbol(symbol);\n },\n getDeclaredTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getDeclaredTypeOfSymbol(symbol);\n },\n getTypeOfSymbolAtLocation(symbol, node) {\n return (\n this.getTypeOfSymbol(symbol) ??\n this.getDeclaredTypeOfSymbol(symbol) ??\n this.getTypeAtLocation(node)\n );\n },\n typeToString(type, enclosingDeclaration, flags) {\n void enclosingDeclaration;\n return sessionForContext(context).session.typeToString(type, flags);\n },\n getBaseTypeOfLiteralType(type) {\n return sessionForContext(context).session.getBaseTypeOfLiteralType(type);\n },\n getPropertiesOfType(type) {\n return sessionForContext(context).session.getPropertiesOfType(type);\n },\n getSignaturesOfType(type, kind) {\n return sessionForContext(context).session.getSignaturesOfType(type, kind);\n },\n getReturnTypeOfSignature(signature) {\n return sessionForContext(context).session.getReturnTypeOfSignature(signature);\n },\n getTypePredicateOfSignature(signature) {\n return sessionForContext(context).session.getTypePredicateOfSignature(signature);\n },\n getBaseTypes(type) {\n return sessionForContext(context).session.getBaseTypes(type);\n },\n getImplementedTypes(node) {\n if (\"pos\" in node) {\n return implementedTypesFromCorsaNode(context, node, this);\n }\n return implementedClauseNodes(node)\n .map((clause) => {\n const expression = implementedClauseChildNode(clause, \"expression\") ?? clause;\n const symbol = this.getSymbolAtLocation(expression) ?? this.getSymbolAtLocation(clause);\n return symbol\n ? (this.getDeclaredTypeOfSymbol(symbol) ?? this.getTypeOfSymbol(symbol))\n : (this.getTypeAtLocation(expression) ?? this.getTypeAtLocation(clause));\n })\n .filter((type): type is CorsaType => type !== undefined);\n },\n getImplementedTypesOfType(type) {\n const session = sessionForContext(context).session;\n const symbol = type.symbol ? session.getSymbol(type.symbol) : undefined;\n const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];\n const declarationNode = declaration ? session.getNode(declaration) : undefined;\n const sourceText = declarationNode\n ? sourceTextForPath(context, declarationNode.fileName)\n : undefined;\n return declarationNode && sourceText\n ? implementedTypesFromSourceText(declarationNode, sourceText, this)\n : [];\n },\n getTypeArguments(type) {\n return sessionForContext(context).session.getTypeArguments(type);\n },\n getTypesOfType(type) {\n return sessionForContext(context).session.getTypesOfType(type);\n },\n getTargetOfType(type) {\n return sessionForContext(context).session.getTargetOfType(type);\n },\n getTypeParametersOfType(type) {\n return sessionForContext(context).session.getTypeParametersOfType(type);\n },\n getOuterTypeParametersOfType(type) {\n return sessionForContext(context).session.getOuterTypeParametersOfType(type);\n },\n getLocalTypeParametersOfType(type) {\n return sessionForContext(context).session.getLocalTypeParametersOfType(type);\n },\n getObjectTypeOfType(type) {\n return sessionForContext(context).session.getObjectTypeOfType(type);\n },\n getIndexTypeOfType(type) {\n return sessionForContext(context).session.getIndexTypeOfType(type);\n },\n getCheckTypeOfType(type) {\n return sessionForContext(context).session.getCheckTypeOfType(type);\n },\n getExtendsTypeOfType(type) {\n return sessionForContext(context).session.getExtendsTypeOfType(type);\n },\n getBaseTypeOfType(type) {\n return sessionForContext(context).session.getBaseTypeOfType(type);\n },\n getConstraintOfType(type) {\n return sessionForContext(context).session.getConstraintOfType(type);\n },\n isUnionType(type) {\n return (type.flags & typeFlags.union) !== 0;\n },\n isIntersectionType(type) {\n return (type.flags & typeFlags.intersection) !== 0;\n },\n };\n}\n\nconst typeFlags = {\n union: 1 << 27,\n intersection: 1 << 28,\n} as const;\n\nfunction sourceTextFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string | undefined {\n return sourceTextForPath(context, filenameFor(context, node));\n}\n\nfunction sourceTextForPath(\n context: ContextWithParserOptions,\n fileName: string,\n): string | undefined {\n const normalizedFileName = fileName.toLowerCase();\n const normalizedContextFilename = context.filename.toLowerCase();\n return normalizedFileName === normalizedContextFilename ||\n normalizedFileName.endsWith(normalizedContextFilename) ||\n normalizedContextFilename.endsWith(normalizedFileName)\n ? context.sourceCode.text\n : sessionForContext(context).session.getSourceTextForPath(fileName);\n}\n\nfunction typeOfNewExpression(node: Node, checker: CorsaTypeCheckerShape): CorsaType | undefined {\n const callee = childNode(node, \"callee\");\n if (!callee) {\n return undefined;\n }\n const calleeType = checker.getTypeAtLocation(callee);\n if (!calleeType) {\n return undefined;\n }\n const constructSignature = checker.getSignaturesOfType(calleeType, 1)[0];\n return constructSignature\n ? (checker.getReturnTypeOfSignature(constructSignature) ?? calleeType)\n : calleeType;\n}\n\nfunction nodeForTypeLookup(node: Node | CorsaNode): Node | CorsaNode {\n if (\"pos\" in node) {\n return node;\n }\n switch ((node as { readonly type?: string }).type) {\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n return childNode(node, \"id\") ?? node;\n case \"TSPropertySignature\":\n return childNode(node, \"key\") ?? node;\n default:\n return node;\n }\n}\n\nfunction childNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedClauseNodes(node: Node | CorsaNode): readonly Node[] {\n if (\"pos\" in node) {\n return [];\n }\n const clauses = (node as unknown as { readonly implements?: unknown }).implements;\n if (!Array.isArray(clauses)) {\n return [];\n }\n return clauses.filter(isNode);\n}\n\nfunction implementedClauseChildNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedTypesFromCorsaNode(\n context: ContextWithParserOptions,\n node: CorsaNode,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n const symbol = checker.getSymbolAtLocation(node);\n if (symbol) {\n const declaredType = checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol);\n if (declaredType) {\n const implemented = checker.getImplementedTypesOfType(declaredType);\n if (implemented.length > 0) {\n return implemented;\n }\n }\n }\n const sourceText = sourceTextFor(context, node);\n if (sourceText) {\n return implementedTypesFromSourceText(node, sourceText, checker);\n }\n const type = checker.getTypeAtLocation(node);\n return type ? checker.getImplementedTypesOfType(type) : [];\n}\n\nfunction implementedTypesFromSourceText(\n node: CorsaNode,\n sourceText: string,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n if (node.pos < 0 || node.end > sourceText.length || node.pos >= node.end) {\n return [];\n }\n const classText = sourceText.slice(node.pos, node.end);\n const classStart = findKeywordOutsideTrivia(classText, \"class\");\n const headerStart = classStart >= 0 ? classStart : 0;\n const bodyOpen = findClassBodyOpen(classText, headerStart);\n const headerText = classText.slice(headerStart, bodyOpen >= 0 ? bodyOpen : classText.length);\n const implementsIndex = findKeywordOutsideTrivia(headerText, \"implements\");\n if (implementsIndex < 0) {\n return [];\n }\n const clauseText = headerText.slice(implementsIndex + \"implements\".length);\n const clauseStart = node.pos + headerStart + implementsIndex + \"implements\".length;\n return splitTopLevelRanges(clauseText, \",\")\n .map((range) => {\n const raw = clauseText.slice(range.start, range.end);\n const leading = raw.search(/\\S/);\n if (leading < 0) {\n return undefined;\n }\n const trailing = raw.match(/\\s*$/)?.[0].length ?? 0;\n const pos = clauseStart + range.start + leading;\n const end = clauseStart + range.end - trailing;\n const lookupNode: CorsaNode = {\n fileName: node.fileName,\n pos,\n end,\n range: [pos, end] as const,\n };\n const symbol = checker.getSymbolAtLocation(lookupNode);\n return symbol\n ? (checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol))\n : checker.getTypeAtLocation(lookupNode);\n })\n .filter((type): type is CorsaType => type !== undefined);\n}\n\nfunction findClassBodyOpen(text: string, start: number): number {\n const scanner = createScanner();\n let angleDepth = 0;\n let parenDepth = 0;\n let bracketDepth = 0;\n let braceDepth = 0;\n for (let index = start; index < text.length; index += 1) {\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n const char = text[index];\n if (char === \"<\") angleDepth += 1;\n else if (char === \">\") angleDepth = Math.max(0, angleDepth - 1);\n else if (char === \"(\") parenDepth += 1;\n else if (char === \")\") parenDepth = Math.max(0, parenDepth - 1);\n else if (char === \"[\") bracketDepth += 1;\n else if (char === \"]\") bracketDepth = Math.max(0, bracketDepth - 1);\n else if (\n char === \"{\" &&\n angleDepth === 0 &&\n parenDepth === 0 &&\n bracketDepth === 0 &&\n braceDepth === 0\n ) {\n return index;\n } else if (char === \"{\") braceDepth += 1;\n else if (char === \"}\") braceDepth = Math.max(0, braceDepth - 1);\n }\n return -1;\n}\n\nfunction findKeywordOutsideTrivia(text: string, keyword: string): number {\n const scanner = createScanner();\n for (let index = 0; index < text.length; index += 1) {\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n if (matchesKeyword(text, keyword, index)) {\n return index;\n }\n }\n return -1;\n}\n\nfunction matchesKeyword(text: string, keyword: string, index: number): boolean {\n return (\n text.startsWith(keyword, index) &&\n !isIdentifierPart(text[index - 1]) &&\n !isIdentifierPart(text[index + keyword.length])\n );\n}\n\nfunction isIdentifierPart(char: string | undefined): boolean {\n return char !== undefined && /[A-Za-z0-9_$]/.test(char);\n}\n\nfunction splitTopLevelRanges(\n text: string,\n delimiter: string,\n): readonly { readonly start: number; readonly end: number }[] {\n const ranges: { start: number; end: number }[] = [];\n const scanner = createScanner();\n let start = 0;\n let angleDepth = 0;\n let parenDepth = 0;\n let bracketDepth = 0;\n let braceDepth = 0;\n for (let index = 0; index < text.length; index += 1) {\n const char = text[index];\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n if (char === \"<\") angleDepth += 1;\n else if (char === \">\") angleDepth = Math.max(0, angleDepth - 1);\n else if (char === \"(\") parenDepth += 1;\n else if (char === \")\") parenDepth = Math.max(0, parenDepth - 1);\n else if (char === \"[\") bracketDepth += 1;\n else if (char === \"]\") bracketDepth = Math.max(0, bracketDepth - 1);\n else if (char === \"{\") braceDepth += 1;\n else if (char === \"}\") braceDepth = Math.max(0, braceDepth - 1);\n else if (\n char === delimiter &&\n angleDepth === 0 &&\n parenDepth === 0 &&\n bracketDepth === 0 &&\n braceDepth === 0\n ) {\n ranges.push({ start, end: index });\n start = index + 1;\n }\n }\n ranges.push({ start, end: text.length });\n return ranges;\n}\n\nfunction createScanner(): {\n skip(text: string, index: number): number;\n} {\n let quote: string | undefined;\n let escaped = false;\n let inLineComment = false;\n let inBlockComment = false;\n return {\n skip(text, index) {\n const char = text[index];\n const next = text[index + 1];\n if (inLineComment) {\n if (char === \"\\n\" || char === \"\\r\") {\n inLineComment = false;\n }\n return index + 1;\n }\n if (inBlockComment) {\n if (char === \"*\" && next === \"/\") {\n inBlockComment = false;\n return index + 2;\n }\n return index + 1;\n }\n if (quote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === quote) {\n quote = undefined;\n }\n return index + 1;\n }\n if (char === \"/\" && next === \"/\") {\n inLineComment = true;\n return index + 2;\n }\n if (char === \"/\" && next === \"*\") {\n inBlockComment = true;\n return index + 2;\n }\n if (char === '\"' || char === \"'\" || char === \"`\") {\n quote = char;\n return index + 1;\n }\n return index;\n },\n };\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof value === \"object\" && value !== null && \"type\" in value && \"range\" in value;\n}\n\nfunction filenameFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string {\n if (\"fileName\" in node) {\n return node.fileName;\n }\n return context.filename;\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ import { oxlintCompat, oxlint_compat_d_exports } from "./oxlint_compat.js";
|
|
|
6
6
|
import { ts_utils_d_exports } from "./ts_utils.js";
|
|
7
7
|
import { utils_d_exports } from "./utils.js";
|
|
8
8
|
import { getParserServices } from "./parser_services.js";
|
|
9
|
+
import { Plugin, Rule, compatPlugin, definePlugin, defineRule } from "./plugin.js";
|
|
9
10
|
import { ESLintUtils, OxlintUtils, RuleCreator } from "./oxlint_utils.js";
|
|
10
|
-
import {
|
|
11
|
-
import { RuleTester } from "./rule_tester.js";
|
|
11
|
+
import { RuleTester, RuleTesterConfig } from "./rule_tester.js";
|
|
12
12
|
import { TSESLint } from "./ts_eslint.js";
|
|
13
13
|
import { index_d_exports } from "./rules/index.js";
|
|
14
14
|
import { ESTree as ESTree$1 } from "@oxlint/plugins";
|
|
@@ -23,5 +23,5 @@ type ESTree = {
|
|
|
23
23
|
[key: string]: unknown;
|
|
24
24
|
};
|
|
25
25
|
//#endregion
|
|
26
|
-
export { ast_utils_d_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, type ContextWithParserOptions, type CorsaNode, type CorsaOxlintSettings, type CorsaProgramShape, type CorsaRuntimeOptions, type CorsaSignature, type CorsaSymbol, type CorsaType, type CorsaTypeCheckerShape, ESLintUtils, ESTree, json_schema_d_exports as JSONSchema, oxlint_compat_d_exports as OxlintCompat, OxlintUtils, type ParserServices, type ParserServicesWithTypeInformation, type ProjectServiceOptions, RuleCreator, RuleTester, TSESLint, TSESTree, ts_utils_d_exports as TSUtils, type TypeAwareParserOptions, utils_d_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, index_d_exports as rules };
|
|
26
|
+
export { ast_utils_d_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, type ContextWithParserOptions, type CorsaNode, type CorsaOxlintSettings, type CorsaProgramShape, type CorsaRuntimeOptions, type CorsaSignature, type CorsaSymbol, type CorsaType, type CorsaTypeCheckerShape, ESLintUtils, ESTree, json_schema_d_exports as JSONSchema, oxlint_compat_d_exports as OxlintCompat, OxlintUtils, type ParserServices, type ParserServicesWithTypeInformation, type Plugin, type ProjectServiceOptions, type Rule, RuleCreator, RuleTester, type RuleTesterConfig, TSESLint, TSESTree, ts_utils_d_exports as TSUtils, type TypeAwareParserOptions, utils_d_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, index_d_exports as rules };
|
|
27
27
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/oxlint_utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ContextWithParserOptions, ParserServices } from "./types.js";
|
|
2
2
|
import { getParserServices } from "./parser_services.js";
|
|
3
|
-
import { Rule
|
|
3
|
+
import { Rule as Rule$1 } from "./plugin.js";
|
|
4
|
+
import { RuleMeta, Visitor } from "@oxlint/plugins";
|
|
4
5
|
|
|
5
6
|
//#region src/bindings/nodejs/corsa_oxlint/ts/oxlint_utils.d.ts
|
|
6
7
|
type RuleCreatorRule<TOptions extends readonly unknown[] = readonly unknown[], TMessageIds extends string = string> = {
|
|
@@ -11,7 +12,7 @@ type RuleCreatorRule<TOptions extends readonly unknown[] = readonly unknown[], T
|
|
|
11
12
|
readonly defaultOptions?: TOptions;
|
|
12
13
|
readonly create: (context: ContextWithParserOptions) => Visitor;
|
|
13
14
|
};
|
|
14
|
-
type RuleCreatorCreatedRule<TRule extends RuleCreatorRule> =
|
|
15
|
+
type RuleCreatorCreatedRule<TRule extends RuleCreatorRule> = Rule$1 & {
|
|
15
16
|
readonly defaultOptions: TRule extends {
|
|
16
17
|
readonly defaultOptions: infer TOptions;
|
|
17
18
|
} ? TOptions : readonly [];
|
|
@@ -20,7 +21,7 @@ type RuleCreatorCreatedRule<TRule extends RuleCreatorRule> = Omit<TRule, "defaul
|
|
|
20
21
|
readonly url: string;
|
|
21
22
|
};
|
|
22
23
|
};
|
|
23
|
-
}
|
|
24
|
+
};
|
|
24
25
|
type RuleCreatorFactory = <TRule extends RuleCreatorRule>(rule: TRule) => RuleCreatorCreatedRule<TRule>;
|
|
25
26
|
/**
|
|
26
27
|
* Self-hosted type-aware utilities for Oxlint rules backed by Corsa.
|
|
@@ -34,7 +35,7 @@ declare const NullThrowsReasons: Readonly<{
|
|
|
34
35
|
MissingToken: (token: string, thing: string) => string;
|
|
35
36
|
}>;
|
|
36
37
|
declare const RuleCreator: ((urlCreator: (ruleName: string) => string) => RuleCreatorFactory) & {
|
|
37
|
-
withoutDocs<TRule extends Omit<RuleCreatorRule, "name">>(rule: TRule):
|
|
38
|
+
withoutDocs<TRule extends Omit<RuleCreatorRule, "name">>(rule: TRule): Rule$1 & {
|
|
38
39
|
readonly defaultOptions: TRule extends {
|
|
39
40
|
readonly defaultOptions: infer TOptions;
|
|
40
41
|
} ? TOptions : readonly [];
|
|
@@ -50,7 +51,7 @@ declare const ESLintUtils: Readonly<{
|
|
|
50
51
|
MissingToken: (token: string, thing: string) => string;
|
|
51
52
|
}>;
|
|
52
53
|
RuleCreator: ((urlCreator: (ruleName: string) => string) => RuleCreatorFactory) & {
|
|
53
|
-
withoutDocs<TRule extends Omit<RuleCreatorRule, "name">>(rule: TRule):
|
|
54
|
+
withoutDocs<TRule extends Omit<RuleCreatorRule, "name">>(rule: TRule): Rule$1 & {
|
|
54
55
|
readonly defaultOptions: TRule extends {
|
|
55
56
|
readonly defaultOptions: infer TOptions;
|
|
56
57
|
} ? TOptions : readonly [];
|
package/dist/oxlint_utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxlint_utils.js","names":[],"sources":["../ts/oxlint_utils.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"oxlint_utils.js","names":[],"sources":["../ts/oxlint_utils.ts"],"sourcesContent":["import type { RuleMeta, Visitor } from \"@oxlint/plugins\";\n\nimport { getParserServices } from \"./parser_services\";\nimport { decorateRule } from \"./plugin\";\nimport type { Rule } from \"./plugin\";\nimport type { ContextWithParserOptions } from \"./types\";\n\nexport type RuleCreatorRule<\n TOptions extends readonly unknown[] = readonly unknown[],\n TMessageIds extends string = string,\n> = {\n readonly name: string;\n readonly meta: RuleMeta & {\n readonly messages?: Record<TMessageIds, string>;\n };\n readonly defaultOptions?: TOptions;\n readonly create: (context: ContextWithParserOptions) => Visitor;\n};\n\nexport type RuleCreatorCreatedRule<TRule extends RuleCreatorRule> = Rule & {\n readonly defaultOptions: TRule extends { readonly defaultOptions: infer TOptions }\n ? TOptions\n : readonly [];\n readonly meta: TRule[\"meta\"] & {\n readonly docs: NonNullable<TRule[\"meta\"][\"docs\"]> & {\n readonly url: string;\n };\n };\n};\n\nexport type RuleCreatorFactory = <TRule extends RuleCreatorRule>(\n rule: TRule,\n) => RuleCreatorCreatedRule<TRule>;\n\n/**\n * Self-hosted type-aware utilities for Oxlint rules backed by Corsa.\n */\nexport const OxlintUtils = Object.freeze({\n RuleCreator(urlCreator: (ruleName: string) => string): RuleCreatorFactory {\n return ((rule) => {\n const docs = rule.meta?.docs;\n return decorateRule({\n ...rule,\n meta: {\n ...rule.meta,\n docs: {\n ...docs,\n url: urlCreator(rule.name),\n },\n },\n defaultOptions: rule.defaultOptions ?? [],\n } as unknown as Rule) as RuleCreatorCreatedRule<typeof rule>;\n }) as RuleCreatorFactory;\n },\n getParserServices(context: ContextWithParserOptions, allowWithoutFullTypeInformation = false) {\n return getParserServices(context, allowWithoutFullTypeInformation);\n },\n});\n\nexport const NullThrowsReasons = Object.freeze({\n MissingParent: \"Expected node to have a parent.\",\n MissingToken: (token: string, thing: string) => `Expected to find a ${token} for the ${thing}.`,\n});\n\nexport const RuleCreator = Object.assign(OxlintUtils.RuleCreator, {\n withoutDocs<TRule extends Omit<RuleCreatorRule, \"name\">>(\n rule: TRule,\n ): Rule & {\n readonly defaultOptions: TRule extends { readonly defaultOptions: infer TOptions }\n ? TOptions\n : readonly [];\n } {\n return decorateRule({\n ...rule,\n defaultOptions: rule.defaultOptions ?? [],\n } as unknown as Rule) as never;\n },\n});\nexport { getParserServices } from \"./parser_services\";\n\nexport function applyDefault<User extends readonly unknown[], Defaults extends readonly unknown[]>(\n defaultOptions: Defaults,\n userOptions: User | null | undefined,\n): readonly unknown[] {\n const options = structuredClone(defaultOptions) as unknown as unknown[];\n if (userOptions == null) {\n return options;\n }\n options.forEach((option, index) => {\n if (userOptions[index] === undefined) {\n return;\n }\n const userOption = userOptions[index];\n options[index] =\n isObjectNotArray(option) && isObjectNotArray(userOption)\n ? deepMerge(option, userOption)\n : userOption;\n });\n return options;\n}\n\nexport function deepMerge<T>(base: T, override: unknown): T {\n if (isObject(base) && isObject(override)) {\n return Object.fromEntries(\n [...new Set([...Object.keys(base), ...Object.keys(override)])].map((key) => [\n key,\n key in base && key in override\n ? deepMerge((base as any)[key], (override as any)[key])\n : key in base\n ? (base as any)[key]\n : (override as any)[key],\n ]),\n ) as T;\n }\n return (override === undefined ? base : override) as T;\n}\n\nexport function nullThrows<T>(\n value: T | null | undefined,\n message = \"Expected value to be present\",\n): T {\n if (value == null) {\n throw new Error(`Non-null Assertion Failed: ${message}`);\n }\n return value;\n}\n\nexport function isObjectNotArray(value: unknown): value is Record<string, unknown> {\n return isObject(value);\n}\n\nexport const ESLintUtils = Object.freeze({\n NullThrowsReasons,\n RuleCreator,\n applyDefault,\n deepMerge,\n getParserServices,\n isObjectNotArray,\n nullThrows,\n});\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";;;;;;AAqCA,MAAa,cAAc,OAAO,OAAO;CACvC,YAAY,YAA8D;EACxE,SAAS,SAAS;GAChB,MAAM,OAAO,KAAK,MAAM;GACxB,OAAO,aAAa;IAClB,GAAG;IACH,MAAM;KACJ,GAAG,KAAK;KACR,MAAM;MACJ,GAAG;MACH,KAAK,WAAW,KAAK,KAAK;MAC3B;KACF;IACD,gBAAgB,KAAK,kBAAkB,EAAE;IAC1C,CAAoB;;;CAGzB,kBAAkB,SAAmC,kCAAkC,OAAO;EAC5F,OAAO,kBAAkB,SAAS,gCAAgC;;CAErE,CAAC;AAEF,MAAa,oBAAoB,OAAO,OAAO;CAC7C,eAAe;CACf,eAAe,OAAe,UAAkB,sBAAsB,MAAM,WAAW,MAAM;CAC9F,CAAC;AAEF,MAAa,cAAc,OAAO,OAAO,YAAY,aAAa,EAChE,YACE,MAKA;CACA,OAAO,aAAa;EAClB,GAAG;EACH,gBAAgB,KAAK,kBAAkB,EAAE;EAC1C,CAAoB;GAExB,CAAC;AAGF,SAAgB,aACd,gBACA,aACoB;CACpB,MAAM,UAAU,gBAAgB,eAAe;CAC/C,IAAI,eAAe,MACjB,OAAO;CAET,QAAQ,SAAS,QAAQ,UAAU;EACjC,IAAI,YAAY,WAAW,KAAA,GACzB;EAEF,MAAM,aAAa,YAAY;EAC/B,QAAQ,SACN,iBAAiB,OAAO,IAAI,iBAAiB,WAAW,GACpD,UAAU,QAAQ,WAAW,GAC7B;GACN;CACF,OAAO;;AAGT,SAAgB,UAAa,MAAS,UAAsB;CAC1D,IAAI,SAAS,KAAK,IAAI,SAAS,SAAS,EACtC,OAAO,OAAO,YACZ,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAC1E,KACA,OAAO,QAAQ,OAAO,WAClB,UAAW,KAAa,MAAO,SAAiB,KAAK,GACrD,OAAO,OACJ,KAAa,OACb,SAAiB,KACzB,CAAC,CACH;CAEH,OAAQ,aAAa,KAAA,IAAY,OAAO;;AAG1C,SAAgB,WACd,OACA,UAAU,gCACP;CACH,IAAI,SAAS,MACX,MAAM,IAAI,MAAM,8BAA8B,UAAU;CAE1D,OAAO;;AAGT,SAAgB,iBAAiB,OAAkD;CACjF,OAAO,SAAS,MAAM;;AAGxB,MAAa,cAAc,OAAO,OAAO;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
package/dist/parser_services.js
CHANGED
|
@@ -51,9 +51,9 @@ function getParserServices(context, allowWithoutFullTypeInformation = false) {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
function createEslintParserServices(parserServices) {
|
|
54
|
-
const checker = parserServices.program.getTypeChecker();
|
|
54
|
+
const checker = createEslintTypeChecker(parserServices.program.getTypeChecker(), parserServices.esTreeNodeToTSNodeMap);
|
|
55
55
|
return {
|
|
56
|
-
program: parserServices.program,
|
|
56
|
+
program: createEslintProgram(parserServices.program, checker),
|
|
57
57
|
esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,
|
|
58
58
|
tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,
|
|
59
59
|
hasFullTypeInformation: true,
|
|
@@ -67,6 +67,148 @@ function createEslintParserServices(parserServices) {
|
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
+
function createEslintProgram(program, checker) {
|
|
71
|
+
return Object.assign(Object.create(program), { getTypeChecker() {
|
|
72
|
+
return checker;
|
|
73
|
+
} });
|
|
74
|
+
}
|
|
75
|
+
function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
|
|
76
|
+
const source = checker;
|
|
77
|
+
return {
|
|
78
|
+
...checker,
|
|
79
|
+
getTypeAtLocation(node) {
|
|
80
|
+
return callChecker(source, "getTypeAtLocation", tsNodeFor(node, esTreeNodeToTSNodeMap));
|
|
81
|
+
},
|
|
82
|
+
getContextualType(node) {
|
|
83
|
+
return callChecker(source, "getContextualType", tsNodeFor(node, esTreeNodeToTSNodeMap)) ?? this.getTypeAtLocation(node);
|
|
84
|
+
},
|
|
85
|
+
getSymbolAtLocation(node) {
|
|
86
|
+
return callChecker(source, "getSymbolAtLocation", tsNodeFor(node, esTreeNodeToTSNodeMap));
|
|
87
|
+
},
|
|
88
|
+
getSymbol(symbol) {
|
|
89
|
+
return typeof symbol === "object" ? symbol : void 0;
|
|
90
|
+
},
|
|
91
|
+
getSymbolById(id) {
|
|
92
|
+
return typeof id === "object" ? id : void 0;
|
|
93
|
+
},
|
|
94
|
+
getNode(node) {
|
|
95
|
+
return typeof node === "object" ? node : void 0;
|
|
96
|
+
},
|
|
97
|
+
getNodeById(id) {
|
|
98
|
+
return typeof id === "object" ? id : void 0;
|
|
99
|
+
},
|
|
100
|
+
getTypeOfSymbol(symbol) {
|
|
101
|
+
return callChecker(source, "getTypeOfSymbol", symbol);
|
|
102
|
+
},
|
|
103
|
+
getDeclaredTypeOfSymbol(symbol) {
|
|
104
|
+
return callChecker(source, "getDeclaredTypeOfSymbol", symbol);
|
|
105
|
+
},
|
|
106
|
+
getTypeOfSymbolAtLocation(symbol, node) {
|
|
107
|
+
return callChecker(source, "getTypeOfSymbolAtLocation", symbol, tsNodeFor(node, esTreeNodeToTSNodeMap)) ?? this.getTypeOfSymbol(symbol) ?? this.getDeclaredTypeOfSymbol(symbol);
|
|
108
|
+
},
|
|
109
|
+
typeToString(type, enclosingDeclaration, flags) {
|
|
110
|
+
return callChecker(source, "typeToString", type, enclosingDeclaration ? tsNodeFor(enclosingDeclaration, esTreeNodeToTSNodeMap) : void 0, flags) ?? fallbackTypeText(type);
|
|
111
|
+
},
|
|
112
|
+
getBaseTypeOfLiteralType(type) {
|
|
113
|
+
return callChecker(source, "getBaseTypeOfLiteralType", type) ?? type;
|
|
114
|
+
},
|
|
115
|
+
getPropertiesOfType(type) {
|
|
116
|
+
return asReadonlyArray(callChecker(source, "getPropertiesOfType", type));
|
|
117
|
+
},
|
|
118
|
+
getSignaturesOfType(type, kind) {
|
|
119
|
+
return asReadonlyArray(callChecker(source, "getSignaturesOfType", type, kind));
|
|
120
|
+
},
|
|
121
|
+
getReturnTypeOfSignature(signature) {
|
|
122
|
+
return callChecker(source, "getReturnTypeOfSignature", signature);
|
|
123
|
+
},
|
|
124
|
+
getTypePredicateOfSignature(signature) {
|
|
125
|
+
return callChecker(source, "getTypePredicateOfSignature", signature);
|
|
126
|
+
},
|
|
127
|
+
getBaseTypes(type) {
|
|
128
|
+
const baseTypes = asReadonlyArray(callChecker(source, "getBaseTypes", type));
|
|
129
|
+
return baseTypes.length > 0 ? baseTypes : heritageTypes(type, source, "extends");
|
|
130
|
+
},
|
|
131
|
+
getImplementedTypes(node) {
|
|
132
|
+
return heritageTypesFromDeclaration(tsNodeFor(node, esTreeNodeToTSNodeMap), source, "implements");
|
|
133
|
+
},
|
|
134
|
+
getImplementedTypesOfType(type) {
|
|
135
|
+
return heritageTypes(type, source, "implements");
|
|
136
|
+
},
|
|
137
|
+
getTypeArguments(type) {
|
|
138
|
+
return asReadonlyArray(callChecker(source, "getTypeArguments", type));
|
|
139
|
+
},
|
|
140
|
+
getTypesOfType(type) {
|
|
141
|
+
return asReadonlyArray(type.types);
|
|
142
|
+
},
|
|
143
|
+
getTargetOfType(type) {
|
|
144
|
+
return type.target;
|
|
145
|
+
},
|
|
146
|
+
getTypeParametersOfType(type) {
|
|
147
|
+
return asReadonlyArray(type.typeParameters);
|
|
148
|
+
},
|
|
149
|
+
getOuterTypeParametersOfType(type) {
|
|
150
|
+
return asReadonlyArray(type.outerTypeParameters);
|
|
151
|
+
},
|
|
152
|
+
getLocalTypeParametersOfType(type) {
|
|
153
|
+
return asReadonlyArray(type.localTypeParameters);
|
|
154
|
+
},
|
|
155
|
+
getObjectTypeOfType(type) {
|
|
156
|
+
return type.objectType;
|
|
157
|
+
},
|
|
158
|
+
getIndexTypeOfType(type) {
|
|
159
|
+
return type.indexType;
|
|
160
|
+
},
|
|
161
|
+
getCheckTypeOfType(type) {
|
|
162
|
+
return type.checkType;
|
|
163
|
+
},
|
|
164
|
+
getExtendsTypeOfType(type) {
|
|
165
|
+
return type.extendsType;
|
|
166
|
+
},
|
|
167
|
+
getBaseTypeOfType(type) {
|
|
168
|
+
return type.baseType;
|
|
169
|
+
},
|
|
170
|
+
getConstraintOfType(type) {
|
|
171
|
+
return callChecker(source, "getBaseConstraintOfType", type);
|
|
172
|
+
},
|
|
173
|
+
isUnionType(type) {
|
|
174
|
+
const value = type;
|
|
175
|
+
return typeof value.isUnion === "function" ? Boolean(value.isUnion()) : false;
|
|
176
|
+
},
|
|
177
|
+
isIntersectionType(type) {
|
|
178
|
+
const value = type;
|
|
179
|
+
return typeof value.isIntersection === "function" ? Boolean(value.isIntersection()) : false;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function callChecker(checker, method, ...args) {
|
|
184
|
+
const candidate = checker[method];
|
|
185
|
+
return typeof candidate === "function" ? candidate.apply(checker, args) : void 0;
|
|
186
|
+
}
|
|
187
|
+
function asReadonlyArray(value) {
|
|
188
|
+
return Array.isArray(value) ? value : [];
|
|
189
|
+
}
|
|
190
|
+
function tsNodeFor(node, esTreeNodeToTSNodeMap) {
|
|
191
|
+
return hasNode(esTreeNodeToTSNodeMap, node) ? esTreeNodeToTSNodeMap.get(node) : node;
|
|
192
|
+
}
|
|
193
|
+
function hasNode(esTreeNodeToTSNodeMap, node) {
|
|
194
|
+
return typeof node === "object" && node !== null && esTreeNodeToTSNodeMap.has(node);
|
|
195
|
+
}
|
|
196
|
+
function fallbackTypeText(type) {
|
|
197
|
+
const name = type.name;
|
|
198
|
+
return typeof name === "string" || typeof name === "number" || typeof name === "boolean" ? String(name) : "";
|
|
199
|
+
}
|
|
200
|
+
function heritageTypes(type, checker, keyword) {
|
|
201
|
+
return asReadonlyArray(type.symbol?.declarations).flatMap((declaration) => heritageTypesFromDeclaration(declaration, checker, keyword));
|
|
202
|
+
}
|
|
203
|
+
function heritageTypesFromDeclaration(declaration, checker, keyword) {
|
|
204
|
+
return asReadonlyArray(declaration.heritageClauses).filter((clause) => heritageClauseText(clause).trimStart().startsWith(keyword)).flatMap((clause) => asReadonlyArray(clause.types)).map((node) => {
|
|
205
|
+
return callChecker(checker, "getTypeAtLocation", node.expression ?? node);
|
|
206
|
+
}).filter((type) => type !== void 0);
|
|
207
|
+
}
|
|
208
|
+
function heritageClauseText(clause) {
|
|
209
|
+
const getText = clause.getText;
|
|
210
|
+
return typeof getText === "function" ? String(getText.call(clause)) : "";
|
|
211
|
+
}
|
|
70
212
|
function resolveEslintParserServices(context) {
|
|
71
213
|
const candidates = [context.parserServices, context.sourceCode.parserServices];
|
|
72
214
|
for (const candidate of candidates) if (hasEslintParserServices(candidate)) return candidate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser_services.js","names":[],"sources":["../ts/parser_services.ts"],"sourcesContent":["import { createProgram, createTypeChecker } from \"./checker\";\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { createNodeMaps } from \"./node_map\";\nimport type {\n ContextWithParserOptions,\n ParserServices,\n ParserServicesWithTypeInformation,\n} from \"./types\";\n\nconst parserServices = new WeakMap<object, ParserServices>();\n\n/**\n * Returns type-aware parser services backed by Corsa.\n *\n * @example\n * ```ts\n * const services = getParserServices(context);\n * const checker = services.program.getTypeChecker();\n * ```\n */\nexport function getParserServices(\n context: ContextWithParserOptions,\n allowWithoutFullTypeInformation = false,\n): ParserServices {\n const current = parserServices.get(context);\n if (current) {\n return current;\n }\n const parserOptions = resolveTypeAwareParserOptions(context);\n const eslintParserServices = resolveEslintParserServices(context);\n if (!parserOptions.corsa && eslintParserServices) {\n const services = createEslintParserServices(eslintParserServices);\n parserServices.set(context, services);\n return services;\n }\n try {\n const maps = createNodeMaps(context);\n const program = createProgram(context);\n const services: ParserServicesWithTypeInformation = {\n program,\n ...maps,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n return createTypeChecker(context).getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n return createTypeChecker(context).getSymbolAtLocation(node);\n },\n };\n parserServices.set(context, services);\n return services;\n } catch (error) {\n if (!allowWithoutFullTypeInformation) {\n throw error;\n }\n const fallback: ParserServices = {\n program: createProgram(context),\n ...createNodeMaps(context),\n hasFullTypeInformation: false,\n getTypeAtLocation() {\n return undefined;\n },\n getSymbolAtLocation() {\n return undefined;\n },\n };\n parserServices.set(context, fallback);\n return fallback;\n }\n}\n\nfunction createEslintParserServices(\n parserServices: ParserServices,\n): ParserServicesWithTypeInformation {\n const checker = parserServices.program.getTypeChecker();\n return {\n program: parserServices.program,\n esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,\n tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getTypeAtLocation(tsNode) : undefined;\n },\n getSymbolAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getSymbolAtLocation(tsNode) : undefined;\n },\n };\n}\n\nfunction resolveEslintParserServices(\n context: ContextWithParserOptions,\n): ParserServices | undefined {\n const candidates = [context.parserServices, context.sourceCode.parserServices] as const;\n for (const candidate of candidates) {\n if (hasEslintParserServices(candidate)) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction hasEslintParserServices(value: unknown): value is ParserServices {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n \"program\" in value &&\n \"esTreeNodeToTSNodeMap\" in value &&\n \"tsNodeToESTreeNodeMap\" in value,\n );\n}\n"],"mappings":";;;;AASA,MAAM,iCAAiB,IAAI,SAAiC;;;;;;;;;;AAW5D,SAAgB,kBACd,SACA,kCAAkC,OAClB;CAChB,MAAM,UAAU,eAAe,IAAI,QAAQ;CAC3C,IAAI,SACF,OAAO;CAET,MAAM,gBAAgB,8BAA8B,QAAQ;CAC5D,MAAM,uBAAuB,4BAA4B,QAAQ;CACjE,IAAI,CAAC,cAAc,SAAS,sBAAsB;EAChD,MAAM,WAAW,2BAA2B,qBAAqB;EACjE,eAAe,IAAI,SAAS,SAAS;EACrC,OAAO;;CAET,IAAI;EACF,MAAM,OAAO,eAAe,QAAQ;EAEpC,MAAM,WAA8C;GAClD,SAFc,cAAc,QAErB;GACP,GAAG;GACH,wBAAwB;GACxB,kBAAkB,MAAM;IACtB,OAAO,kBAAkB,QAAQ,CAAC,kBAAkB,KAAK;;GAE3D,oBAAoB,MAAM;IACxB,OAAO,kBAAkB,QAAQ,CAAC,oBAAoB,KAAK;;GAE9D;EACD,eAAe,IAAI,SAAS,SAAS;EACrC,OAAO;UACA,OAAO;EACd,IAAI,CAAC,iCACH,MAAM;EAER,MAAM,WAA2B;GAC/B,SAAS,cAAc,QAAQ;GAC/B,GAAG,eAAe,QAAQ;GAC1B,wBAAwB;GACxB,oBAAoB;GAGpB,sBAAsB;GAGvB;EACD,eAAe,IAAI,SAAS,SAAS;EACrC,OAAO;;;AAIX,SAAS,2BACP,gBACmC;CACnC,MAAM,UAAU,eAAe,QAAQ,gBAAgB;CACvD,OAAO;EACL,SAAS,eAAe;EACxB,uBAAuB,eAAe;EACtC,uBAAuB,eAAe;EACtC,wBAAwB;EACxB,kBAAkB,MAAM;GACtB,MAAM,SAAS,eAAe,sBAAsB,IAAI,KAAK;GAC7D,OAAO,SAAS,QAAQ,kBAAkB,OAAO,GAAG,KAAA;;EAEtD,oBAAoB,MAAM;GACxB,MAAM,SAAS,eAAe,sBAAsB,IAAI,KAAK;GAC7D,OAAO,SAAS,QAAQ,oBAAoB,OAAO,GAAG,KAAA;;EAEzD;;AAGH,SAAS,4BACP,SAC4B;CAC5B,MAAM,aAAa,CAAC,QAAQ,gBAAgB,QAAQ,WAAW,eAAe;CAC9E,KAAK,MAAM,aAAa,YACtB,IAAI,wBAAwB,UAAU,EACpC,OAAO;;AAMb,SAAS,wBAAwB,OAAyC;CACxE,OAAO,QACL,SACA,OAAO,UAAU,YACjB,aAAa,SACb,2BAA2B,SAC3B,2BAA2B,MAC5B"}
|
|
1
|
+
{"version":3,"file":"parser_services.js","names":[],"sources":["../ts/parser_services.ts"],"sourcesContent":["import { createProgram, createTypeChecker } from \"./checker\";\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { createNodeMaps } from \"./node_map\";\nimport type {\n ContextWithParserOptions,\n CorsaTypeCheckerShape,\n ParserServices,\n ParserServicesWithTypeInformation,\n} from \"./types\";\n\nconst parserServices = new WeakMap<object, ParserServices>();\n\n/**\n * Returns type-aware parser services backed by Corsa.\n *\n * @example\n * ```ts\n * const services = getParserServices(context);\n * const checker = services.program.getTypeChecker();\n * ```\n */\nexport function getParserServices(\n context: ContextWithParserOptions,\n allowWithoutFullTypeInformation = false,\n): ParserServices {\n const current = parserServices.get(context);\n if (current) {\n return current;\n }\n const parserOptions = resolveTypeAwareParserOptions(context);\n const eslintParserServices = resolveEslintParserServices(context);\n if (!parserOptions.corsa && eslintParserServices) {\n const services = createEslintParserServices(eslintParserServices);\n parserServices.set(context, services);\n return services;\n }\n try {\n const maps = createNodeMaps(context);\n const program = createProgram(context);\n const services: ParserServicesWithTypeInformation = {\n program,\n ...maps,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n return createTypeChecker(context).getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n return createTypeChecker(context).getSymbolAtLocation(node);\n },\n };\n parserServices.set(context, services);\n return services;\n } catch (error) {\n if (!allowWithoutFullTypeInformation) {\n throw error;\n }\n const fallback: ParserServices = {\n program: createProgram(context),\n ...createNodeMaps(context),\n hasFullTypeInformation: false,\n getTypeAtLocation() {\n return undefined;\n },\n getSymbolAtLocation() {\n return undefined;\n },\n };\n parserServices.set(context, fallback);\n return fallback;\n }\n}\n\nfunction createEslintParserServices(\n parserServices: ParserServices,\n): ParserServicesWithTypeInformation {\n const checker = createEslintTypeChecker(\n parserServices.program.getTypeChecker(),\n parserServices.esTreeNodeToTSNodeMap,\n );\n return {\n program: createEslintProgram(parserServices.program, checker),\n esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,\n tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getTypeAtLocation(tsNode) : undefined;\n },\n getSymbolAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getSymbolAtLocation(tsNode) : undefined;\n },\n };\n}\n\nfunction createEslintProgram(\n program: ParserServices[\"program\"],\n checker: CorsaTypeCheckerShape,\n): ParserServices[\"program\"] {\n return Object.assign(Object.create(program), {\n getTypeChecker() {\n return checker;\n },\n });\n}\n\nfunction createEslintTypeChecker(\n checker: CorsaTypeCheckerShape,\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n): CorsaTypeCheckerShape {\n const source = checker as unknown as Record<string, unknown>;\n return {\n ...checker,\n getTypeAtLocation(node) {\n return callChecker(source, \"getTypeAtLocation\", tsNodeFor(node, esTreeNodeToTSNodeMap));\n },\n getContextualType(node) {\n return (\n callChecker(source, \"getContextualType\", tsNodeFor(node, esTreeNodeToTSNodeMap)) ??\n this.getTypeAtLocation(node)\n );\n },\n getSymbolAtLocation(node) {\n return callChecker(source, \"getSymbolAtLocation\", tsNodeFor(node, esTreeNodeToTSNodeMap));\n },\n getSymbol(symbol) {\n return typeof symbol === \"object\" ? symbol : undefined;\n },\n getSymbolById(id) {\n return typeof id === \"object\" ? id : undefined;\n },\n getNode(node) {\n return typeof node === \"object\" ? node : undefined;\n },\n getNodeById(id) {\n return typeof id === \"object\" ? id : undefined;\n },\n getTypeOfSymbol(symbol) {\n return callChecker(source, \"getTypeOfSymbol\", symbol);\n },\n getDeclaredTypeOfSymbol(symbol) {\n return callChecker(source, \"getDeclaredTypeOfSymbol\", symbol);\n },\n getTypeOfSymbolAtLocation(symbol, node) {\n return (\n callChecker(\n source,\n \"getTypeOfSymbolAtLocation\",\n symbol,\n tsNodeFor(node, esTreeNodeToTSNodeMap),\n ) ??\n this.getTypeOfSymbol(symbol) ??\n this.getDeclaredTypeOfSymbol(symbol)\n );\n },\n typeToString(type, enclosingDeclaration, flags) {\n return (\n callChecker(\n source,\n \"typeToString\",\n type,\n enclosingDeclaration ? tsNodeFor(enclosingDeclaration, esTreeNodeToTSNodeMap) : undefined,\n flags,\n ) ?? fallbackTypeText(type)\n );\n },\n getBaseTypeOfLiteralType(type) {\n return callChecker(source, \"getBaseTypeOfLiteralType\", type) ?? type;\n },\n getPropertiesOfType(type) {\n return asReadonlyArray(callChecker(source, \"getPropertiesOfType\", type));\n },\n getSignaturesOfType(type, kind) {\n return asReadonlyArray(callChecker(source, \"getSignaturesOfType\", type, kind));\n },\n getReturnTypeOfSignature(signature) {\n return callChecker(source, \"getReturnTypeOfSignature\", signature);\n },\n getTypePredicateOfSignature(signature) {\n return callChecker(source, \"getTypePredicateOfSignature\", signature);\n },\n getBaseTypes(type) {\n const baseTypes = asReadonlyArray(callChecker(source, \"getBaseTypes\", type));\n return baseTypes.length > 0 ? baseTypes : heritageTypes(type, source, \"extends\");\n },\n getImplementedTypes(node) {\n return heritageTypesFromDeclaration(\n tsNodeFor(node, esTreeNodeToTSNodeMap),\n source,\n \"implements\",\n );\n },\n getImplementedTypesOfType(type) {\n return heritageTypes(type, source, \"implements\");\n },\n getTypeArguments(type) {\n return asReadonlyArray(callChecker(source, \"getTypeArguments\", type));\n },\n getTypesOfType(type) {\n return asReadonlyArray((type as { readonly types?: unknown }).types);\n },\n getTargetOfType(type) {\n return (type as { readonly target?: unknown }).target as never;\n },\n getTypeParametersOfType(type) {\n return asReadonlyArray((type as { readonly typeParameters?: unknown }).typeParameters);\n },\n getOuterTypeParametersOfType(type) {\n return asReadonlyArray(\n (type as { readonly outerTypeParameters?: unknown }).outerTypeParameters,\n );\n },\n getLocalTypeParametersOfType(type) {\n return asReadonlyArray(\n (type as { readonly localTypeParameters?: unknown }).localTypeParameters,\n );\n },\n getObjectTypeOfType(type) {\n return (type as { readonly objectType?: unknown }).objectType as never;\n },\n getIndexTypeOfType(type) {\n return (type as { readonly indexType?: unknown }).indexType as never;\n },\n getCheckTypeOfType(type) {\n return (type as { readonly checkType?: unknown }).checkType as never;\n },\n getExtendsTypeOfType(type) {\n return (type as { readonly extendsType?: unknown }).extendsType as never;\n },\n getBaseTypeOfType(type) {\n return (type as { readonly baseType?: unknown }).baseType as never;\n },\n getConstraintOfType(type) {\n return callChecker(source, \"getBaseConstraintOfType\", type);\n },\n isUnionType(type) {\n const value = type as { readonly isUnion?: unknown };\n return typeof value.isUnion === \"function\" ? Boolean(value.isUnion()) : false;\n },\n isIntersectionType(type) {\n const value = type as { readonly isIntersection?: unknown };\n return typeof value.isIntersection === \"function\" ? Boolean(value.isIntersection()) : false;\n },\n } as CorsaTypeCheckerShape;\n}\n\nfunction callChecker(\n checker: Record<string, unknown>,\n method: string,\n ...args: readonly unknown[]\n): never | undefined {\n const candidate = checker[method];\n return typeof candidate === \"function\" ? candidate.apply(checker, args) : undefined;\n}\n\nfunction asReadonlyArray<T>(value: unknown): readonly T[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction tsNodeFor(\n node: unknown,\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n): unknown {\n return hasNode(esTreeNodeToTSNodeMap, node) ? esTreeNodeToTSNodeMap.get(node as never) : node;\n}\n\nfunction hasNode(\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n node: unknown,\n): boolean {\n return typeof node === \"object\" && node !== null && esTreeNodeToTSNodeMap.has(node as never);\n}\n\nfunction fallbackTypeText(type: unknown): string {\n const name = (type as { readonly name?: unknown }).name;\n return typeof name === \"string\" || typeof name === \"number\" || typeof name === \"boolean\"\n ? String(name)\n : \"\";\n}\n\nfunction heritageTypes(\n type: unknown,\n checker: Record<string, unknown>,\n keyword: \"extends\" | \"implements\",\n): readonly never[] {\n const declarations = asReadonlyArray(\n (type as { readonly symbol?: { readonly declarations?: unknown } }).symbol?.declarations,\n );\n return declarations.flatMap((declaration) =>\n heritageTypesFromDeclaration(declaration, checker, keyword),\n );\n}\n\nfunction heritageTypesFromDeclaration(\n declaration: unknown,\n checker: Record<string, unknown>,\n keyword: \"extends\" | \"implements\",\n): readonly never[] {\n const clauses = asReadonlyArray(\n (declaration as { readonly heritageClauses?: unknown }).heritageClauses,\n );\n return clauses\n .filter((clause) => heritageClauseText(clause).trimStart().startsWith(keyword))\n .flatMap((clause) => asReadonlyArray((clause as { readonly types?: unknown }).types))\n .map((node) => {\n const expression = (node as { readonly expression?: unknown }).expression ?? node;\n return callChecker(checker, \"getTypeAtLocation\", expression);\n })\n .filter((type): type is never => type !== undefined);\n}\n\nfunction heritageClauseText(clause: unknown): string {\n const getText = (clause as { readonly getText?: unknown }).getText;\n return typeof getText === \"function\" ? String(getText.call(clause)) : \"\";\n}\n\nfunction resolveEslintParserServices(\n context: ContextWithParserOptions,\n): ParserServices | undefined {\n const candidates = [context.parserServices, context.sourceCode.parserServices] as const;\n for (const candidate of candidates) {\n if (hasEslintParserServices(candidate)) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction hasEslintParserServices(value: unknown): value is ParserServices {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n \"program\" in value &&\n \"esTreeNodeToTSNodeMap\" in value &&\n \"tsNodeToESTreeNodeMap\" in value,\n );\n}\n"],"mappings":"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"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { Plugin, Rule } from "@oxlint/plugins";
|
|
1
|
+
import { Plugin as Plugin$1, Rule as Rule$1 } from "@oxlint/plugins";
|
|
2
2
|
|
|
3
3
|
//#region src/bindings/nodejs/corsa_oxlint/ts/plugin.d.ts
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
type Plugin = Omit<Plugin$1, "rules"> & {
|
|
5
|
+
readonly rules: Record<string, Rule>;
|
|
6
|
+
} & Record<string, unknown>;
|
|
7
|
+
type Rule = Rule$1 & Record<string, unknown>;
|
|
8
|
+
declare function definePlugin(plugin: Plugin): Plugin;
|
|
7
9
|
/**
|
|
8
10
|
* Defines a single Oxlint rule with type-aware parser services.
|
|
9
11
|
*
|
|
@@ -18,9 +20,9 @@ declare function definePlugin<Plugin extends PluginShape>(plugin: Plugin): Plugi
|
|
|
18
20
|
* });
|
|
19
21
|
* ```
|
|
20
22
|
*/
|
|
21
|
-
declare function defineRule
|
|
22
|
-
declare function compatPlugin
|
|
23
|
-
declare function decorateRule
|
|
23
|
+
declare function defineRule(rule: Rule): Rule;
|
|
24
|
+
declare function compatPlugin(plugin: Plugin): Plugin;
|
|
25
|
+
declare function decorateRule(rule: Rule): Rule;
|
|
24
26
|
//#endregion
|
|
25
|
-
export { compatPlugin, decorateRule, definePlugin, defineRule };
|
|
27
|
+
export { Plugin, Rule, compatPlugin, decorateRule, definePlugin, defineRule };
|
|
26
28
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../ts/plugin.ts"],"sourcesContent":["import * as oxlintPluginApi from \"@oxlint/plugins\";\nimport type {\n Context as OxlintContext,\n Plugin as OxlintPlugin,\n Rule as OxlintRule,\n} from \"@oxlint/plugins\";\n\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { getParserServices } from \"./parser_services\";\nimport type { ContextWithParserOptions, ParserServices } from \"./types\";\n\
|
|
1
|
+
{"version":3,"file":"plugin.js","names":[],"sources":["../ts/plugin.ts"],"sourcesContent":["import * as oxlintPluginApi from \"@oxlint/plugins\";\nimport type {\n Context as OxlintContext,\n Plugin as OxlintPlugin,\n Rule as OxlintRule,\n} from \"@oxlint/plugins\";\n\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { getParserServices } from \"./parser_services\";\nimport type { ContextWithParserOptions, ParserServices } from \"./types\";\n\nexport type Plugin = Omit<OxlintPlugin, \"rules\"> & {\n readonly rules: Record<string, Rule>;\n} & Record<string, unknown>;\nexport type Rule = OxlintRule & Record<string, unknown>;\n\nconst defineOxlintPlugin = oxlintPluginApi.definePlugin;\nconst defineOxlintRule = oxlintPluginApi.defineRule;\nconst baseCompatPlugin = Reflect.get(\n oxlintPluginApi as object,\n [\"es\", \"lintCompatPlugin\"].join(\"\"),\n) as typeof oxlintPluginApi.definePlugin;\n\nexport function definePlugin(plugin: Plugin): Plugin {\n return defineOxlintPlugin({\n ...plugin,\n rules: wrapRules(plugin.rules ?? {}),\n } as OxlintPlugin) as Plugin;\n}\n\n/**\n * Defines a single Oxlint rule with type-aware parser services.\n *\n * @example\n * ```ts\n * export default defineRule({\n * meta: { schema: [], messages: { demo: \"demo\" } },\n * create(context) {\n * const services = context.parserServices;\n * return {};\n * },\n * });\n * ```\n */\nexport function defineRule(rule: Rule): Rule {\n return defineOxlintRule(decorateRule(rule) as OxlintRule) as Rule;\n}\n\nexport function compatPlugin(plugin: Plugin): Plugin {\n return baseCompatPlugin(definePlugin(plugin)) as Plugin;\n}\n\nexport function decorateRule(rule: Rule): Rule {\n if (rule.create) {\n return {\n ...rule,\n create(context) {\n return rule.create!(decorateContext(context));\n },\n } as Rule;\n }\n if (\"createOnce\" in rule && typeof (rule as any).createOnce === \"function\") {\n return {\n ...rule,\n createOnce(context) {\n return (rule as any).createOnce(decorateContext(context));\n },\n } as Rule;\n }\n return rule;\n}\n\nfunction wrapRules(rules: Record<string, Rule>): Record<string, Rule> {\n return Object.fromEntries(\n Object.entries(rules).map(([name, rule]) => [name, decorateRule(rule)]),\n );\n}\n\nfunction decorateContext(context: ContextWithParserOptions): ContextWithParserOptions {\n const parserOptions = Object.freeze(resolveTypeAwareParserOptions(context));\n const baseLanguageOptions = context.languageOptions;\n const languageOptions = Object.freeze({\n ...baseLanguageOptions,\n parserOptions,\n });\n return Object.create(context as OxlintContext, {\n languageOptions: {\n configurable: true,\n enumerable: true,\n get() {\n return languageOptions;\n },\n },\n parserOptions: {\n configurable: true,\n enumerable: false,\n get() {\n return parserOptions;\n },\n },\n parserServices: {\n configurable: true,\n enumerable: false,\n get(): ParserServices {\n return getParserServices(context);\n },\n },\n }) as ContextWithParserOptions;\n}\n"],"mappings":";;;;AAgBA,MAAM,qBAAqB,gBAAgB;AAC3C,MAAM,mBAAmB,gBAAgB;AACzC,MAAM,mBAAmB,QAAQ,IAC/B,iBACA,CAAC,MAAM,mBAAmB,CAAC,KAAK,GAAG,CACpC;AAED,SAAgB,aAAa,QAAwB;CACnD,OAAO,mBAAmB;EACxB,GAAG;EACH,OAAO,UAAU,OAAO,SAAS,EAAE,CAAC;EACrC,CAAiB;;;;;;;;;;;;;;;;AAiBpB,SAAgB,WAAW,MAAkB;CAC3C,OAAO,iBAAiB,aAAa,KAAK,CAAe;;AAG3D,SAAgB,aAAa,QAAwB;CACnD,OAAO,iBAAiB,aAAa,OAAO,CAAC;;AAG/C,SAAgB,aAAa,MAAkB;CAC7C,IAAI,KAAK,QACP,OAAO;EACL,GAAG;EACH,OAAO,SAAS;GACd,OAAO,KAAK,OAAQ,gBAAgB,QAAQ,CAAC;;EAEhD;CAEH,IAAI,gBAAgB,QAAQ,OAAQ,KAAa,eAAe,YAC9D,OAAO;EACL,GAAG;EACH,WAAW,SAAS;GAClB,OAAQ,KAAa,WAAW,gBAAgB,QAAQ,CAAC;;EAE5D;CAEH,OAAO;;AAGT,SAAS,UAAU,OAAmD;CACpE,OAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM,aAAa,KAAK,CAAC,CAAC,CACxE;;AAGH,SAAS,gBAAgB,SAA6D;CACpF,MAAM,gBAAgB,OAAO,OAAO,8BAA8B,QAAQ,CAAC;CAC3E,MAAM,sBAAsB,QAAQ;CACpC,MAAM,kBAAkB,OAAO,OAAO;EACpC,GAAG;EACH;EACD,CAAC;CACF,OAAO,OAAO,OAAO,SAA0B;EAC7C,iBAAiB;GACf,cAAc;GACd,YAAY;GACZ,MAAM;IACJ,OAAO;;GAEV;EACD,eAAe;GACb,cAAc;GACd,YAAY;GACZ,MAAM;IACJ,OAAO;;GAEV;EACD,gBAAgB;GACd,cAAc;GACd,YAAY;GACZ,MAAsB;IACpB,OAAO,kBAAkB,QAAQ;;GAEpC;EACF,CAAC"}
|