Skip to content

Commit 61a0da8

Browse files
xeho91Rich-Harris
andauthored
feat: Expose more AST types from "svelte/compiler" (#14601)
* add missing `SvelteBoundary` in `ElementLike` * make union of AST types public and exportable with `AST` namespace * apply AST types change to codebase * changeset * manually generate types * Add `AttributeLike` type * export namespace `Css` inside `AST` * manually generate types again * exported `Css` -> `CSS` * `Css` -> `AST.CSS` * fix Prettier issue * Apply suggestions from code review --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 2e0dcd7 commit 61a0da8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+343
-303
lines changed

.changeset/short-papayas-relate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': minor
3+
---
4+
5+
feat: expose more AST types from `"svelte/compiler"`

packages/svelte/src/compiler/legacy.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @import { Expression } from 'estree' */
2-
/** @import { AST, SvelteNode, TemplateNode } from '#compiler' */
2+
/** @import { AST } from '#compiler' */
33
/** @import * as Legacy from './types/legacy-nodes.js' */
44
import { walk } from 'zimmerframe';
55
import {
@@ -11,7 +11,7 @@ import { extract_svelte_ignore } from './utils/extract_svelte_ignore.js';
1111

1212
/**
1313
* Some of the legacy Svelte AST nodes remove whitespace from the start and end of their children.
14-
* @param {TemplateNode[]} nodes
14+
* @param {AST.TemplateNode[]} nodes
1515
*/
1616
function remove_surrounding_whitespace_nodes(nodes) {
1717
const first = nodes.at(0);
@@ -40,7 +40,7 @@ function remove_surrounding_whitespace_nodes(nodes) {
4040
* @returns {Legacy.LegacyRoot}
4141
*/
4242
export function convert(source, ast) {
43-
const root = /** @type {SvelteNode | Legacy.LegacySvelteNode} */ (ast);
43+
const root = /** @type {AST.SvelteNode | Legacy.LegacySvelteNode} */ (ast);
4444

4545
return /** @type {Legacy.LegacyRoot} */ (
4646
walk(root, null, {

packages/svelte/src/compiler/migrate/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/** @import { Visitors } from 'zimmerframe' */
33
/** @import { ComponentAnalysis } from '../phases/types.js' */
44
/** @import { Scope, ScopeRoot } from '../phases/scope.js' */
5-
/** @import { AST, Binding, SvelteNode, ValidatedCompileOptions } from '#compiler' */
5+
/** @import { AST, Binding, ValidatedCompileOptions } from '#compiler' */
66
import MagicString from 'magic-string';
77
import { walk } from 'zimmerframe';
88
import { parse } from '../phases/1-parse/index.js';
@@ -479,7 +479,7 @@ export function migrate(source, { filename, use_ts } = {}) {
479479
* }} State
480480
*/
481481

482-
/** @type {Visitors<SvelteNode, State>} */
482+
/** @type {Visitors<AST.SvelteNode, State>} */
483483
const instance_script = {
484484
_(node, { state, next }) {
485485
// @ts-expect-error
@@ -1050,7 +1050,7 @@ function trim_block(state, start, end) {
10501050
}
10511051
}
10521052

1053-
/** @type {Visitors<SvelteNode, State>} */
1053+
/** @type {Visitors<AST.SvelteNode, State>} */
10541054
const template = {
10551055
Identifier(node, { state, path }) {
10561056
handle_identifier(node, state, path);
@@ -1410,7 +1410,7 @@ const template = {
14101410

14111411
/**
14121412
* @param {AST.RegularElement | AST.SvelteElement | AST.SvelteComponent | AST.Component | AST.SlotElement | AST.SvelteFragment} node
1413-
* @param {SvelteNode[]} path
1413+
* @param {AST.SvelteNode[]} path
14141414
* @param {State} state
14151415
*/
14161416
function migrate_slot_usage(node, path, state) {
@@ -1580,7 +1580,7 @@ function migrate_slot_usage(node, path, state) {
15801580
/**
15811581
* @param {VariableDeclarator} declarator
15821582
* @param {State} state
1583-
* @param {SvelteNode[]} path
1583+
* @param {AST.SvelteNode[]} path
15841584
*/
15851585
function extract_type_and_comment(declarator, state, path) {
15861586
const str = state.str;

packages/svelte/src/compiler/phases/1-parse/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { AST, TemplateNode } from '#compiler' */
1+
/** @import { AST } from '#compiler' */
22
// @ts-expect-error acorn type definitions are borked in the release we use
33
import { isIdentifierStart, isIdentifierChar } from 'acorn';
44
import fragment from './state/fragment.js';
@@ -28,7 +28,7 @@ export class Parser {
2828
/** Whether we're parsing in TypeScript mode */
2929
ts = false;
3030

31-
/** @type {TemplateNode[]} */
31+
/** @type {AST.TemplateNode[]} */
3232
stack = [];
3333

3434
/** @type {AST.Fragment[]} */

packages/svelte/src/compiler/phases/1-parse/read/script.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @import { Program } from 'estree' */
2-
/** @import { AST, Directive } from '#compiler' */
2+
/** @import { AST } from '#compiler' */
33
/** @import { Parser } from '../index.js' */
44
import * as acorn from '../acorn.js';
55
import { regex_not_newline_characters } from '../../patterns.js';
@@ -16,7 +16,7 @@ const ALLOWED_ATTRIBUTES = ['context', 'generics', 'lang', 'module'];
1616
/**
1717
* @param {Parser} parser
1818
* @param {number} start
19-
* @param {Array<AST.Attribute | AST.SpreadAttribute | Directive>} attributes
19+
* @param {Array<AST.Attribute | AST.SpreadAttribute | AST.Directive>} attributes
2020
* @returns {AST.Script}
2121
*/
2222
export function read_script(parser, start, attributes) {

packages/svelte/src/compiler/phases/1-parse/read/style.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { AST, Css, Directive } from '#compiler' */
1+
/** @import { AST } from '#compiler' */
22
/** @import { Parser } from '../index.js' */
33
import * as e from '../../../errors.js';
44

@@ -18,8 +18,8 @@ const REGEX_HTML_COMMENT_CLOSE = /-->/;
1818
/**
1919
* @param {Parser} parser
2020
* @param {number} start
21-
* @param {Array<AST.Attribute | AST.SpreadAttribute | Directive>} attributes
22-
* @returns {Css.StyleSheet}
21+
* @param {Array<AST.Attribute | AST.SpreadAttribute | AST.Directive>} attributes
22+
* @returns {AST.CSS.StyleSheet}
2323
*/
2424
export default function read_style(parser, start, attributes) {
2525
const content_start = parser.index;
@@ -49,7 +49,7 @@ export default function read_style(parser, start, attributes) {
4949
* @returns {any[]}
5050
*/
5151
function read_body(parser, close) {
52-
/** @type {Array<Css.Rule | Css.Atrule>} */
52+
/** @type {Array<AST.CSS.Rule | AST.CSS.Atrule>} */
5353
const children = [];
5454

5555
while (parser.index < parser.template.length) {
@@ -71,7 +71,7 @@ function read_body(parser, close) {
7171

7272
/**
7373
* @param {Parser} parser
74-
* @returns {Css.Atrule}
74+
* @returns {AST.CSS.Atrule}
7575
*/
7676
function read_at_rule(parser) {
7777
const start = parser.index;
@@ -81,7 +81,7 @@ function read_at_rule(parser) {
8181

8282
const prelude = read_value(parser);
8383

84-
/** @type {Css.Block | null} */
84+
/** @type {AST.CSS.Block | null} */
8585
let block = null;
8686

8787
if (parser.match('{')) {
@@ -104,7 +104,7 @@ function read_at_rule(parser) {
104104

105105
/**
106106
* @param {Parser} parser
107-
* @returns {Css.Rule}
107+
* @returns {AST.CSS.Rule}
108108
*/
109109
function read_rule(parser) {
110110
const start = parser.index;
@@ -126,10 +126,10 @@ function read_rule(parser) {
126126
/**
127127
* @param {Parser} parser
128128
* @param {boolean} [inside_pseudo_class]
129-
* @returns {Css.SelectorList}
129+
* @returns {AST.CSS.SelectorList}
130130
*/
131131
function read_selector_list(parser, inside_pseudo_class = false) {
132-
/** @type {Css.ComplexSelector[]} */
132+
/** @type {AST.CSS.ComplexSelector[]} */
133133
const children = [];
134134

135135
allow_comment_or_whitespace(parser);
@@ -162,18 +162,18 @@ function read_selector_list(parser, inside_pseudo_class = false) {
162162
/**
163163
* @param {Parser} parser
164164
* @param {boolean} [inside_pseudo_class]
165-
* @returns {Css.ComplexSelector}
165+
* @returns {AST.CSS.ComplexSelector}
166166
*/
167167
function read_selector(parser, inside_pseudo_class = false) {
168168
const list_start = parser.index;
169169

170-
/** @type {Css.RelativeSelector[]} */
170+
/** @type {AST.CSS.RelativeSelector[]} */
171171
const children = [];
172172

173173
/**
174-
* @param {Css.Combinator | null} combinator
174+
* @param {AST.CSS.Combinator | null} combinator
175175
* @param {number} start
176-
* @returns {Css.RelativeSelector}
176+
* @returns {AST.CSS.RelativeSelector}
177177
*/
178178
function create_selector(combinator, start) {
179179
return {
@@ -190,7 +190,7 @@ function read_selector(parser, inside_pseudo_class = false) {
190190
};
191191
}
192192

193-
/** @type {Css.RelativeSelector} */
193+
/** @type {AST.CSS.RelativeSelector} */
194194
let relative_selector = create_selector(null, parser.index);
195195

196196
while (parser.index < parser.template.length) {
@@ -247,7 +247,7 @@ function read_selector(parser, inside_pseudo_class = false) {
247247
} else if (parser.eat(':')) {
248248
const name = read_identifier(parser);
249249

250-
/** @type {null | Css.SelectorList} */
250+
/** @type {null | AST.CSS.SelectorList} */
251251
let args = null;
252252

253253
if (parser.eat('(')) {
@@ -372,7 +372,7 @@ function read_selector(parser, inside_pseudo_class = false) {
372372

373373
/**
374374
* @param {Parser} parser
375-
* @returns {Css.Combinator | null}
375+
* @returns {AST.CSS.Combinator | null}
376376
*/
377377
function read_combinator(parser) {
378378
const start = parser.index;
@@ -407,14 +407,14 @@ function read_combinator(parser) {
407407

408408
/**
409409
* @param {Parser} parser
410-
* @returns {Css.Block}
410+
* @returns {AST.CSS.Block}
411411
*/
412412
function read_block(parser) {
413413
const start = parser.index;
414414

415415
parser.eat('{', true);
416416

417-
/** @type {Array<Css.Declaration | Css.Rule | Css.Atrule>} */
417+
/** @type {Array<AST.CSS.Declaration | AST.CSS.Rule | AST.CSS.Atrule>} */
418418
const children = [];
419419

420420
while (parser.index < parser.template.length) {
@@ -441,7 +441,7 @@ function read_block(parser) {
441441
* Reads a declaration, rule or at-rule
442442
*
443443
* @param {Parser} parser
444-
* @returns {Css.Declaration | Css.Rule | Css.Atrule}
444+
* @returns {AST.CSS.Declaration | AST.CSS.Rule | AST.CSS.Atrule}
445445
*/
446446
function read_block_item(parser) {
447447
if (parser.match('@')) {
@@ -460,7 +460,7 @@ function read_block_item(parser) {
460460

461461
/**
462462
* @param {Parser} parser
463-
* @returns {Css.Declaration}
463+
* @returns {AST.CSS.Declaration}
464464
*/
465465
function read_declaration(parser) {
466466
const start = parser.index;

packages/svelte/src/compiler/phases/1-parse/state/element.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @import { Expression } from 'estree' */
2-
/** @import { AST, Directive, ElementLike, TemplateNode } from '#compiler' */
2+
/** @import { AST } from '#compiler' */
33
/** @import { Parser } from '../index.js' */
44
import { is_void } from '../../../../utils.js';
55
import read_expression from '../read/expression.js';
@@ -28,7 +28,7 @@ export const regex_valid_component_name =
2828
// (must start with uppercase letter if no dots, can contain dots)
2929
/^(?:\p{Lu}[$\u200c\u200d\p{ID_Continue}.]*|\p{ID_Start}[$\u200c\u200d\p{ID_Continue}]*(?:\.[$\u200c\u200d\p{ID_Continue}]+)+)$/u;
3030

31-
/** @type {Map<string, ElementLike['type']>} */
31+
/** @type {Map<string, AST.ElementLike['type']>} */
3232
const root_only_meta_tags = new Map([
3333
['svelte:head', 'SvelteHead'],
3434
['svelte:options', 'SvelteOptions'],
@@ -37,7 +37,7 @@ const root_only_meta_tags = new Map([
3737
['svelte:body', 'SvelteBody']
3838
]);
3939

40-
/** @type {Map<string, ElementLike['type']>} */
40+
/** @type {Map<string, AST.ElementLike['type']>} */
4141
const meta_tags = new Map([
4242
...root_only_meta_tags,
4343
['svelte:element', 'SvelteElement'],
@@ -137,7 +137,7 @@ export default function element(parser) {
137137
? 'SlotElement'
138138
: 'RegularElement';
139139

140-
/** @type {ElementLike} */
140+
/** @type {AST.ElementLike} */
141141
const element =
142142
type === 'RegularElement'
143143
? {
@@ -155,7 +155,7 @@ export default function element(parser) {
155155
path: []
156156
}
157157
}
158-
: /** @type {ElementLike} */ ({
158+
: /** @type {AST.ElementLike} */ ({
159159
type,
160160
start,
161161
end: -1,
@@ -358,7 +358,7 @@ export default function element(parser) {
358358
}
359359
}
360360

361-
/** @param {TemplateNode[]} stack */
361+
/** @param {AST.TemplateNode[]} stack */
362362
function parent_is_head(stack) {
363363
let i = stack.length;
364364
while (i--) {
@@ -369,7 +369,7 @@ function parent_is_head(stack) {
369369
return false;
370370
}
371371

372-
/** @param {TemplateNode[]} stack */
372+
/** @param {AST.TemplateNode[]} stack */
373373
function parent_is_shadowroot_template(stack) {
374374
// https://developer.chrome.com/docs/css-ui/declarative-shadow-dom#building_a_declarative_shadow_root
375375
let i = stack.length;
@@ -433,7 +433,7 @@ function read_static_attribute(parser) {
433433

434434
/**
435435
* @param {Parser} parser
436-
* @returns {AST.Attribute | AST.SpreadAttribute | Directive | null}
436+
* @returns {AST.Attribute | AST.SpreadAttribute | AST.Directive | null}
437437
*/
438438
function read_attribute(parser) {
439439
const start = parser.index;
@@ -564,7 +564,7 @@ function read_attribute(parser) {
564564
}
565565
}
566566

567-
/** @type {Directive} */
567+
/** @type {AST.Directive} */
568568
const directive = {
569569
start,
570570
end,

0 commit comments

Comments
 (0)