@biomejs/runtime 2.6.3 → 2.6.5
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/package.json +2 -2
- package/plugin.d.ts +211 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@biomejs/runtime",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.5",
|
|
4
4
|
"description": "JavaScript APIs for Biome JS plugins",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test:types": "tsc --project tsconfig.json"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"typescript": "7.0.2"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@biomejs/biome": "^2.6.
|
|
37
|
+
"@biomejs/biome": "^2.6.5"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"provenance": true
|
package/plugin.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export * from "./semantic";
|
|
|
15
15
|
|
|
16
16
|
declare const queriedNode: unique symbol;
|
|
17
17
|
declare const nativeMutation: unique symbol;
|
|
18
|
+
declare const nodeKindSet: unique symbol;
|
|
19
|
+
declare const tokenKindSet: unique symbol;
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* A query matching AST nodes by their syntax kinds, created with {@link ast}.
|
|
@@ -290,6 +292,215 @@ export const factory: {
|
|
|
290
292
|
readonly token: (kind: JsTokenKind, text?: string) => JsAstToken;
|
|
291
293
|
};
|
|
292
294
|
|
|
295
|
+
/**
|
|
296
|
+
* A set of node kinds, created with {@link nodeKinds}.
|
|
297
|
+
*
|
|
298
|
+
* Testing membership with {@link NodeKindSet#has} reads the node's kind
|
|
299
|
+
* natively, which is cheaper than comparing `node.kind` strings. Build sets
|
|
300
|
+
* once at module scope and reuse them across `run()` calls.
|
|
301
|
+
*
|
|
302
|
+
* `K` is the exact union of kinds in the set, so a set of some kinds is not
|
|
303
|
+
* assignable to a set of other or more kinds. Functions that accept any node
|
|
304
|
+
* kind set should be generic, as in
|
|
305
|
+
* `function f<K extends keyof JsNodeByKind>(set: NodeKindSet<K>)`.
|
|
306
|
+
*/
|
|
307
|
+
export interface NodeKindSet<
|
|
308
|
+
in out K extends keyof JsNodeByKind = keyof JsNodeByKind,
|
|
309
|
+
> {
|
|
310
|
+
readonly [nodeKindSet]: true;
|
|
311
|
+
/**
|
|
312
|
+
* Returns whether `element` is a node whose kind is in this set.
|
|
313
|
+
*
|
|
314
|
+
* Returns `false` for tokens and for `undefined`, so optional fields and the
|
|
315
|
+
* results of childrenWithTokens() can be passed directly.
|
|
316
|
+
*
|
|
317
|
+
* For example, report calls and constructor calls:
|
|
318
|
+
* ```ts
|
|
319
|
+
* const CALLS = nodeKinds("JS_CALL_EXPRESSION", "JS_NEW_EXPRESSION");
|
|
320
|
+
*
|
|
321
|
+
* if (CALLS.has(statement.expression)) {
|
|
322
|
+
* registerDiagnostic(statement, "information", "This statement is a call.");
|
|
323
|
+
* }
|
|
324
|
+
* ```
|
|
325
|
+
*
|
|
326
|
+
* @throws {TypeError} If `element` is not a node, a token, or `undefined`.
|
|
327
|
+
*/
|
|
328
|
+
has(element: JsAstElement | undefined): element is JsNodeByKind[K];
|
|
329
|
+
/**
|
|
330
|
+
* Returns a new set with the kinds of this set and `other`. Neither set
|
|
331
|
+
* changes.
|
|
332
|
+
*
|
|
333
|
+
* For example, extend a shared set of calls:
|
|
334
|
+
* ```ts
|
|
335
|
+
* const CALLS = nodeKinds("JS_CALL_EXPRESSION", "JS_NEW_EXPRESSION");
|
|
336
|
+
* const CALLS_AND_IMPORTS = CALLS.union(nodeKinds("JS_IMPORT_CALL_EXPRESSION"));
|
|
337
|
+
* ```
|
|
338
|
+
*
|
|
339
|
+
* @throws {TypeError} If `other` is not a set returned by {@link nodeKinds},
|
|
340
|
+
* including when it is a token kind set.
|
|
341
|
+
*/
|
|
342
|
+
union<J extends keyof JsNodeByKind>(
|
|
343
|
+
other: NodeKindSet<J>,
|
|
344
|
+
): NodeKindSet<K | J>;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* A set of token kinds, created with {@link tokenKinds}.
|
|
349
|
+
*
|
|
350
|
+
* Testing membership with {@link TokenKindSet#has} reads the token's kind
|
|
351
|
+
* natively, which is cheaper than comparing `token.kind` strings. Build sets
|
|
352
|
+
* once at module scope and reuse them across `run()` calls.
|
|
353
|
+
*
|
|
354
|
+
* `K` is the exact union of kinds in the set, so a set of some kinds is not
|
|
355
|
+
* assignable to a set of other or more kinds. Functions that accept any token
|
|
356
|
+
* kind set should be generic, as in
|
|
357
|
+
* `function f<K extends JsAstToken["kind"]>(set: TokenKindSet<K>)`.
|
|
358
|
+
*/
|
|
359
|
+
export interface TokenKindSet<
|
|
360
|
+
in out K extends JsAstToken["kind"] = JsAstToken["kind"],
|
|
361
|
+
> {
|
|
362
|
+
readonly [tokenKindSet]: true;
|
|
363
|
+
/**
|
|
364
|
+
* Returns whether `element` is a token whose kind is in this set.
|
|
365
|
+
*
|
|
366
|
+
* Returns `false` for nodes and for `undefined`, so the results of
|
|
367
|
+
* childrenWithTokens() can be passed directly.
|
|
368
|
+
*
|
|
369
|
+
* For example, report loose equality operators:
|
|
370
|
+
* ```ts
|
|
371
|
+
* const LOOSE_EQUALITY = tokenKinds("EQ2", "NEQ");
|
|
372
|
+
*
|
|
373
|
+
* for (const element of binary.childrenWithTokens()) {
|
|
374
|
+
* if (LOOSE_EQUALITY.has(element)) {
|
|
375
|
+
* registerDiagnostic(binary, "warning", `Use strict equality instead of ${element.text}.`);
|
|
376
|
+
* }
|
|
377
|
+
* }
|
|
378
|
+
* ```
|
|
379
|
+
*
|
|
380
|
+
* @throws {TypeError} If `element` is not a node, a token, or `undefined`.
|
|
381
|
+
*/
|
|
382
|
+
has(
|
|
383
|
+
element: JsAstElement | undefined,
|
|
384
|
+
): element is JsAstToken & { readonly kind: K };
|
|
385
|
+
/**
|
|
386
|
+
* Returns a new set with the kinds of this set and `other`. Neither set
|
|
387
|
+
* changes.
|
|
388
|
+
*
|
|
389
|
+
* For example, combine equality and relational operators:
|
|
390
|
+
* ```ts
|
|
391
|
+
* const EQUALITY = tokenKinds("EQ2", "EQ3", "NEQ", "NEQ2");
|
|
392
|
+
* const COMPARISON = EQUALITY.union(tokenKinds("L_ANGLE", "R_ANGLE", "LTEQ", "GTEQ"));
|
|
393
|
+
* ```
|
|
394
|
+
*
|
|
395
|
+
* @throws {TypeError} If `other` is not a set returned by {@link tokenKinds},
|
|
396
|
+
* including when it is a node kind set.
|
|
397
|
+
*/
|
|
398
|
+
union<J extends JsAstToken["kind"]>(
|
|
399
|
+
other: TokenKindSet<J>,
|
|
400
|
+
): TokenKindSet<K | J>;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Creates a set of node kinds. Pass names listed in {@link JsNodeByKind}.
|
|
405
|
+
*
|
|
406
|
+
* Node kinds and token kinds are separate: passing a token kind such as
|
|
407
|
+
* `"IDENT"` throws. Use {@link tokenKinds} to build a set of token kinds.
|
|
408
|
+
*
|
|
409
|
+
* @throws {TypeError} If a kind is not a string or does not name a node kind.
|
|
410
|
+
*/
|
|
411
|
+
export function nodeKinds<K extends readonly (keyof JsNodeByKind)[]>(
|
|
412
|
+
...kinds: K
|
|
413
|
+
): NodeKindSet<K[number]>;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Creates a set of token kinds. Pass any name that {@link JsAstToken#kind}
|
|
417
|
+
* can return, such as `"IDENT"` or `"LET_KW"`.
|
|
418
|
+
*
|
|
419
|
+
* Node kinds and token kinds are separate: passing a node kind such as
|
|
420
|
+
* `"JS_CALL_EXPRESSION"` throws. Use {@link nodeKinds} to build a set of node
|
|
421
|
+
* kinds.
|
|
422
|
+
*
|
|
423
|
+
* @throws {TypeError} If a kind is not a string or does not name a token kind.
|
|
424
|
+
*/
|
|
425
|
+
export function tokenKinds<K extends readonly JsAstToken["kind"][]>(
|
|
426
|
+
...kinds: K
|
|
427
|
+
): TokenKindSet<K[number]>;
|
|
428
|
+
|
|
429
|
+
declare module "./js_ast" {
|
|
430
|
+
interface JsAstNode {
|
|
431
|
+
/**
|
|
432
|
+
* Returns a fresh array of the nodes inside this node whose kind is in
|
|
433
|
+
* `kinds`, in source order. This node itself is never included, even
|
|
434
|
+
* when its kind is in `kinds`.
|
|
435
|
+
*
|
|
436
|
+
* Biome searches the tree natively and creates JavaScript objects only
|
|
437
|
+
* for the matching nodes, which is much faster than visiting every node
|
|
438
|
+
* with children(). Returned nodes do not have stable JavaScript object
|
|
439
|
+
* identity.
|
|
440
|
+
*
|
|
441
|
+
* For example, report every `debugger` statement in a file:
|
|
442
|
+
* ```ts
|
|
443
|
+
* const DEBUGGER = nodeKinds("JS_DEBUGGER_STATEMENT");
|
|
444
|
+
*
|
|
445
|
+
* export const noDebugger = defineRule({
|
|
446
|
+
* query: ast("JS_MODULE"),
|
|
447
|
+
* run(root) {
|
|
448
|
+
* for (const statement of root.descendants(DEBUGGER)) {
|
|
449
|
+
* registerDiagnostic(statement, "warning", "Remove this debugger statement.");
|
|
450
|
+
* }
|
|
451
|
+
* },
|
|
452
|
+
* });
|
|
453
|
+
* ```
|
|
454
|
+
*
|
|
455
|
+
* @throws {TypeError} If `kinds` is not a set created with {@link nodeKinds}.
|
|
456
|
+
*/
|
|
457
|
+
descendants<K extends keyof JsNodeByKind>(
|
|
458
|
+
kinds: NodeKindSet<K>,
|
|
459
|
+
): readonly JsNodeByKind[K][];
|
|
460
|
+
/**
|
|
461
|
+
* Visits the nodes inside this node whose kind is in `kinds`, in source
|
|
462
|
+
* order. This node itself is never visited, even when its kind is in
|
|
463
|
+
* `kinds`.
|
|
464
|
+
*
|
|
465
|
+
* `enter` is called with each matching node before the nodes inside it,
|
|
466
|
+
* and `exit`, when provided, is called with the same object after them.
|
|
467
|
+
* Use the pair to track nesting, such as a stack of enclosing elements.
|
|
468
|
+
* Return `false` from `enter` to skip the nodes inside that node; `exit`
|
|
469
|
+
* is then not called for it. Any other return value continues the walk.
|
|
470
|
+
* An exception thrown by a callback stops the walk and is rethrown.
|
|
471
|
+
*
|
|
472
|
+
* Biome walks the tree natively and calls the functions only for the
|
|
473
|
+
* matching nodes, which is much faster than visiting every node with
|
|
474
|
+
* children().
|
|
475
|
+
*
|
|
476
|
+
* For example, report calls nested inside another call:
|
|
477
|
+
* ```ts
|
|
478
|
+
* const CALLS = nodeKinds("JS_CALL_EXPRESSION");
|
|
479
|
+
*
|
|
480
|
+
* let depth = 0;
|
|
481
|
+
* root.walk(
|
|
482
|
+
* CALLS,
|
|
483
|
+
* (call) => {
|
|
484
|
+
* if (depth > 0) registerDiagnostic(call, "information", "Nested call.");
|
|
485
|
+
* depth++;
|
|
486
|
+
* },
|
|
487
|
+
* () => {
|
|
488
|
+
* depth--;
|
|
489
|
+
* },
|
|
490
|
+
* );
|
|
491
|
+
* ```
|
|
492
|
+
*
|
|
493
|
+
* @throws {TypeError} If `kinds` is not a set created with {@link nodeKinds},
|
|
494
|
+
* or `enter` or `exit` is not a function.
|
|
495
|
+
*/
|
|
496
|
+
walk<K extends keyof JsNodeByKind>(
|
|
497
|
+
kinds: NodeKindSet<K>,
|
|
498
|
+
enter: (node: JsNodeByKind[K]) => unknown,
|
|
499
|
+
exit?: (node: JsNodeByKind[K]) => void,
|
|
500
|
+
): void;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
293
504
|
/** A suggested source edit attached to a diagnostic. */
|
|
294
505
|
export interface CodeFix {
|
|
295
506
|
readonly mutation: JsMutation;
|