corsa-oxlint 0.3.2 → 0.4.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 +37 -2
- package/dist/checker.js.map +1 -1
- package/dist/oxlint_utils.d.ts +23 -3
- package/dist/oxlint_utils.js +2 -2
- package/dist/oxlint_utils.js.map +1 -1
- package/dist/session.js +5 -27
- package/dist/session.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/package.json +2 -2
package/dist/checker.js
CHANGED
|
@@ -27,13 +27,15 @@ function createProgram(context) {
|
|
|
27
27
|
function createTypeChecker(context) {
|
|
28
28
|
return {
|
|
29
29
|
getTypeAtLocation(node) {
|
|
30
|
-
|
|
30
|
+
const lookupNode = nodeForTypeLookup(node);
|
|
31
|
+
return sessionForContext(context).session.getTypeAtPosition(filenameFor(context, lookupNode), toPosition(lookupNode));
|
|
31
32
|
},
|
|
32
33
|
getContextualType(node) {
|
|
33
34
|
return this.getTypeAtLocation(node);
|
|
34
35
|
},
|
|
35
36
|
getSymbolAtLocation(node) {
|
|
36
|
-
|
|
37
|
+
const lookupNode = nodeForTypeLookup(node);
|
|
38
|
+
return sessionForContext(context).session.getSymbolAtPosition(filenameFor(context, lookupNode), toPosition(lookupNode));
|
|
37
39
|
},
|
|
38
40
|
getTypeOfSymbol(symbol) {
|
|
39
41
|
return sessionForContext(context).session.getTypeOfSymbol(symbol);
|
|
@@ -65,11 +67,44 @@ function createTypeChecker(context) {
|
|
|
65
67
|
getBaseTypes(type) {
|
|
66
68
|
return sessionForContext(context).session.getBaseTypes(type);
|
|
67
69
|
},
|
|
70
|
+
getImplementedTypes(node) {
|
|
71
|
+
return implementedClauseNodes(node).map((clause) => {
|
|
72
|
+
const expression = implementedClauseChildNode(clause, "expression") ?? clause;
|
|
73
|
+
const symbol = this.getSymbolAtLocation(expression) ?? this.getSymbolAtLocation(clause);
|
|
74
|
+
return symbol ? this.getDeclaredTypeOfSymbol(symbol) ?? this.getTypeOfSymbol(symbol) : this.getTypeAtLocation(expression) ?? this.getTypeAtLocation(clause);
|
|
75
|
+
}).filter((type) => type !== void 0);
|
|
76
|
+
},
|
|
68
77
|
getTypeArguments(type) {
|
|
69
78
|
return sessionForContext(context).session.getTypeArguments(type);
|
|
70
79
|
}
|
|
71
80
|
};
|
|
72
81
|
}
|
|
82
|
+
function nodeForTypeLookup(node) {
|
|
83
|
+
if ("pos" in node) return node;
|
|
84
|
+
switch (node.type) {
|
|
85
|
+
case "ClassDeclaration":
|
|
86
|
+
case "ClassExpression": return childNode(node, "id") ?? node;
|
|
87
|
+
case "TSPropertySignature": return childNode(node, "key") ?? node;
|
|
88
|
+
default: return node;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function childNode(node, key) {
|
|
92
|
+
const value = node[key];
|
|
93
|
+
if (isNode(value)) return value;
|
|
94
|
+
}
|
|
95
|
+
function implementedClauseNodes(node) {
|
|
96
|
+
if ("pos" in node) return [];
|
|
97
|
+
const clauses = node.implements;
|
|
98
|
+
if (!Array.isArray(clauses)) return [];
|
|
99
|
+
return clauses.filter(isNode);
|
|
100
|
+
}
|
|
101
|
+
function implementedClauseChildNode(node, key) {
|
|
102
|
+
const value = node[key];
|
|
103
|
+
if (isNode(value)) return value;
|
|
104
|
+
}
|
|
105
|
+
function isNode(value) {
|
|
106
|
+
return typeof value === "object" && value !== null && "type" in value && "range" in value;
|
|
107
|
+
}
|
|
73
108
|
function filenameFor(context, node) {
|
|
74
109
|
if ("fileName" in node) return node.fileName;
|
|
75
110
|
return context.filename;
|
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 TsgoNode,\n TsgoProgramShape,\n TsgoSignature,\n TsgoSymbol,\n TsgoType,\n TsgoTypeCheckerShape,\n} from \"./types\";\n\nexport function createProgram(\n context: ContextWithParserOptions,\n): TsgoProgramShape & { 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): TsgoTypeCheckerShape {\n return {\n getTypeAtLocation(node) {\n return sessionForContext(context).session.getTypeAtPosition(\n filenameFor(context,
|
|
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 TsgoNode,\n TsgoProgramShape,\n TsgoSignature,\n TsgoSymbol,\n TsgoType,\n TsgoTypeCheckerShape,\n} from \"./types\";\n\nexport function createProgram(\n context: ContextWithParserOptions,\n): TsgoProgramShape & { 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): TsgoTypeCheckerShape {\n return {\n getTypeAtLocation(node) {\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getTypeAtPosition(\n filenameFor(context, lookupNode),\n toPosition(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 );\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 this.getTypeAtLocation(node) ?? this.getTypeOfSymbol(symbol);\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 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 TsgoType => type !== undefined);\n },\n getTypeArguments(type) {\n return sessionForContext(context).session.getTypeArguments(type);\n },\n };\n}\n\nfunction nodeForTypeLookup(node: Node | TsgoNode): Node | TsgoNode {\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 | TsgoNode): 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 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 | TsgoNode | TsgoType | TsgoSymbol | TsgoSignature,\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/oxlint_utils.d.ts
CHANGED
|
@@ -1,18 +1,38 @@
|
|
|
1
1
|
import { ContextWithParserOptions, ParserServices } from "./types.js";
|
|
2
2
|
import { getParserServices } from "./parser_services.js";
|
|
3
|
+
import { Rule, RuleMeta, Visitor } from "@oxlint/plugins";
|
|
3
4
|
|
|
4
5
|
//#region src/bindings/nodejs/typescript_oxlint/ts/oxlint_utils.d.ts
|
|
6
|
+
type RuleCreatorRule<TOptions extends readonly unknown[] = readonly unknown[], TMessageIds extends string = string> = {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly meta: RuleMeta & {
|
|
9
|
+
readonly messages?: Record<TMessageIds, string>;
|
|
10
|
+
};
|
|
11
|
+
readonly defaultOptions?: TOptions;
|
|
12
|
+
readonly create: (context: ContextWithParserOptions) => Visitor;
|
|
13
|
+
};
|
|
14
|
+
type RuleCreatorCreatedRule<TRule extends RuleCreatorRule> = Omit<TRule, "defaultOptions" | "meta"> & {
|
|
15
|
+
readonly defaultOptions: TRule extends {
|
|
16
|
+
readonly defaultOptions: infer TOptions;
|
|
17
|
+
} ? TOptions : readonly [];
|
|
18
|
+
readonly meta: TRule["meta"] & {
|
|
19
|
+
readonly docs: NonNullable<TRule["meta"]["docs"]> & {
|
|
20
|
+
readonly url: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
} & Rule & Record<string, unknown>;
|
|
24
|
+
type RuleCreatorFactory = <TRule extends RuleCreatorRule>(rule: TRule) => RuleCreatorCreatedRule<TRule>;
|
|
5
25
|
/**
|
|
6
26
|
* Self-hosted type-aware utilities for Oxlint rules backed by tsgo.
|
|
7
27
|
*/
|
|
8
28
|
declare const OxlintUtils: Readonly<{
|
|
9
|
-
RuleCreator(urlCreator: (ruleName: string) => string):
|
|
29
|
+
RuleCreator(urlCreator: (ruleName: string) => string): RuleCreatorFactory;
|
|
10
30
|
getParserServices(context: ContextWithParserOptions, allowWithoutFullTypeInformation?: boolean): ParserServices;
|
|
11
31
|
}>;
|
|
12
|
-
declare const RuleCreator: (urlCreator: (ruleName: string) => string) =>
|
|
32
|
+
declare const RuleCreator: (urlCreator: (ruleName: string) => string) => RuleCreatorFactory;
|
|
13
33
|
declare function applyDefault<Values extends readonly unknown[], Defaults extends readonly unknown[]>(values: Values | undefined, defaults: Defaults): readonly unknown[];
|
|
14
34
|
declare function deepMerge<T>(base: T, override: unknown): T;
|
|
15
35
|
declare function nullThrows<T>(value: T | null | undefined, message?: string): T;
|
|
16
36
|
//#endregion
|
|
17
|
-
export { OxlintUtils, RuleCreator, applyDefault, deepMerge, getParserServices, nullThrows };
|
|
37
|
+
export { OxlintUtils, RuleCreator, RuleCreatorCreatedRule, RuleCreatorFactory, RuleCreatorRule, applyDefault, deepMerge, getParserServices, nullThrows };
|
|
18
38
|
//# sourceMappingURL=oxlint_utils.d.ts.map
|
package/dist/oxlint_utils.js
CHANGED
|
@@ -6,7 +6,7 @@ import { decorateRule } from "./plugin.js";
|
|
|
6
6
|
*/
|
|
7
7
|
const OxlintUtils = Object.freeze({
|
|
8
8
|
RuleCreator(urlCreator) {
|
|
9
|
-
return (rule) => {
|
|
9
|
+
return ((rule) => {
|
|
10
10
|
const docs = rule.meta?.docs;
|
|
11
11
|
return decorateRule({
|
|
12
12
|
...rule,
|
|
@@ -19,7 +19,7 @@ const OxlintUtils = Object.freeze({
|
|
|
19
19
|
},
|
|
20
20
|
defaultOptions: rule.defaultOptions ?? []
|
|
21
21
|
});
|
|
22
|
-
};
|
|
22
|
+
});
|
|
23
23
|
},
|
|
24
24
|
getParserServices(context, allowWithoutFullTypeInformation = false) {
|
|
25
25
|
return getParserServices(context, allowWithoutFullTypeInformation);
|
package/dist/oxlint_utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxlint_utils.js","names":[],"sources":["../ts/oxlint_utils.ts"],"sourcesContent":["import { getParserServices } from \"./parser_services\";\nimport { decorateRule } from \"./plugin\";\nimport type { ContextWithParserOptions } from \"./types\";\n\n/**\n * Self-hosted type-aware utilities for Oxlint rules backed by tsgo.\n */\nexport const OxlintUtils = Object.freeze({\n RuleCreator(urlCreator: (ruleName: string) => string) {\n return (rule
|
|
1
|
+
{"version":3,"file":"oxlint_utils.js","names":[],"sources":["../ts/oxlint_utils.ts"],"sourcesContent":["import type { Rule, RuleMeta, Visitor } from \"@oxlint/plugins\";\n\nimport { getParserServices } from \"./parser_services\";\nimport { decorateRule } 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> = Omit<\n TRule,\n \"defaultOptions\" | \"meta\"\n> & {\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} & Rule &\n Record<string, unknown>;\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 tsgo.\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 RuleCreator = OxlintUtils.RuleCreator;\nexport { getParserServices } from \"./parser_services\";\n\nexport function applyDefault<\n Values extends readonly unknown[],\n Defaults extends readonly unknown[],\n>(values: Values | undefined, defaults: Defaults): readonly unknown[] {\n return deepMerge(defaults, values ?? []) as readonly unknown[];\n}\n\nexport function deepMerge<T>(base: T, override: unknown): T {\n if (Array.isArray(base) && Array.isArray(override)) {\n return base.map((value, index) => deepMerge(value, override[index])) as unknown as T;\n }\n if (isObject(base) && isObject(override)) {\n return Object.fromEntries(\n [...new Set([...Object.keys(base), ...Object.keys(override)])].map((key) => [\n key,\n deepMerge((base as any)[key], (override as any)[key]),\n ]),\n ) as T;\n }\n return (override ?? base) 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(message);\n }\n return value;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";;;;;;AAwCA,MAAa,cAAc,OAAO,OAAO;CACvC,YAAY,YAA8D;AACxE,WAAS,SAAS;GAChB,MAAM,OAAO,KAAK,MAAM;AACxB,UAAO,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;AAC5F,SAAO,kBAAkB,SAAS,gCAAgC;;CAErE,CAAC;AAEF,MAAa,cAAc,YAAY;AAGvC,SAAgB,aAGd,QAA4B,UAAwC;AACpE,QAAO,UAAU,UAAU,UAAU,EAAE,CAAC;;AAG1C,SAAgB,UAAa,MAAS,UAAsB;AAC1D,KAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ,SAAS,CAChD,QAAO,KAAK,KAAK,OAAO,UAAU,UAAU,OAAO,SAAS,OAAO,CAAC;AAEtE,KAAI,SAAS,KAAK,IAAI,SAAS,SAAS,CACtC,QAAO,OAAO,YACZ,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAC1E,KACA,UAAW,KAAa,MAAO,SAAiB,KAAK,CACtD,CAAC,CACH;AAEH,QAAQ,YAAY;;AAGtB,SAAgB,WACd,OACA,UAAU,gCACP;AACH,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,QAAQ;AAE1B,QAAO;;AAGT,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
package/dist/session.js
CHANGED
|
@@ -29,37 +29,19 @@ var TsgoProjectSession = class {
|
|
|
29
29
|
}
|
|
30
30
|
getTypeAtPosition(fileName, position) {
|
|
31
31
|
const state = this.fileState(fileName);
|
|
32
|
-
if (!state.typeByPosition.has(position)) state.typeByPosition.set(position, this.client().
|
|
33
|
-
snapshot: this.#snapshot,
|
|
34
|
-
project: state.projectId,
|
|
35
|
-
file: fileName,
|
|
36
|
-
position
|
|
37
|
-
}));
|
|
32
|
+
if (!state.typeByPosition.has(position)) state.typeByPosition.set(position, this.client().getTypeAtPosition(this.#snapshot, state.projectId, fileName, position));
|
|
38
33
|
return state.typeByPosition.get(position);
|
|
39
34
|
}
|
|
40
35
|
getSymbolAtPosition(fileName, position) {
|
|
41
36
|
const state = this.fileState(fileName);
|
|
42
|
-
if (!state.symbolByPosition.has(position)) state.symbolByPosition.set(position, this.client().
|
|
43
|
-
snapshot: this.#snapshot,
|
|
44
|
-
project: state.projectId,
|
|
45
|
-
file: fileName,
|
|
46
|
-
position
|
|
47
|
-
}));
|
|
37
|
+
if (!state.symbolByPosition.has(position)) state.symbolByPosition.set(position, this.client().getSymbolAtPosition(this.#snapshot, state.projectId, fileName, position));
|
|
48
38
|
return state.symbolByPosition.get(position);
|
|
49
39
|
}
|
|
50
40
|
getTypeOfSymbol(symbol) {
|
|
51
|
-
return this.client().
|
|
52
|
-
snapshot: this.#snapshot,
|
|
53
|
-
project: this.projectId(),
|
|
54
|
-
symbol: symbol.id
|
|
55
|
-
});
|
|
41
|
+
return this.client().getTypeOfSymbol(this.#snapshot, this.projectId(), symbol.id);
|
|
56
42
|
}
|
|
57
43
|
getDeclaredTypeOfSymbol(symbol) {
|
|
58
|
-
return this.client().
|
|
59
|
-
snapshot: this.#snapshot,
|
|
60
|
-
project: this.projectId(),
|
|
61
|
-
symbol: symbol.id
|
|
62
|
-
});
|
|
44
|
+
return this.client().getDeclaredTypeOfSymbol(this.#snapshot, this.projectId(), symbol.id);
|
|
63
45
|
}
|
|
64
46
|
typeToString(type, flags) {
|
|
65
47
|
return this.client().typeToString(this.#snapshot, this.projectId(), type.id, void 0, flags);
|
|
@@ -108,11 +90,7 @@ var TsgoProjectSession = class {
|
|
|
108
90
|
}) ?? [];
|
|
109
91
|
}
|
|
110
92
|
getTypeArguments(type) {
|
|
111
|
-
return this.client().
|
|
112
|
-
snapshot: this.#snapshot,
|
|
113
|
-
project: this.projectId(),
|
|
114
|
-
type: type.id
|
|
115
|
-
}) ?? [];
|
|
93
|
+
return this.client().getTypeArguments(this.#snapshot, this.projectId(), type.id, type.objectFlags);
|
|
116
94
|
}
|
|
117
95
|
client() {
|
|
118
96
|
if (!this.#client) {
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","names":["#snapshot","#client","#files","#config","#lastRefreshMs","#projects"],"sources":["../ts/session.ts"],"sourcesContent":["import { statSync } from \"node:fs\";\n\nimport { type ProjectResponse, TsgoApiClient } from \"@corsa-bind/napi\";\n\nimport type { TsgoSignature, TsgoSymbol, TsgoType, TsgoTypePredicate } from \"./types\";\nimport type { ResolvedProjectConfig, ResolvedRuntimeOptions } from \"./types\";\n\ntype FileCache = {\n mtimeMs: number;\n projectId: string;\n typeByPosition: Map<number, TsgoType | undefined>;\n symbolByPosition: Map<number, TsgoSymbol | undefined>;\n};\n\nexport class TsgoProjectSession {\n #client?: TsgoApiClient;\n #config?: { options: unknown; fileNames: string[] };\n #snapshot?: string;\n #projects: ProjectResponse[] = [];\n #files = new Map<string, FileCache>();\n #lastRefreshMs = 0;\n\n constructor(\n readonly project: ResolvedProjectConfig,\n readonly runtime: ResolvedRuntimeOptions,\n ) {}\n\n close(): void {\n if (this.#snapshot) {\n this.#client?.releaseHandle(this.#snapshot);\n this.#snapshot = undefined;\n }\n this.#client?.close();\n this.#client = undefined;\n this.#files.clear();\n }\n\n getCompilerOptions(): unknown {\n return this.config().options;\n }\n\n getRootFileNames(): readonly string[] {\n return this.config().fileNames;\n }\n\n getTypeAtPosition(fileName: string, position: number): TsgoType | undefined {\n const state = this.fileState(fileName);\n if (!state.typeByPosition.has(position)) {\n state.typeByPosition.set(\n position,\n this.client().callJson(\"getTypeAtPosition\", {\n snapshot: this.#snapshot,\n project: state.projectId,\n file: fileName,\n position,\n }),\n );\n }\n return state.typeByPosition.get(position);\n }\n\n getSymbolAtPosition(fileName: string, position: number): TsgoSymbol | undefined {\n const state = this.fileState(fileName);\n if (!state.symbolByPosition.has(position)) {\n state.symbolByPosition.set(\n position,\n this.client().callJson(\"getSymbolAtPosition\", {\n snapshot: this.#snapshot,\n project: state.projectId,\n file: fileName,\n position,\n }),\n );\n }\n return state.symbolByPosition.get(position);\n }\n\n getTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().callJson(\"getTypeOfSymbol\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n symbol: symbol.id,\n });\n }\n\n getDeclaredTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().callJson(\"getDeclaredTypeOfSymbol\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n symbol: symbol.id,\n });\n }\n\n typeToString(type: TsgoType, flags?: number): string {\n return this.client().typeToString(this.#snapshot!, this.projectId(), type.id, undefined, flags);\n }\n\n getBaseTypeOfLiteralType(type: TsgoType): TsgoType | undefined {\n return this.client().callJson(\"getBaseTypeOfLiteralType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n });\n }\n\n getPropertiesOfType(type: TsgoType): readonly TsgoSymbol[] {\n return (\n this.client().callJson(\"getPropertiesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getSignaturesOfType(type: TsgoType, kind: number): readonly TsgoSignature[] {\n return this.client().callJson(\"getSignaturesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n kind,\n });\n }\n\n getReturnTypeOfSignature(signature: TsgoSignature): TsgoType | undefined {\n return this.client().callJson(\"getReturnTypeOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getTypePredicateOfSignature(signature: TsgoSignature): TsgoTypePredicate | undefined {\n return this.client().callJson(\"getTypePredicateOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getBaseTypes(type: TsgoType): readonly TsgoType[] {\n return (\n this.client().callJson(\"getBaseTypes\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getTypeArguments(type: TsgoType): readonly TsgoType[] {\n return (\n this.client().callJson(\"getTypeArguments\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n private client(): TsgoApiClient {\n if (!this.#client) {\n this.#client = TsgoApiClient.spawn({\n executable: this.runtime.executable,\n cwd: this.runtime.cwd,\n mode: this.runtime.mode,\n });\n this.#client.initialize();\n }\n return this.#client;\n }\n\n private config(): { options: unknown; fileNames: string[] } {\n if (!this.#config) {\n this.#config = this.client().parseConfigFile(this.project.configPath);\n }\n const config = this.#config;\n if (!config) {\n throw new Error(`corsa-oxlint could not parse a tsgo config for ${this.project.configPath}`);\n }\n return config;\n }\n\n private fileState(fileName: string): FileCache {\n this.refreshIfNeeded(fileName);\n const current = this.#files.get(fileName);\n if (current) {\n return current;\n }\n const project = this.client().callJson<ProjectResponse | null>(\"getDefaultProjectForFile\", {\n snapshot: this.#snapshot,\n file: fileName,\n });\n const state: FileCache = {\n mtimeMs: statMtimeMs(fileName),\n projectId: project?.id ?? this.projectId(),\n typeByPosition: new Map(),\n symbolByPosition: new Map(),\n };\n this.#files.set(fileName, state);\n return state;\n }\n\n private refreshIfNeeded(fileName: string): void {\n const now = Date.now();\n const expired = now - this.#lastRefreshMs > this.runtime.cacheLifetimeMs;\n const stale =\n !this.#snapshot || statMtimeMs(fileName) !== this.#files.get(fileName)?.mtimeMs || expired;\n if (!stale) {\n return;\n }\n const previous = this.#snapshot;\n const response = this.client().updateSnapshot(\n previous\n ? { fileChanges: { changed: [fileName] } }\n : { openProject: this.project.configPath },\n );\n this.#snapshot = response.snapshot;\n this.#projects = response.projects;\n this.#lastRefreshMs = now;\n this.#files.clear();\n if (previous && previous !== this.#snapshot) {\n this.client().releaseHandle(previous);\n }\n }\n\n private projectId(): string {\n const id = this.#projects[0]?.id;\n if (!id) {\n throw new Error(`corsa-oxlint could not resolve a tsgo project for ${this.project.filename}`);\n }\n return id;\n }\n}\n\nfunction statMtimeMs(fileName: string): number {\n try {\n return statSync(fileName).mtimeMs;\n } catch {\n return 0;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session.js","names":["#snapshot","#client","#files","#config","#lastRefreshMs","#projects"],"sources":["../ts/session.ts"],"sourcesContent":["import { statSync } from \"node:fs\";\n\nimport { type ProjectResponse, TsgoApiClient } from \"@corsa-bind/napi\";\n\nimport type { TsgoSignature, TsgoSymbol, TsgoType, TsgoTypePredicate } from \"./types\";\nimport type { ResolvedProjectConfig, ResolvedRuntimeOptions } from \"./types\";\n\ntype FileCache = {\n mtimeMs: number;\n projectId: string;\n typeByPosition: Map<number, TsgoType | undefined>;\n symbolByPosition: Map<number, TsgoSymbol | undefined>;\n};\n\nexport class TsgoProjectSession {\n #client?: TsgoApiClient;\n #config?: { options: unknown; fileNames: string[] };\n #snapshot?: string;\n #projects: ProjectResponse[] = [];\n #files = new Map<string, FileCache>();\n #lastRefreshMs = 0;\n\n constructor(\n readonly project: ResolvedProjectConfig,\n readonly runtime: ResolvedRuntimeOptions,\n ) {}\n\n close(): void {\n if (this.#snapshot) {\n this.#client?.releaseHandle(this.#snapshot);\n this.#snapshot = undefined;\n }\n this.#client?.close();\n this.#client = undefined;\n this.#files.clear();\n }\n\n getCompilerOptions(): unknown {\n return this.config().options;\n }\n\n getRootFileNames(): readonly string[] {\n return this.config().fileNames;\n }\n\n getTypeAtPosition(fileName: string, position: number): TsgoType | undefined {\n const state = this.fileState(fileName);\n if (!state.typeByPosition.has(position)) {\n state.typeByPosition.set(\n position,\n this.client().getTypeAtPosition(this.#snapshot!, state.projectId, fileName, position) as\n | TsgoType\n | undefined,\n );\n }\n return state.typeByPosition.get(position);\n }\n\n getSymbolAtPosition(fileName: string, position: number): TsgoSymbol | undefined {\n const state = this.fileState(fileName);\n if (!state.symbolByPosition.has(position)) {\n state.symbolByPosition.set(\n position,\n this.client().getSymbolAtPosition(this.#snapshot!, state.projectId, fileName, position) as\n | TsgoSymbol\n | undefined,\n );\n }\n return state.symbolByPosition.get(position);\n }\n\n getTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().getTypeOfSymbol(this.#snapshot!, this.projectId(), symbol.id) as\n | TsgoType\n | undefined;\n }\n\n getDeclaredTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().getDeclaredTypeOfSymbol(this.#snapshot!, this.projectId(), symbol.id) as\n | TsgoType\n | undefined;\n }\n\n typeToString(type: TsgoType, flags?: number): string {\n return this.client().typeToString(this.#snapshot!, this.projectId(), type.id, undefined, flags);\n }\n\n getBaseTypeOfLiteralType(type: TsgoType): TsgoType | undefined {\n return this.client().callJson(\"getBaseTypeOfLiteralType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n });\n }\n\n getPropertiesOfType(type: TsgoType): readonly TsgoSymbol[] {\n return (\n this.client().callJson(\"getPropertiesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getSignaturesOfType(type: TsgoType, kind: number): readonly TsgoSignature[] {\n return this.client().callJson(\"getSignaturesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n kind,\n });\n }\n\n getReturnTypeOfSignature(signature: TsgoSignature): TsgoType | undefined {\n return this.client().callJson(\"getReturnTypeOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getTypePredicateOfSignature(signature: TsgoSignature): TsgoTypePredicate | undefined {\n return this.client().callJson(\"getTypePredicateOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getBaseTypes(type: TsgoType): readonly TsgoType[] {\n return (\n this.client().callJson(\"getBaseTypes\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getTypeArguments(type: TsgoType): readonly TsgoType[] {\n return this.client().getTypeArguments(\n this.#snapshot!,\n this.projectId(),\n type.id,\n type.objectFlags,\n ) as unknown as readonly TsgoType[];\n }\n\n private client(): TsgoApiClient {\n if (!this.#client) {\n this.#client = TsgoApiClient.spawn({\n executable: this.runtime.executable,\n cwd: this.runtime.cwd,\n mode: this.runtime.mode,\n });\n this.#client.initialize();\n }\n return this.#client;\n }\n\n private config(): { options: unknown; fileNames: string[] } {\n if (!this.#config) {\n this.#config = this.client().parseConfigFile(this.project.configPath);\n }\n const config = this.#config;\n if (!config) {\n throw new Error(`corsa-oxlint could not parse a tsgo config for ${this.project.configPath}`);\n }\n return config;\n }\n\n private fileState(fileName: string): FileCache {\n this.refreshIfNeeded(fileName);\n const current = this.#files.get(fileName);\n if (current) {\n return current;\n }\n const project = this.client().callJson<ProjectResponse | null>(\"getDefaultProjectForFile\", {\n snapshot: this.#snapshot,\n file: fileName,\n });\n const state: FileCache = {\n mtimeMs: statMtimeMs(fileName),\n projectId: project?.id ?? this.projectId(),\n typeByPosition: new Map(),\n symbolByPosition: new Map(),\n };\n this.#files.set(fileName, state);\n return state;\n }\n\n private refreshIfNeeded(fileName: string): void {\n const now = Date.now();\n const expired = now - this.#lastRefreshMs > this.runtime.cacheLifetimeMs;\n const stale =\n !this.#snapshot || statMtimeMs(fileName) !== this.#files.get(fileName)?.mtimeMs || expired;\n if (!stale) {\n return;\n }\n const previous = this.#snapshot;\n const response = this.client().updateSnapshot(\n previous\n ? { fileChanges: { changed: [fileName] } }\n : { openProject: this.project.configPath },\n );\n this.#snapshot = response.snapshot;\n this.#projects = response.projects;\n this.#lastRefreshMs = now;\n this.#files.clear();\n if (previous && previous !== this.#snapshot) {\n this.client().releaseHandle(previous);\n }\n }\n\n private projectId(): string {\n const id = this.#projects[0]?.id;\n if (!id) {\n throw new Error(`corsa-oxlint could not resolve a tsgo project for ${this.project.filename}`);\n }\n return id;\n }\n}\n\nfunction statMtimeMs(fileName: string): number {\n try {\n return statSync(fileName).mtimeMs;\n } catch {\n return 0;\n }\n}\n"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -95,6 +95,7 @@ interface TsgoTypeCheckerShape {
|
|
|
95
95
|
getReturnTypeOfSignature(signature: TsgoSignature): TsgoType | undefined;
|
|
96
96
|
getTypePredicateOfSignature(signature: TsgoSignature): TsgoTypePredicate | undefined;
|
|
97
97
|
getBaseTypes(type: TsgoType): readonly TsgoType[];
|
|
98
|
+
getImplementedTypes(node: Node | TsgoNode): readonly TsgoType[];
|
|
98
99
|
getTypeArguments(type: TsgoType): readonly TsgoType[];
|
|
99
100
|
}
|
|
100
101
|
interface ParserServices {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corsa-oxlint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Type-aware Oxlint helpers powered by corsa and typescript-go",
|
|
5
5
|
"homepage": "https://github.com/ubugeeei/corsa-bind/tree/main/src/bindings/nodejs/typescript_oxlint",
|
|
6
6
|
"bugs": {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@oxlint/plugins": "1.57.0",
|
|
63
63
|
"oxlint": "1.57.0",
|
|
64
|
-
"@corsa-bind/napi": "0.
|
|
64
|
+
"@corsa-bind/napi": "0.4.0"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">=22"
|