@ast-grep/napi 0.31.1 → 0.32.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/index.d.ts +18 -286
- package/package.json +24 -16
- package/types/api.d.ts +46 -0
- package/types/config.d.ts +39 -0
- package/types/deprecated.d.ts +117 -0
- package/types/lang.d.ts +26 -0
- package/{manual.d.ts → types/rule.d.ts} +30 -24
- package/types/sgnode.d.ts +119 -0
- package/types/staticTypes.d.ts +95 -0
package/index.d.ts
CHANGED
|
@@ -1,287 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//-----Type Only Export!-----//
|
|
2
|
+
export type { Pos, Edit, Range } from './types/sgnode'
|
|
3
|
+
export type { NapiConfig, FindConfig, FileOption } from './types/config'
|
|
4
|
+
// Only Rule here. User can use Rule['pattern'], e.g., to get the type of subfield.
|
|
5
|
+
export type { Rule } from './types/rule'
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* transform is NOT useful in JavaScript. You can use JS code to directly transform the result.
|
|
19
|
-
* https://ast-grep.github.io/reference/yaml.html#transform
|
|
20
|
-
*/
|
|
21
|
-
transform?: any
|
|
22
|
-
/** https://ast-grep.github.io/guide/rule-config/utility-rule.html */
|
|
23
|
-
utils?: any
|
|
24
|
-
}
|
|
25
|
-
export interface FileOption {
|
|
26
|
-
paths: Array<string>
|
|
27
|
-
languageGlobs: Record<string, Array<string>>
|
|
28
|
-
}
|
|
29
|
-
export declare function parseFiles(paths: Array<string> | FileOption, callback: (err: null | Error, result: SgRoot) => void): Promise<number>
|
|
30
|
-
export interface FindConfig {
|
|
31
|
-
/** specify the file paths to recursively find files */
|
|
32
|
-
paths: Array<string>
|
|
33
|
-
/** a Rule object to find what nodes will match */
|
|
34
|
-
matcher: NapiConfig
|
|
35
|
-
/**
|
|
36
|
-
* An list of pattern globs to treat of certain files in the specified language.
|
|
37
|
-
* eg. ['*.vue', '*.svelte'] for html.findFiles, or ['*.ts'] for tsx.findFiles.
|
|
38
|
-
* It is slightly different from https://ast-grep.github.io/reference/sgconfig.html#languageglobs
|
|
39
|
-
*/
|
|
40
|
-
languageGlobs?: Array<string>
|
|
41
|
-
}
|
|
42
|
-
export enum Lang {
|
|
43
|
-
Html = 'Html',
|
|
44
|
-
JavaScript = 'JavaScript',
|
|
45
|
-
Tsx = 'Tsx',
|
|
46
|
-
Css = 'Css',
|
|
47
|
-
TypeScript = 'TypeScript',
|
|
48
|
-
Bash = 'Bash',
|
|
49
|
-
C = 'C',
|
|
50
|
-
Cpp = 'Cpp',
|
|
51
|
-
CSharp = 'CSharp',
|
|
52
|
-
Go = 'Go',
|
|
53
|
-
Elixir = 'Elixir',
|
|
54
|
-
Haskell = 'Haskell',
|
|
55
|
-
Java = 'Java',
|
|
56
|
-
Json = 'Json',
|
|
57
|
-
Kotlin = 'Kotlin',
|
|
58
|
-
Lua = 'Lua',
|
|
59
|
-
Php = 'Php',
|
|
60
|
-
Python = 'Python',
|
|
61
|
-
Ruby = 'Ruby',
|
|
62
|
-
Rust = 'Rust',
|
|
63
|
-
Scala = 'Scala',
|
|
64
|
-
Sql = 'Sql',
|
|
65
|
-
Swift = 'Swift',
|
|
66
|
-
Yaml = 'Yaml'
|
|
67
|
-
}
|
|
68
|
-
export interface Edit {
|
|
69
|
-
/** The start position of the edit */
|
|
70
|
-
startPos: number
|
|
71
|
-
/** The end position of the edit */
|
|
72
|
-
endPos: number
|
|
73
|
-
/** The text to be inserted */
|
|
74
|
-
insertedText: string
|
|
75
|
-
}
|
|
76
|
-
export interface Pos {
|
|
77
|
-
/** line number starting from 0 */
|
|
78
|
-
line: number
|
|
79
|
-
/** column number starting from 0 */
|
|
80
|
-
column: number
|
|
81
|
-
/** byte offset of the position */
|
|
82
|
-
index: number
|
|
83
|
-
}
|
|
84
|
-
export interface Range {
|
|
85
|
-
/** starting position of the range */
|
|
86
|
-
start: Pos
|
|
87
|
-
/** ending position of the range */
|
|
88
|
-
end: Pos
|
|
89
|
-
}
|
|
90
|
-
/** Parse a string to an ast-grep instance */
|
|
91
|
-
export declare function parse(lang: Lang, src: string): SgRoot
|
|
92
|
-
/**
|
|
93
|
-
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
94
|
-
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
95
|
-
* However, spawning excessive many threads may backfire.
|
|
96
|
-
* Please refer to libuv doc, nodejs' underlying runtime
|
|
97
|
-
* for its default behavior and performance tuning tricks.
|
|
98
|
-
*/
|
|
99
|
-
export declare function parseAsync(lang: Lang, src: string): Promise<SgRoot>
|
|
100
|
-
/** Get the `kind` number from its string name. */
|
|
101
|
-
export declare function kind(lang: Lang, kindName: string): number
|
|
102
|
-
/** Compile a string to ast-grep Pattern. */
|
|
103
|
-
export declare function pattern(lang: Lang, pattern: string): NapiConfig
|
|
104
|
-
/**
|
|
105
|
-
* Discover and parse multiple files in Rust.
|
|
106
|
-
* `lang` specifies the language.
|
|
107
|
-
* `config` specifies the file path and matcher.
|
|
108
|
-
* `callback` will receive matching nodes found in a file.
|
|
109
|
-
*/
|
|
110
|
-
export declare function findInFiles(lang: Lang, config: FindConfig, callback: (err: null | Error, result: SgNode[]) => void): Promise<number>
|
|
111
|
-
export declare class SgNode {
|
|
112
|
-
range(): Range
|
|
113
|
-
isLeaf(): boolean
|
|
114
|
-
isNamed(): boolean
|
|
115
|
-
isNamedLeaf(): boolean
|
|
116
|
-
/** Returns the string name of the node kind */
|
|
117
|
-
kind(): string
|
|
118
|
-
text(): string
|
|
119
|
-
matches(m: string): boolean
|
|
120
|
-
inside(m: string): boolean
|
|
121
|
-
has(m: string): boolean
|
|
122
|
-
precedes(m: string): boolean
|
|
123
|
-
follows(m: string): boolean
|
|
124
|
-
getMatch(m: string): SgNode | null
|
|
125
|
-
getMultipleMatches(m: string): Array<SgNode>
|
|
126
|
-
getTransformed(m: string): string | null
|
|
127
|
-
/** Returns the node's SgRoot */
|
|
128
|
-
getRoot(): SgRoot
|
|
129
|
-
children(): Array<SgNode>
|
|
130
|
-
/** Returns the node's id */
|
|
131
|
-
id(): number
|
|
132
|
-
find(matcher: string | number | NapiConfig): SgNode | null
|
|
133
|
-
findAll(matcher: string | number | NapiConfig): Array<SgNode>
|
|
134
|
-
/** Finds the child node in the `field` */
|
|
135
|
-
field(name: string): SgNode | null
|
|
136
|
-
parent(): SgNode | null
|
|
137
|
-
child(nth: number): SgNode | null
|
|
138
|
-
ancestors(): Array<SgNode>
|
|
139
|
-
next(): SgNode | null
|
|
140
|
-
nextAll(): Array<SgNode>
|
|
141
|
-
prev(): SgNode | null
|
|
142
|
-
prevAll(): Array<SgNode>
|
|
143
|
-
replace(text: string): Edit
|
|
144
|
-
commitEdits(edits: Array<Edit>): string
|
|
145
|
-
}
|
|
146
|
-
/** Represents the parsed tree of code. */
|
|
147
|
-
export declare class SgRoot {
|
|
148
|
-
/** Returns the root SgNode of the ast-grep instance. */
|
|
149
|
-
root(): SgNode
|
|
150
|
-
/**
|
|
151
|
-
* Returns the path of the file if it is discovered by ast-grep's `findInFiles`.
|
|
152
|
-
* Returns `"anonymous"` if the instance is created by `lang.parse(source)`.
|
|
153
|
-
*/
|
|
154
|
-
filename(): string
|
|
155
|
-
}
|
|
156
|
-
export declare namespace html {
|
|
157
|
-
/** Parse a string to an ast-grep instance */
|
|
158
|
-
export function parse(src: string): SgRoot
|
|
159
|
-
/**
|
|
160
|
-
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
161
|
-
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
162
|
-
* However, spawning excessive many threads may backfire.
|
|
163
|
-
* Please refer to libuv doc, nodejs' underlying runtime
|
|
164
|
-
* for its default behavior and performance tuning tricks.
|
|
165
|
-
*/
|
|
166
|
-
export function parseAsync(src: string): Promise<SgRoot>
|
|
167
|
-
/** Get the `kind` number from its string name. */
|
|
168
|
-
export function kind(kindName: string): number
|
|
169
|
-
/** Compile a string to ast-grep Pattern. */
|
|
170
|
-
export function pattern(pattern: string): NapiConfig
|
|
171
|
-
/**
|
|
172
|
-
* Discover and parse multiple files in Rust.
|
|
173
|
-
* `config` specifies the file path and matcher.
|
|
174
|
-
* `callback` will receive matching nodes found in a file.
|
|
175
|
-
*/
|
|
176
|
-
export function findInFiles(config: FindConfig, callback: (err: null | Error, result: SgNode[]) => void): Promise<number>
|
|
177
|
-
}
|
|
178
|
-
export declare namespace js {
|
|
179
|
-
/** Parse a string to an ast-grep instance */
|
|
180
|
-
export function parse(src: string): SgRoot
|
|
181
|
-
/**
|
|
182
|
-
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
183
|
-
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
184
|
-
* However, spawning excessive many threads may backfire.
|
|
185
|
-
* Please refer to libuv doc, nodejs' underlying runtime
|
|
186
|
-
* for its default behavior and performance tuning tricks.
|
|
187
|
-
*/
|
|
188
|
-
export function parseAsync(src: string): Promise<SgRoot>
|
|
189
|
-
/** Get the `kind` number from its string name. */
|
|
190
|
-
export function kind(kindName: string): number
|
|
191
|
-
/** Compile a string to ast-grep Pattern. */
|
|
192
|
-
export function pattern(pattern: string): NapiConfig
|
|
193
|
-
/**
|
|
194
|
-
* Discover and parse multiple files in Rust.
|
|
195
|
-
* `config` specifies the file path and matcher.
|
|
196
|
-
* `callback` will receive matching nodes found in a file.
|
|
197
|
-
*/
|
|
198
|
-
export function findInFiles(config: FindConfig, callback: (err: null | Error, result: SgNode[]) => void): Promise<number>
|
|
199
|
-
}
|
|
200
|
-
export declare namespace jsx {
|
|
201
|
-
/** Parse a string to an ast-grep instance */
|
|
202
|
-
export function parse(src: string): SgRoot
|
|
203
|
-
/**
|
|
204
|
-
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
205
|
-
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
206
|
-
* However, spawning excessive many threads may backfire.
|
|
207
|
-
* Please refer to libuv doc, nodejs' underlying runtime
|
|
208
|
-
* for its default behavior and performance tuning tricks.
|
|
209
|
-
*/
|
|
210
|
-
export function parseAsync(src: string): Promise<SgRoot>
|
|
211
|
-
/** Get the `kind` number from its string name. */
|
|
212
|
-
export function kind(kindName: string): number
|
|
213
|
-
/** Compile a string to ast-grep Pattern. */
|
|
214
|
-
export function pattern(pattern: string): NapiConfig
|
|
215
|
-
/**
|
|
216
|
-
* Discover and parse multiple files in Rust.
|
|
217
|
-
* `config` specifies the file path and matcher.
|
|
218
|
-
* `callback` will receive matching nodes found in a file.
|
|
219
|
-
*/
|
|
220
|
-
export function findInFiles(config: FindConfig, callback: (err: null | Error, result: SgNode[]) => void): Promise<number>
|
|
221
|
-
}
|
|
222
|
-
export declare namespace ts {
|
|
223
|
-
/** Parse a string to an ast-grep instance */
|
|
224
|
-
export function parse(src: string): SgRoot
|
|
225
|
-
/**
|
|
226
|
-
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
227
|
-
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
228
|
-
* However, spawning excessive many threads may backfire.
|
|
229
|
-
* Please refer to libuv doc, nodejs' underlying runtime
|
|
230
|
-
* for its default behavior and performance tuning tricks.
|
|
231
|
-
*/
|
|
232
|
-
export function parseAsync(src: string): Promise<SgRoot>
|
|
233
|
-
/** Get the `kind` number from its string name. */
|
|
234
|
-
export function kind(kindName: string): number
|
|
235
|
-
/** Compile a string to ast-grep Pattern. */
|
|
236
|
-
export function pattern(pattern: string): NapiConfig
|
|
237
|
-
/**
|
|
238
|
-
* Discover and parse multiple files in Rust.
|
|
239
|
-
* `config` specifies the file path and matcher.
|
|
240
|
-
* `callback` will receive matching nodes found in a file.
|
|
241
|
-
*/
|
|
242
|
-
export function findInFiles(config: FindConfig, callback: (err: null | Error, result: SgNode[]) => void): Promise<number>
|
|
243
|
-
}
|
|
244
|
-
export declare namespace tsx {
|
|
245
|
-
/** Parse a string to an ast-grep instance */
|
|
246
|
-
export function parse(src: string): SgRoot
|
|
247
|
-
/**
|
|
248
|
-
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
249
|
-
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
250
|
-
* However, spawning excessive many threads may backfire.
|
|
251
|
-
* Please refer to libuv doc, nodejs' underlying runtime
|
|
252
|
-
* for its default behavior and performance tuning tricks.
|
|
253
|
-
*/
|
|
254
|
-
export function parseAsync(src: string): Promise<SgRoot>
|
|
255
|
-
/** Get the `kind` number from its string name. */
|
|
256
|
-
export function kind(kindName: string): number
|
|
257
|
-
/** Compile a string to ast-grep Pattern. */
|
|
258
|
-
export function pattern(pattern: string): NapiConfig
|
|
259
|
-
/**
|
|
260
|
-
* Discover and parse multiple files in Rust.
|
|
261
|
-
* `config` specifies the file path and matcher.
|
|
262
|
-
* `callback` will receive matching nodes found in a file.
|
|
263
|
-
*/
|
|
264
|
-
export function findInFiles(config: FindConfig, callback: (err: null | Error, result: SgNode[]) => void): Promise<number>
|
|
265
|
-
}
|
|
266
|
-
export declare namespace css {
|
|
267
|
-
/** Parse a string to an ast-grep instance */
|
|
268
|
-
export function parse(src: string): SgRoot
|
|
269
|
-
/**
|
|
270
|
-
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
271
|
-
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
272
|
-
* However, spawning excessive many threads may backfire.
|
|
273
|
-
* Please refer to libuv doc, nodejs' underlying runtime
|
|
274
|
-
* for its default behavior and performance tuning tricks.
|
|
275
|
-
*/
|
|
276
|
-
export function parseAsync(src: string): Promise<SgRoot>
|
|
277
|
-
/** Get the `kind` number from its string name. */
|
|
278
|
-
export function kind(kindName: string): number
|
|
279
|
-
/** Compile a string to ast-grep Pattern. */
|
|
280
|
-
export function pattern(pattern: string): NapiConfig
|
|
281
|
-
/**
|
|
282
|
-
* Discover and parse multiple files in Rust.
|
|
283
|
-
* `config` specifies the file path and matcher.
|
|
284
|
-
* `callback` will receive matching nodes found in a file.
|
|
285
|
-
*/
|
|
286
|
-
export function findInFiles(config: FindConfig, callback: (err: null | Error, result: SgNode[]) => void): Promise<number>
|
|
287
|
-
}
|
|
7
|
+
//-----Runtime Value Export!-----//
|
|
8
|
+
export { SgRoot, SgNode } from './types/sgnode'
|
|
9
|
+
export { Lang } from './types/lang'
|
|
10
|
+
export {
|
|
11
|
+
parseFiles,
|
|
12
|
+
parse,
|
|
13
|
+
parseAsync,
|
|
14
|
+
kind,
|
|
15
|
+
pattern,
|
|
16
|
+
findInFiles,
|
|
17
|
+
} from './types/api'
|
|
18
|
+
// deprecated
|
|
19
|
+
export * from './types/deprecated'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ast-grep/napi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Search and Rewrite code at large scale using precise AST pattern",
|
|
5
5
|
"homepage": "https://ast-grep.github.io",
|
|
6
6
|
"main": "index.js",
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
"rewrite"
|
|
15
15
|
],
|
|
16
16
|
"files": [
|
|
17
|
-
"manual.d.ts",
|
|
18
17
|
"index.d.ts",
|
|
19
|
-
"index.js"
|
|
18
|
+
"index.js",
|
|
19
|
+
"types/*.ts",
|
|
20
|
+
"lang/*.ts"
|
|
20
21
|
],
|
|
21
22
|
"napi": {
|
|
22
23
|
"name": "ast-grep-napi",
|
|
@@ -41,16 +42,23 @@
|
|
|
41
42
|
},
|
|
42
43
|
"scripts": {
|
|
43
44
|
"artifacts": "napi artifacts",
|
|
44
|
-
"build": "napi build --no-const-enum --platform --release",
|
|
45
|
-
"build:debug": "napi build --no-const-enum --platform",
|
|
45
|
+
"build": "napi build --no-const-enum --dts ignore.d.ts --platform --release",
|
|
46
|
+
"build:debug": "napi build --no-const-enum --dts ignore.d.ts --platform",
|
|
46
47
|
"prepublishOnly": "napi prepublish -t npm --skip-gh-release",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
48
|
+
"pretest": "ts-node scripts/generateTypes.ts --test-only",
|
|
49
|
+
"test": "tsc --noEmit && ava",
|
|
50
|
+
"version": "napi version",
|
|
51
|
+
"lint": "biome lint --fix && biome format --write",
|
|
52
|
+
"typegen": "ts-node scripts/generateTypes.ts"
|
|
49
53
|
},
|
|
50
54
|
"devDependencies": {
|
|
55
|
+
"@ast-grep/napi": "0.31.1",
|
|
56
|
+
"@biomejs/biome": "1.9.4",
|
|
51
57
|
"@napi-rs/cli": "2.18.4",
|
|
58
|
+
"@types/node": "^22.10.2",
|
|
52
59
|
"ava": "6.2.0",
|
|
53
60
|
"chalk": "5.3.0",
|
|
61
|
+
"smol-toml": "^1.3.1",
|
|
54
62
|
"ts-node": "10.9.2",
|
|
55
63
|
"typescript": "5.7.2"
|
|
56
64
|
},
|
|
@@ -68,14 +76,14 @@
|
|
|
68
76
|
}
|
|
69
77
|
},
|
|
70
78
|
"optionalDependencies": {
|
|
71
|
-
"@ast-grep/napi-win32-x64-msvc": "0.
|
|
72
|
-
"@ast-grep/napi-darwin-x64": "0.
|
|
73
|
-
"@ast-grep/napi-linux-x64-gnu": "0.
|
|
74
|
-
"@ast-grep/napi-win32-ia32-msvc": "0.
|
|
75
|
-
"@ast-grep/napi-darwin-arm64": "0.
|
|
76
|
-
"@ast-grep/napi-win32-arm64-msvc": "0.
|
|
77
|
-
"@ast-grep/napi-linux-arm64-gnu": "0.
|
|
78
|
-
"@ast-grep/napi-linux-arm64-musl": "0.
|
|
79
|
-
"@ast-grep/napi-linux-x64-musl": "0.
|
|
79
|
+
"@ast-grep/napi-win32-x64-msvc": "0.32.0",
|
|
80
|
+
"@ast-grep/napi-darwin-x64": "0.32.0",
|
|
81
|
+
"@ast-grep/napi-linux-x64-gnu": "0.32.0",
|
|
82
|
+
"@ast-grep/napi-win32-ia32-msvc": "0.32.0",
|
|
83
|
+
"@ast-grep/napi-darwin-arm64": "0.32.0",
|
|
84
|
+
"@ast-grep/napi-win32-arm64-msvc": "0.32.0",
|
|
85
|
+
"@ast-grep/napi-linux-arm64-gnu": "0.32.0",
|
|
86
|
+
"@ast-grep/napi-linux-arm64-musl": "0.32.0",
|
|
87
|
+
"@ast-grep/napi-linux-x64-musl": "0.32.0"
|
|
80
88
|
}
|
|
81
89
|
}
|
package/types/api.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SgNode, SgRoot } from './sgnode'
|
|
2
|
+
import type { NapiConfig, FindConfig, FileOption } from './config'
|
|
3
|
+
import type { Lang } from './lang'
|
|
4
|
+
import type { NamedKinds, TypesMap } from './staticTypes'
|
|
5
|
+
|
|
6
|
+
export declare function parseFiles<M extends TypesMap>(
|
|
7
|
+
paths: Array<string> | FileOption,
|
|
8
|
+
callback: (err: null | Error, result: SgRoot<M>) => void,
|
|
9
|
+
): Promise<number>
|
|
10
|
+
/** Parse a string to an ast-grep instance */
|
|
11
|
+
export declare function parse<M extends TypesMap>(
|
|
12
|
+
lang: Lang,
|
|
13
|
+
src: string,
|
|
14
|
+
): SgRoot<M>
|
|
15
|
+
/**
|
|
16
|
+
* Parse a string to an ast-grep instance asynchronously in threads.
|
|
17
|
+
* It utilize multiple CPU cores when **concurrent processing sources**.
|
|
18
|
+
* However, spawning excessive many threads may backfire.
|
|
19
|
+
* Please refer to libuv doc, nodejs' underlying runtime
|
|
20
|
+
* for its default behavior and performance tuning tricks.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseAsync<M extends TypesMap>(
|
|
23
|
+
lang: Lang,
|
|
24
|
+
src: string,
|
|
25
|
+
): Promise<SgRoot<M>>
|
|
26
|
+
/** Get the `kind` number from its string name. */
|
|
27
|
+
export declare function kind<M extends TypesMap>(
|
|
28
|
+
lang: Lang,
|
|
29
|
+
kindName: NamedKinds<M>,
|
|
30
|
+
): number
|
|
31
|
+
/** Compile a string to ast-grep Pattern. */
|
|
32
|
+
export declare function pattern<M extends TypesMap>(
|
|
33
|
+
lang: Lang,
|
|
34
|
+
pattern: string,
|
|
35
|
+
): NapiConfig<M>
|
|
36
|
+
/**
|
|
37
|
+
* Discover and parse multiple files in Rust.
|
|
38
|
+
* `lang` specifies the language.
|
|
39
|
+
* `config` specifies the file path and matcher.
|
|
40
|
+
* `callback` will receive matching nodes found in a file.
|
|
41
|
+
*/
|
|
42
|
+
export declare function findInFiles<M extends TypesMap>(
|
|
43
|
+
lang: Lang,
|
|
44
|
+
config: FindConfig<M>,
|
|
45
|
+
callback: (err: null | Error, result: SgNode<M>[]) => void,
|
|
46
|
+
): Promise<number>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Rule } from './rule'
|
|
2
|
+
import type { Lang } from './lang'
|
|
3
|
+
import type { TypesMap } from './staticTypes'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Rule configuration similar to YAML
|
|
7
|
+
* See https://ast-grep.github.io/reference/yaml.html
|
|
8
|
+
*/
|
|
9
|
+
export interface NapiConfig<M extends TypesMap = TypesMap> {
|
|
10
|
+
/** The rule object, see https://ast-grep.github.io/reference/rule.html */
|
|
11
|
+
rule: Rule<M>
|
|
12
|
+
/** See https://ast-grep.github.io/guide/rule-config.html#constraints */
|
|
13
|
+
constraints?: Record<string, Rule<M>>
|
|
14
|
+
/** Available languages: html, css, js, jsx, ts, tsx */
|
|
15
|
+
language?: Lang
|
|
16
|
+
/**
|
|
17
|
+
* transform is NOT useful in JavaScript. You can use JS code to directly transform the result.
|
|
18
|
+
* https://ast-grep.github.io/reference/yaml.html#transform
|
|
19
|
+
*/
|
|
20
|
+
transform?: unknown
|
|
21
|
+
/** https://ast-grep.github.io/guide/rule-config/utility-rule.html */
|
|
22
|
+
utils?: Record<string, Rule<M>>
|
|
23
|
+
}
|
|
24
|
+
export interface FileOption {
|
|
25
|
+
paths: Array<string>
|
|
26
|
+
languageGlobs: Record<string, Array<string>>
|
|
27
|
+
}
|
|
28
|
+
export interface FindConfig<M extends TypesMap = TypesMap> {
|
|
29
|
+
/** specify the file paths to recursively find files */
|
|
30
|
+
paths: Array<string>
|
|
31
|
+
/** a Rule object to find what nodes will match */
|
|
32
|
+
matcher: NapiConfig<M>
|
|
33
|
+
/**
|
|
34
|
+
* An list of pattern globs to treat of certain files in the specified language.
|
|
35
|
+
* eg. ['*.vue', '*.svelte'] for html.findFiles, or ['*.ts'] for tsx.findFiles.
|
|
36
|
+
* It is slightly different from https://ast-grep.github.io/reference/sgconfig.html#languageglobs
|
|
37
|
+
*/
|
|
38
|
+
languageGlobs?: Array<string>
|
|
39
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { SgRoot, SgNode } from './sgnode'
|
|
2
|
+
import type { NapiConfig, FindConfig } from './config'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated language specific objects are deprecated
|
|
6
|
+
* use the equivalent functions like `parse` in @ast-grep/napi
|
|
7
|
+
*/
|
|
8
|
+
export declare namespace html {
|
|
9
|
+
/** @deprecated use `parse(Lang.Html, src)` instead */
|
|
10
|
+
export function parse(src: string): SgRoot
|
|
11
|
+
/** @deprecated use `parseAsync(Lang.Html, src)` instead */
|
|
12
|
+
export function parseAsync(src: string): Promise<SgRoot>
|
|
13
|
+
/** @deprecated use `kind(Lang.Html, kindName)` instead */
|
|
14
|
+
export function kind(kindName: string): number
|
|
15
|
+
/** @deprecated use `pattern(Lang.Html, p)` instead */
|
|
16
|
+
export function pattern(pattern: string): NapiConfig
|
|
17
|
+
/** @deprecated use `findInFiles(Lang.Html, config, callback)` instead */
|
|
18
|
+
export function findInFiles(
|
|
19
|
+
config: FindConfig,
|
|
20
|
+
callback: (err: null | Error, result: SgNode[]) => void,
|
|
21
|
+
): Promise<number>
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated language specific objects are deprecated
|
|
25
|
+
* use the equivalent functions like `parse` in @ast-grep/napi
|
|
26
|
+
*/
|
|
27
|
+
export declare namespace js {
|
|
28
|
+
/** @deprecated use `parse(Lang.JavaScript, src)` instead */
|
|
29
|
+
export function parse(src: string): SgRoot
|
|
30
|
+
/** @deprecated use `parseAsync(Lang.JavaScript, src)` instead */
|
|
31
|
+
export function parseAsync(src: string): Promise<SgRoot>
|
|
32
|
+
/** @deprecated use `kind(Lang.JavaScript, kindName)` instead */
|
|
33
|
+
export function kind(kindName: string): number
|
|
34
|
+
/** @deprecated use `pattern(Lang.JavaScript, p)` instead */
|
|
35
|
+
export function pattern(pattern: string): NapiConfig
|
|
36
|
+
/** @deprecated use `findInFiles(Lang.JavaScript, config, callback)` instead */
|
|
37
|
+
export function findInFiles(
|
|
38
|
+
config: FindConfig,
|
|
39
|
+
callback: (err: null | Error, result: SgNode[]) => void,
|
|
40
|
+
): Promise<number>
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated language specific objects are deprecated
|
|
44
|
+
* use the equivalent functions like `parse` in @ast-grep/napi
|
|
45
|
+
*/
|
|
46
|
+
export declare namespace jsx {
|
|
47
|
+
/** @deprecated use `parse(Lang.JavaScript, src)` instead */
|
|
48
|
+
export function parse(src: string): SgRoot
|
|
49
|
+
/** @deprecated use `parseAsync(Lang.JavaScript, src)` instead */
|
|
50
|
+
export function parseAsync(src: string): Promise<SgRoot>
|
|
51
|
+
/** @deprecated use `kind(Lang.JavaScript, kindName)` instead */
|
|
52
|
+
export function kind(kindName: string): number
|
|
53
|
+
/** @deprecated use `pattern(Lang.JavaScript, p)` instead */
|
|
54
|
+
export function pattern(pattern: string): NapiConfig
|
|
55
|
+
/** @deprecated use `findInFiles(Lang.JavaScript, config, callback)` instead */
|
|
56
|
+
export function findInFiles(
|
|
57
|
+
config: FindConfig,
|
|
58
|
+
callback: (err: null | Error, result: SgNode[]) => void,
|
|
59
|
+
): Promise<number>
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* @deprecated language specific objects are deprecated
|
|
63
|
+
* use the equivalent functions like `parse` in @ast-grep/napi
|
|
64
|
+
*/
|
|
65
|
+
export declare namespace ts {
|
|
66
|
+
/** @deprecated use `parse(Lang.TypeScript, src)` instead */
|
|
67
|
+
export function parse(src: string): SgRoot
|
|
68
|
+
/** @deprecated use `parseAsync(Lang.TypeScript, src)` instead */
|
|
69
|
+
export function parseAsync(src: string): Promise<SgRoot>
|
|
70
|
+
/** @deprecated use `kind(Lang.TypeScript, kindName)` instead */
|
|
71
|
+
export function kind(kindName: string): number
|
|
72
|
+
/** @deprecated use `pattern(Lang.TypeScript, p)` instead */
|
|
73
|
+
export function pattern(pattern: string): NapiConfig
|
|
74
|
+
/** @deprecated use `findInFiles(Lang.TypeScript, config, callback)` instead */
|
|
75
|
+
export function findInFiles(
|
|
76
|
+
config: FindConfig,
|
|
77
|
+
callback: (err: null | Error, result: SgNode[]) => void,
|
|
78
|
+
): Promise<number>
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* @deprecated language specific objects are deprecated
|
|
82
|
+
* use the equivalent functions like `parse` in @ast-grep/napi
|
|
83
|
+
*/
|
|
84
|
+
export declare namespace tsx {
|
|
85
|
+
/** @deprecated use `parse(Lang.Tsx, src)` instead */
|
|
86
|
+
export function parse(src: string): SgRoot
|
|
87
|
+
/** @deprecated use `parseAsync(Lang.Tsx, src)` instead */
|
|
88
|
+
export function parseAsync(src: string): Promise<SgRoot>
|
|
89
|
+
/** @deprecated use `kind(Lang.Tsx, kindName)` instead */
|
|
90
|
+
export function kind(kindName: string): number
|
|
91
|
+
/** @deprecated use `pattern(Lang.Tsx, p)` instead */
|
|
92
|
+
export function pattern(pattern: string): NapiConfig
|
|
93
|
+
/** @deprecated use `findInFiles(Lang.Tsx, config, callback)` instead */
|
|
94
|
+
export function findInFiles(
|
|
95
|
+
config: FindConfig,
|
|
96
|
+
callback: (err: null | Error, result: SgNode[]) => void,
|
|
97
|
+
): Promise<number>
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* @deprecated language specific objects are deprecated
|
|
101
|
+
* use the equivalent functions like `parse` in @ast-grep/napi
|
|
102
|
+
*/
|
|
103
|
+
export declare namespace css {
|
|
104
|
+
/** @deprecated use `parse(Lang.Css, src)` instead */
|
|
105
|
+
export function parse(src: string): SgRoot
|
|
106
|
+
/** @deprecated use `parseAsync(Lang.Css, src)` instead */
|
|
107
|
+
export function parseAsync(src: string): Promise<SgRoot>
|
|
108
|
+
/** @deprecated use `kind(Lang.Css, kindName)` instead */
|
|
109
|
+
export function kind(kindName: string): number
|
|
110
|
+
/** @deprecated use `pattern(Lang.Css, p)` instead */
|
|
111
|
+
export function pattern(pattern: string): NapiConfig
|
|
112
|
+
/** @deprecated use `findInFiles(Lang.Css, config, callback)` instead */
|
|
113
|
+
export function findInFiles(
|
|
114
|
+
config: FindConfig,
|
|
115
|
+
callback: (err: null | Error, result: SgNode[]) => void,
|
|
116
|
+
): Promise<number>
|
|
117
|
+
}
|
package/types/lang.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export enum Lang {
|
|
2
|
+
Html = 'Html',
|
|
3
|
+
JavaScript = 'JavaScript',
|
|
4
|
+
Tsx = 'Tsx',
|
|
5
|
+
Css = 'Css',
|
|
6
|
+
TypeScript = 'TypeScript',
|
|
7
|
+
Bash = 'Bash',
|
|
8
|
+
C = 'C',
|
|
9
|
+
Cpp = 'Cpp',
|
|
10
|
+
CSharp = 'CSharp',
|
|
11
|
+
Go = 'Go',
|
|
12
|
+
Elixir = 'Elixir',
|
|
13
|
+
Haskell = 'Haskell',
|
|
14
|
+
Java = 'Java',
|
|
15
|
+
Json = 'Json',
|
|
16
|
+
Kotlin = 'Kotlin',
|
|
17
|
+
Lua = 'Lua',
|
|
18
|
+
Php = 'Php',
|
|
19
|
+
Python = 'Python',
|
|
20
|
+
Ruby = 'Ruby',
|
|
21
|
+
Rust = 'Rust',
|
|
22
|
+
Scala = 'Scala',
|
|
23
|
+
Sql = 'Sql',
|
|
24
|
+
Swift = 'Swift',
|
|
25
|
+
Yaml = 'Yaml',
|
|
26
|
+
}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
| 'cst' | 'smart' | 'ast' | 'relaxed' | 'signature'
|
|
1
|
+
import type { TypesMap, NamedKinds } from './staticTypes'
|
|
3
2
|
|
|
4
|
-
export
|
|
3
|
+
export type Strictness = 'cst' | 'smart' | 'ast' | 'relaxed' | 'signature'
|
|
4
|
+
|
|
5
|
+
export interface PatternObject<M extends TypesMap = TypesMap> {
|
|
5
6
|
context: string
|
|
6
|
-
selector?:
|
|
7
|
+
selector?: NamedKinds<M> // only named node types
|
|
7
8
|
strictness?: Strictness
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export type PatternStyle =
|
|
11
|
+
export type PatternStyle<M extends TypesMap = TypesMap> =
|
|
12
|
+
| string
|
|
13
|
+
| PatternObject<M>
|
|
11
14
|
|
|
12
|
-
export interface Relation extends Rule {
|
|
15
|
+
export interface Relation<M extends TypesMap = TypesMap> extends Rule<M> {
|
|
13
16
|
/**
|
|
14
17
|
* Specify how relational rule will stop relative to the target node.
|
|
15
18
|
*/
|
|
16
|
-
stopBy?: 'neighbor' | 'end' | Rule
|
|
19
|
+
stopBy?: 'neighbor' | 'end' | Rule<M>
|
|
17
20
|
/** Specify the tree-sitter field in parent node. Only available in has/inside rule. */
|
|
18
21
|
field?: string
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
export interface NthChildObject {
|
|
24
|
+
export interface NthChildObject<M extends TypesMap = TypesMap> {
|
|
22
25
|
/** The position in nodes' sibling list. It can be a number of An+B string */
|
|
23
26
|
position: string | number
|
|
24
|
-
ofRule?: Rule
|
|
27
|
+
ofRule?: Rule<M>
|
|
25
28
|
reverse?: boolean
|
|
26
29
|
}
|
|
27
30
|
|
|
@@ -31,11 +34,14 @@ export interface NthChildObject {
|
|
|
31
34
|
* * string: An + B style string like CSS nth-child selector.
|
|
32
35
|
* * object: An object with `position` and `ofRule` fields.
|
|
33
36
|
*/
|
|
34
|
-
export type NthChild
|
|
37
|
+
export type NthChild<M extends TypesMap = TypesMap> =
|
|
38
|
+
| number
|
|
39
|
+
| string
|
|
40
|
+
| NthChildObject<M>
|
|
35
41
|
|
|
36
42
|
export interface Position {
|
|
37
|
-
/** 0-indexed
|
|
38
|
-
|
|
43
|
+
/** 0-indexed line number. */
|
|
44
|
+
line: number
|
|
39
45
|
/** 0-indexed column number. */
|
|
40
46
|
column: number
|
|
41
47
|
}
|
|
@@ -45,11 +51,11 @@ export interface Range {
|
|
|
45
51
|
end: Position
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
export interface Rule {
|
|
54
|
+
export interface Rule<M extends TypesMap = TypesMap> {
|
|
49
55
|
/** A pattern string or a pattern object. */
|
|
50
|
-
pattern?: PatternStyle
|
|
56
|
+
pattern?: PatternStyle<M>
|
|
51
57
|
/** The kind name of the node to match. You can look up code's kind names in playground. */
|
|
52
|
-
kind?:
|
|
58
|
+
kind?: NamedKinds<M>
|
|
53
59
|
/** The exact range of the node in the source code. */
|
|
54
60
|
range?: Range
|
|
55
61
|
/** A Rust regular expression to match the node's text. https://docs.rs/regex/latest/regex/#syntax */
|
|
@@ -57,36 +63,36 @@ export interface Rule {
|
|
|
57
63
|
/**
|
|
58
64
|
* `nthChild` accepts number, string or object.
|
|
59
65
|
* It specifies the position in nodes' sibling list. */
|
|
60
|
-
nthChild?: NthChild
|
|
66
|
+
nthChild?: NthChild<M>
|
|
61
67
|
|
|
62
68
|
// relational
|
|
63
69
|
/**
|
|
64
70
|
* `inside` accepts a relational rule object.
|
|
65
71
|
* the target node must appear inside of another node matching the `inside` sub-rule. */
|
|
66
|
-
inside?: Relation
|
|
72
|
+
inside?: Relation<M>
|
|
67
73
|
/**
|
|
68
74
|
* `has` accepts a relational rule object.
|
|
69
75
|
* the target node must has a descendant node matching the `has` sub-rule. */
|
|
70
|
-
has?: Relation
|
|
76
|
+
has?: Relation<M>
|
|
71
77
|
/**
|
|
72
78
|
* `precedes` accepts a relational rule object.
|
|
73
79
|
* the target node must appear before another node matching the `precedes` sub-rule. */
|
|
74
|
-
precedes?: Relation
|
|
80
|
+
precedes?: Relation<M>
|
|
75
81
|
/**
|
|
76
82
|
* `follows` accepts a relational rule object.
|
|
77
83
|
* the target node must appear after another node matching the `follows` sub-rule. */
|
|
78
|
-
follows?: Relation
|
|
84
|
+
follows?: Relation<M>
|
|
79
85
|
// composite
|
|
80
86
|
/**
|
|
81
87
|
* A list of sub rules and matches a node if all of sub rules match.
|
|
82
88
|
* The meta variables of the matched node contain all variables from the sub-rules. */
|
|
83
|
-
all?: Array<Rule
|
|
89
|
+
all?: Array<Rule<M>>
|
|
84
90
|
/**
|
|
85
91
|
* A list of sub rules and matches a node if any of sub rules match.
|
|
86
92
|
* The meta variables of the matched node only contain those of the matched sub-rule. */
|
|
87
|
-
any?: Array<Rule
|
|
93
|
+
any?: Array<Rule<M>>
|
|
88
94
|
/** A single sub-rule and matches a node if the sub rule does not match. */
|
|
89
|
-
not?: Rule
|
|
95
|
+
not?: Rule<M>
|
|
90
96
|
/** A utility rule id and matches a node if the utility rule matches. */
|
|
91
97
|
matches?: string
|
|
92
|
-
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FieldNames,
|
|
3
|
+
TypesInField,
|
|
4
|
+
TypesMap,
|
|
5
|
+
ExtractField,
|
|
6
|
+
Kinds,
|
|
7
|
+
NodeFieldInfo,
|
|
8
|
+
RootKind,
|
|
9
|
+
} from './staticTypes'
|
|
10
|
+
import type { NapiConfig } from './config'
|
|
11
|
+
|
|
12
|
+
export interface Edit {
|
|
13
|
+
/** The start position of the edit */
|
|
14
|
+
startPos: number
|
|
15
|
+
/** The end position of the edit */
|
|
16
|
+
endPos: number
|
|
17
|
+
/** The text to be inserted */
|
|
18
|
+
insertedText: string
|
|
19
|
+
}
|
|
20
|
+
export interface Pos {
|
|
21
|
+
/** line number starting from 0 */
|
|
22
|
+
line: number
|
|
23
|
+
/** column number starting from 0 */
|
|
24
|
+
column: number
|
|
25
|
+
/** byte offset of the position */
|
|
26
|
+
index: number
|
|
27
|
+
}
|
|
28
|
+
export interface Range {
|
|
29
|
+
/** starting position of the range */
|
|
30
|
+
start: Pos
|
|
31
|
+
/** ending position of the range */
|
|
32
|
+
end: Pos
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export declare class SgNode<
|
|
36
|
+
M extends TypesMap = TypesMap,
|
|
37
|
+
out T extends Kinds<M> = Kinds<M>,
|
|
38
|
+
> {
|
|
39
|
+
range(): Range
|
|
40
|
+
isLeaf(): boolean
|
|
41
|
+
isNamed(): boolean
|
|
42
|
+
isNamedLeaf(): boolean
|
|
43
|
+
/** Returns the string name of the node kind */
|
|
44
|
+
kind(): T
|
|
45
|
+
readonly kindToRefine: T
|
|
46
|
+
/** Check if the node is the same kind as the given `kind` string */
|
|
47
|
+
is<K extends Kinds<M>>(kind: K): this is SgNode<M, K>
|
|
48
|
+
text(): string
|
|
49
|
+
matches(m: string): boolean
|
|
50
|
+
inside(m: string): boolean
|
|
51
|
+
has(m: string): boolean
|
|
52
|
+
precedes(m: string): boolean
|
|
53
|
+
follows(m: string): boolean
|
|
54
|
+
getMatch<K extends Kinds<M>>(m: string): RefineNode<M, K> | null
|
|
55
|
+
getMultipleMatches(m: string): Array<SgNode<M>>
|
|
56
|
+
getTransformed(m: string): string | null
|
|
57
|
+
/** Returns the node's SgRoot */
|
|
58
|
+
getRoot(): SgRoot<M>
|
|
59
|
+
children(): Array<SgNode<M>>
|
|
60
|
+
/** Returns the node's id */
|
|
61
|
+
id(): number
|
|
62
|
+
find<K extends Kinds<M>>(
|
|
63
|
+
matcher: string | number | NapiConfig<M>,
|
|
64
|
+
): RefineNode<M, K> | null
|
|
65
|
+
findAll<K extends Kinds<M>>(
|
|
66
|
+
matcher: string | number | NapiConfig<M>,
|
|
67
|
+
): Array<RefineNode<M, K>>
|
|
68
|
+
/** Finds the first child node in the `field` */
|
|
69
|
+
field<F extends FieldNames<M[T]>>(name: F): FieldNode<M, T, F>
|
|
70
|
+
/** Finds all the children nodes in the `field` */
|
|
71
|
+
fieldChildren<F extends FieldNames<M[T]>>(
|
|
72
|
+
name: F,
|
|
73
|
+
): Exclude<FieldNode<M, T, F>, null>[]
|
|
74
|
+
parent<K extends Kinds<M>>(): RefineNode<M, K> | null
|
|
75
|
+
child<K extends Kinds<M>>(nth: number): RefineNode<M, K> | null
|
|
76
|
+
ancestors(): Array<SgNode<M>>
|
|
77
|
+
next<K extends Kinds<M>>(): RefineNode<M, K> | null
|
|
78
|
+
nextAll(): Array<SgNode<M>>
|
|
79
|
+
prev<K extends Kinds<M>>(): RefineNode<M, K> | null
|
|
80
|
+
prevAll(): Array<SgNode<M>>
|
|
81
|
+
replace(text: string): Edit
|
|
82
|
+
commitEdits(edits: Array<Edit>): string
|
|
83
|
+
}
|
|
84
|
+
/** Represents the parsed tree of code. */
|
|
85
|
+
export declare class SgRoot<M extends TypesMap = TypesMap> {
|
|
86
|
+
/** Returns the root SgNode of the ast-grep instance. */
|
|
87
|
+
root(): SgNode<M, RootKind<M>>
|
|
88
|
+
/**
|
|
89
|
+
* Returns the path of the file if it is discovered by ast-grep's `findInFiles`.
|
|
90
|
+
* Returns `"anonymous"` if the instance is created by `lang.parse(source)`.
|
|
91
|
+
*/
|
|
92
|
+
filename(): string
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* if K contains string, return general SgNode. Otherwise,
|
|
97
|
+
* if K is a literal union, return a union of SgNode of each kind.
|
|
98
|
+
*/
|
|
99
|
+
type RefineNode<M extends TypesMap, K> = string extends K
|
|
100
|
+
? SgNode<M>
|
|
101
|
+
: K extends Kinds<M>
|
|
102
|
+
? SgNode<M, K>
|
|
103
|
+
: never
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* return the SgNode of the field in the node.
|
|
107
|
+
*/
|
|
108
|
+
// F extends string is used to prevent noisy TS hover info
|
|
109
|
+
type FieldNode<
|
|
110
|
+
M extends TypesMap,
|
|
111
|
+
K extends Kinds<M>,
|
|
112
|
+
F extends FieldNames<M[K]>,
|
|
113
|
+
> = F extends string ? FieldNodeImpl<M, ExtractField<M[K], F>> : never
|
|
114
|
+
|
|
115
|
+
type FieldNodeImpl<M extends TypesMap, I extends NodeFieldInfo> = I extends {
|
|
116
|
+
required: true
|
|
117
|
+
}
|
|
118
|
+
? RefineNode<M, TypesInField<M, I>>
|
|
119
|
+
: RefineNode<M, TypesInField<M, I>> | null
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference
|
|
3
|
+
* https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
|
|
4
|
+
* Rust CLI Impl
|
|
5
|
+
* https://github.com/tree-sitter/tree-sitter/blob/f279d10aa2aca37c0004d84b2261685739f3cab8/cli/generate/src/node_types.rs#L35-L47
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface NodeBasicInfo {
|
|
9
|
+
type: string
|
|
10
|
+
named: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface NodeFieldInfo {
|
|
14
|
+
multiple: boolean
|
|
15
|
+
required: boolean
|
|
16
|
+
types: NodeBasicInfo[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface NodeType extends NodeBasicInfo {
|
|
20
|
+
root?: boolean
|
|
21
|
+
fields?: {
|
|
22
|
+
[fieldName: string]: NodeFieldInfo
|
|
23
|
+
}
|
|
24
|
+
children?: NodeFieldInfo
|
|
25
|
+
subtypes?: NodeBasicInfo[]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A map of key to NodeType.
|
|
30
|
+
* Note, the key is not necessary node's kind.
|
|
31
|
+
* it can be a rule representing a category of syntax nodes
|
|
32
|
+
* (e.g. “expression”, “type”, “declaration”).
|
|
33
|
+
* See reference above for more details.
|
|
34
|
+
*/
|
|
35
|
+
export interface TypesMap {
|
|
36
|
+
[key: string]: NodeType
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type FieldNames<N extends NodeType> = N extends { fields: infer F }
|
|
40
|
+
? keyof F
|
|
41
|
+
: string
|
|
42
|
+
|
|
43
|
+
export type ExtractField<
|
|
44
|
+
N extends NodeType,
|
|
45
|
+
F extends FieldNames<N>,
|
|
46
|
+
> = N['fields'] extends Record<F, NodeFieldInfo>
|
|
47
|
+
? N['fields'][F]
|
|
48
|
+
: NodeFieldInfo
|
|
49
|
+
|
|
50
|
+
// in case of empty types array, return string as fallback
|
|
51
|
+
type NoNever<T, Fallback = string> = [T] extends [never] ? Fallback : T
|
|
52
|
+
|
|
53
|
+
export type TypesInField<M extends TypesMap, I extends NodeFieldInfo> = NoNever<
|
|
54
|
+
ResolveType<M, I['types'][number]['type']>
|
|
55
|
+
>
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* resolve subtypes alias. see tree-sitter's reference
|
|
59
|
+
* e.g. like `expression` => `binary_expression` | `unary_expression` | ...
|
|
60
|
+
*/
|
|
61
|
+
type ResolveType<M extends TypesMap, K> = K extends keyof M
|
|
62
|
+
? M[K] extends { subtypes: infer S extends NodeBasicInfo[] }
|
|
63
|
+
? ResolveType<M, S[number]['type']>
|
|
64
|
+
: K
|
|
65
|
+
: K
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* All named nodes' kinds that are usable in ast-grep rule
|
|
69
|
+
* NOTE: SgNode can return kind not in this list
|
|
70
|
+
*/
|
|
71
|
+
export type NamedKinds<M extends TypesMap> = ResolveType<M, keyof M>
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* See open-ended unions / string literal completion in TypeScript
|
|
75
|
+
* https://github.com/microsoft/TypeScript/issues/26277
|
|
76
|
+
* https://github.com/microsoft/TypeScript/issues/33471
|
|
77
|
+
*/
|
|
78
|
+
type LowPriorityKey = string & {}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A union of all named node kinds and a low priority key
|
|
82
|
+
* tree-sitter Kinds also include unnamed nodes which is not usable in rule
|
|
83
|
+
* NOTE: SgNode can return a string type if it is not a named node
|
|
84
|
+
*/
|
|
85
|
+
export type Kinds<M extends TypesMap = TypesMap> =
|
|
86
|
+
| NamedKinds<M>
|
|
87
|
+
| LowPriorityKey
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The root node kind of the tree.
|
|
91
|
+
*/
|
|
92
|
+
export type RootKind<M extends TypesMap> = NoNever<
|
|
93
|
+
Extract<M[keyof M], { root: true }>['type'],
|
|
94
|
+
Kinds<M>
|
|
95
|
+
>
|