sveast 0.9.7 → 0.9.8
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/README.md +18 -3
- package/index.d.ts +48 -11
- package/package.json +1 -1
- package/scope.d.ts +48 -11
- package/scope.js +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ ast.fragment.nodes; // [Text, RegularElement]
|
|
|
35
35
|
| [`walk`, `visitorKeys`, `markupVisitorKeys`, `valueVisitorKeys`, `skipTypeWrappers`](#walknode-visitor-keys--void) | Visit, skip, stop at or replace nodes, in the whole AST, only the markup, or everything but TypeScript's types | `sveast`, `sveast/walk` |
|
|
36
36
|
| [`children`, `forEachChild`](#childrennode-keys--node-and-foreachchildnode-callback-keys--void) | A node's children, cached or without allocating | `sveast`, `sveast/walk` |
|
|
37
37
|
| [`isReference`](#isreferencenode-parent--boolean), [`extractIdentifiers`](#extractidentifierspattern--identifier) | Which identifiers are references, and which ones a pattern declares | `sveast`, `sveast/walk` |
|
|
38
|
-
| [`analyzeScopes`](#analyzescopesast--scopes) | Which declaration each name refers to, and every read and write of it | `sveast`, `sveast/scope` |
|
|
38
|
+
| [`analyzeScopes`](#analyzescopesast-options--scopes) | Which declaration each name refers to, and every read and write of it | `sveast`, `sveast/scope` |
|
|
39
39
|
| [`a11yWarnings`](#a11ywarningsast-options--a11ywarning) | svelte's accessibility warnings, without compiling | `sveast/a11y` |
|
|
40
40
|
| [`createLocator`, `locate`](#createlocatorsource--offset--position) | Lines and columns for the nodes you report, without parsing with `loc` | `sveast`, `sveast/walk` |
|
|
41
41
|
|
|
@@ -383,7 +383,7 @@ if (declaration.type === "VariableDeclaration") {
|
|
|
383
383
|
}
|
|
384
384
|
```
|
|
385
385
|
|
|
386
|
-
### `analyzeScopes(ast) => Scopes`
|
|
386
|
+
### `analyzeScopes(ast, options?) => Scopes`
|
|
387
387
|
|
|
388
388
|
Finds the scopes of a component, its scripts and markup together, or of a module: which declaration each name refers to, and where each binding is read, written or subscribed to. It resolves names as svelte's analyzer does, which `tests/scope.test.ts` checks on the corpus: on 12,548 components from the corpus, svelte's tests and the Svelte projects listed under parity, they agree on all 208,797 names they both resolve, but for a class expression's name inside its body, a snippet's own name and a `var` declared twice, where sveast follows JavaScript.
|
|
389
389
|
|
|
@@ -408,7 +408,7 @@ size?.references.some((reference) => reference.writes || reference.mutates); //
|
|
|
408
408
|
|
|
409
409
|
It returns:
|
|
410
410
|
|
|
411
|
-
- **`module`** and **`instance`**, the scopes of `<script module>` and `<script>` (one scope, for a module). A `Scope` has the `node` that makes it, its `parent`, its `declarations` by name, and `get(name)`, the binding a name refers to there, or `null` for a global.
|
|
411
|
+
- **`module`** and **`instance`**, the scopes of `<script module>` and `<script>` (one scope, for a module). A `Scope` has the `node` that makes it, its `parent`, its `declarations` by name, and `get(name)`, the binding a name refers to there, or `null` for a global. With `types: true`, its `types` holds its `type`, `interface` and type parameter bindings, and `getType(name)` is the binding a name refers to in a type.
|
|
412
412
|
- **`scopeOf(node)`**, the scope a node is in; `null` in a type, the `<style>` or another AST. The first call walks the AST again to record every node's scope, so a tool that only resolves names doesn't keep a map of every node.
|
|
413
413
|
- **`bindingOf(identifier)`**, the binding an `Identifier` declares or refers to; `null` for a global, a property key or a name in a type.
|
|
414
414
|
- **`referenceOf(identifier)`**, the `Reference` an `Identifier` is, to tell a read from a write or a store subscription; `null` for one that declares a binding or isn't a reference.
|
|
@@ -429,6 +429,21 @@ The markup's scopes are svelte's:
|
|
|
429
429
|
|
|
430
430
|
Names in TypeScript's types aren't references, and `type` and `interface` declare nothing; it skips them with `valueVisitorKeys`. Enums, enum members and namespaces are declared. It doesn't change the AST, and takes less than half as long as parsing it.
|
|
431
431
|
|
|
432
|
+
| Option | Default | Description |
|
|
433
|
+
|:---|:---|:---|
|
|
434
|
+
| `types` | `false` | Resolve the names in types too, for a tool that asks which declarations some code uses, such as one that copies a statement with the imports it needs. |
|
|
435
|
+
|
|
436
|
+
With `types: true`, `type` and `interface` declare bindings of those kinds, and a type parameter or `infer U` one of kind `"type-param"`, in a scope's `types`, apart from its values, so `type A` and `const A` are two bindings. A name in a type is a `Reference` with `type: true` that neither reads, writes nor mutates: `A` in `let a: A`, `a` in `typeof a`, `I` in `implements I` and `extends I`, `N` in `N.T`, and the local name in `export type { A }`. A name in a type refers to a type, an import, a class or an enum; `typeof a` to a value; `N` in `N.T` to a namespace, an enum or an import, so `import type { A }` and `import { type A }` get the references. Property and method names in type literals and interfaces aren't references, but for a computed key's value. Type parameters are in scope for their function, class, method, type alias, interface or function type, `infer U` for its conditional type's true branch, and the parameters of a function type or signature are bindings of kind `"param"`, for `typeof x` and `x is T`. `<script generics="...">`'s names aren't declared. The value references are those it finds without `types`.
|
|
437
|
+
|
|
438
|
+
```ts
|
|
439
|
+
const ast = parse(`<script lang="ts">
|
|
440
|
+
import type { DataTableHeader } from "carbon-components-svelte";
|
|
441
|
+
let headers: DataTableHeader[] = [];
|
|
442
|
+
</script>`);
|
|
443
|
+
const { instance } = analyzeScopes(ast, { types: true });
|
|
444
|
+
instance.get("DataTableHeader")?.references[0]?.type; // true
|
|
445
|
+
```
|
|
446
|
+
|
|
432
447
|
### `a11yWarnings(ast, options?) => A11yWarning[]`
|
|
433
448
|
|
|
434
449
|
From `sveast/a11y`. The `a11y_…` warnings svelte's compiler gives for a component, with the same `code`, `message` and offsets, and without the ones a `<!-- svelte-ignore -->` comment before an element, or one of its ancestors, silences. For a linter that already has the AST: on Carbon's 2,202 components it takes 60 ms, against 735 ms for `compile(source, { generate: false })`. It loads neither acorn nor the parser.
|
package/index.d.ts
CHANGED
|
@@ -2051,7 +2051,18 @@ export declare function parseSections(source: string, options?: ParseOptions): A
|
|
|
2051
2051
|
export declare function isRunesMode(source: string): boolean;
|
|
2052
2052
|
|
|
2053
2053
|
/** How a {@link Binding} is declared. */
|
|
2054
|
-
export type BindingKind = "import" | "var" | "let" | "const" | "using" | "function" | "class" | "enum" | "enum-member" | "namespace" | "param" | "catch" | "reactive" | "each" | "each-index" | "let-directive" | "snippet" | "snippet-param" | "const-tag" | "await-value" | "await-error";
|
|
2054
|
+
export type BindingKind = "import" | "var" | "let" | "const" | "using" | "function" | "class" | "enum" | "enum-member" | "namespace" | "param" | "catch" | "reactive" | "each" | "each-index" | "let-directive" | "snippet" | "snippet-param" | "const-tag" | "await-value" | "await-error" | "type" | "interface" | "type-param";
|
|
2055
|
+
|
|
2056
|
+
/** Options for {@link analyzeScopes}. */
|
|
2057
|
+
export interface AnalyzeScopesOptions {
|
|
2058
|
+
/**
|
|
2059
|
+
* Resolve the names in TypeScript's types too: `type`, `interface` and
|
|
2060
|
+
* type parameters declare bindings, in a scope's `types`, and a name in
|
|
2061
|
+
* a type is a {@link Reference} with `type: true`. Defaults to `false`,
|
|
2062
|
+
* which resolves values only, as svelte's analyzer does.
|
|
2063
|
+
*/
|
|
2064
|
+
types?: boolean;
|
|
2065
|
+
}
|
|
2055
2066
|
|
|
2056
2067
|
/** A name declared in a {@link Scope}. */
|
|
2057
2068
|
export interface Binding {
|
|
@@ -2064,12 +2075,15 @@ export interface Binding {
|
|
|
2064
2075
|
* `"each"` and `"each-index"` (`item` and `i` in `{#each items as item,
|
|
2065
2076
|
* i}`), `"let-directive"`, `"snippet"` (its name), `"snippet-param"`,
|
|
2066
2077
|
* `"const-tag"` (`{@const}`), `"await-value"` and `"await-error"` (`{:then
|
|
2067
|
-
* value}` and `{:catch error}`).
|
|
2078
|
+
* value}` and `{:catch error}`). With `{ types: true }`, `"type"`,
|
|
2079
|
+
* `"interface"` and `"type-param"` (a type parameter or `infer U`), which
|
|
2080
|
+
* are in a scope's `types`, not its `declarations`, and `"param"` for a
|
|
2081
|
+
* parameter of a function type or signature too.
|
|
2068
2082
|
*/
|
|
2069
2083
|
readonly kind: BindingKind;
|
|
2070
2084
|
/**
|
|
2071
|
-
* The `Identifier` that declares it; `null` for an each block's index
|
|
2072
|
-
*
|
|
2085
|
+
* The `Identifier` that declares it; `null` for an each block's index,
|
|
2086
|
+
* `let:x` without a value and a type parameter, whose names are strings.
|
|
2073
2087
|
*/
|
|
2074
2088
|
readonly node: Identifier | null;
|
|
2075
2089
|
/**
|
|
@@ -2077,14 +2091,17 @@ export interface Binding {
|
|
|
2077
2091
|
* `VariableDeclarator`, the function or class, the function a
|
|
2078
2092
|
* parameter belongs to, the `CatchClause`, the `LabeledStatement` of
|
|
2079
2093
|
* `$:`, the `EachBlock`, `LetDirective`, `SnippetBlock` or `AwaitBlock`,
|
|
2080
|
-
* the enum, enum member or namespace, or `import a = b
|
|
2094
|
+
* the enum, enum member or namespace, or `import a = b`; the type
|
|
2095
|
+
* alias, interface or `TSTypeParameter`, or the function type or
|
|
2096
|
+
* signature a parameter belongs to.
|
|
2081
2097
|
*/
|
|
2082
2098
|
readonly declaration: AST.SvelteNode;
|
|
2083
2099
|
/**
|
|
2084
2100
|
* What it starts as, as svelte's analyzer has it: a variable's
|
|
2085
2101
|
* initializer, the function or class, the `ImportDeclaration`, the
|
|
2086
2102
|
* `SnippetBlock` for a snippet's name, the `EachBlock` for an index,
|
|
2087
|
-
* the right side of `$: x = ...`, an enum member's initializer
|
|
2103
|
+
* the right side of `$: x = ...`, an enum member's initializer, the type
|
|
2104
|
+
* alias or interface. For a
|
|
2088
2105
|
* prop destructured from `$props()`, its default, without `$bindable`:
|
|
2089
2106
|
* `"md"` in `let { size = "md" } = $props()` or in `let { size =
|
|
2090
2107
|
* $bindable("md") } = $props()`. `null` otherwise.
|
|
@@ -2148,6 +2165,12 @@ export interface Reference {
|
|
|
2148
2165
|
* `$count = 1` mutates it.
|
|
2149
2166
|
*/
|
|
2150
2167
|
readonly store: boolean;
|
|
2168
|
+
/**
|
|
2169
|
+
* Whether it's in a type, or in `export type { a }`, where it neither
|
|
2170
|
+
* reads, writes nor mutates. Only with `{ types: true }`: `A` in `let
|
|
2171
|
+
* a: A`, `a` in `typeof a`, `I` in `implements I`, `N` in `N.T`.
|
|
2172
|
+
*/
|
|
2173
|
+
readonly type: boolean;
|
|
2151
2174
|
}
|
|
2152
2175
|
|
|
2153
2176
|
/**
|
|
@@ -2161,13 +2184,26 @@ export interface Scope {
|
|
|
2161
2184
|
*/
|
|
2162
2185
|
readonly node: AST.SvelteNode | null;
|
|
2163
2186
|
readonly parent: Scope | null;
|
|
2164
|
-
/**
|
|
2187
|
+
/**
|
|
2188
|
+
* Its own bindings, by name, in the order they're declared: the values,
|
|
2189
|
+
* including imports, classes, enums and namespaces, which are types too.
|
|
2190
|
+
*/
|
|
2165
2191
|
readonly declarations: ReadonlyMap<string, Binding>;
|
|
2166
2192
|
/**
|
|
2167
|
-
*
|
|
2168
|
-
*
|
|
2193
|
+
* Its own type-only bindings, by name: `type`, `interface` and type
|
|
2194
|
+
* parameters. Empty unless `{ types: true }`.
|
|
2195
|
+
*/
|
|
2196
|
+
readonly types: ReadonlyMap<string, Binding>;
|
|
2197
|
+
/**
|
|
2198
|
+
* The binding `name` refers to here as a value, declared in this scope
|
|
2199
|
+
* or one around it; `null` if none does.
|
|
2169
2200
|
*/
|
|
2170
2201
|
get(name: string): Binding | null;
|
|
2202
|
+
/**
|
|
2203
|
+
* The binding `name` refers to here as a type: a `type`, `interface` or
|
|
2204
|
+
* type parameter, or an import, class or enum; `null` if none does.
|
|
2205
|
+
*/
|
|
2206
|
+
getType(name: string): Binding | null;
|
|
2171
2207
|
}
|
|
2172
2208
|
|
|
2173
2209
|
/** What {@link analyzeScopes} found. */
|
|
@@ -2223,7 +2259,8 @@ export interface Scopes {
|
|
|
2223
2259
|
* prop is passed as.
|
|
2224
2260
|
*
|
|
2225
2261
|
* Names in TypeScript types aren't references, and types aren't
|
|
2226
|
-
* declarations: `interface` and `type` declare nothing
|
|
2262
|
+
* declarations: `interface` and `type` declare nothing, unless `{ types:
|
|
2263
|
+
* true }`, which resolves the names in types too. A top-level
|
|
2227
2264
|
* snippet is declared in the markup's scope, as in svelte's analyzer, so
|
|
2228
2265
|
* a `<script>` that uses it refers to a global.
|
|
2229
2266
|
*
|
|
@@ -2240,7 +2277,7 @@ export interface Scopes {
|
|
|
2240
2277
|
*
|
|
2241
2278
|
* It reads the AST but doesn't change it.
|
|
2242
2279
|
*/
|
|
2243
|
-
export declare function analyzeScopes(ast: AST.Root | Program): Scopes;
|
|
2280
|
+
export declare function analyzeScopes(ast: AST.Root | Program, options?: AnalyzeScopesOptions): Scopes;
|
|
2244
2281
|
|
|
2245
2282
|
/** The fields of each node type that hold child nodes, in source order. */
|
|
2246
2283
|
export declare const visitorKeys: {
|
package/package.json
CHANGED
package/scope.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
/** How a {@link Binding} is declared. */
|
|
2
|
-
export type BindingKind = "import" | "var" | "let" | "const" | "using" | "function" | "class" | "enum" | "enum-member" | "namespace" | "param" | "catch" | "reactive" | "each" | "each-index" | "let-directive" | "snippet" | "snippet-param" | "const-tag" | "await-value" | "await-error";
|
|
2
|
+
export type BindingKind = "import" | "var" | "let" | "const" | "using" | "function" | "class" | "enum" | "enum-member" | "namespace" | "param" | "catch" | "reactive" | "each" | "each-index" | "let-directive" | "snippet" | "snippet-param" | "const-tag" | "await-value" | "await-error" | "type" | "interface" | "type-param";
|
|
3
|
+
|
|
4
|
+
/** Options for {@link analyzeScopes}. */
|
|
5
|
+
export interface AnalyzeScopesOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the names in TypeScript's types too: `type`, `interface` and
|
|
8
|
+
* type parameters declare bindings, in a scope's `types`, and a name in
|
|
9
|
+
* a type is a {@link Reference} with `type: true`. Defaults to `false`,
|
|
10
|
+
* which resolves values only, as svelte's analyzer does.
|
|
11
|
+
*/
|
|
12
|
+
types?: boolean;
|
|
13
|
+
}
|
|
3
14
|
|
|
4
15
|
/** A name declared in a {@link Scope}. */
|
|
5
16
|
export interface Binding {
|
|
@@ -12,12 +23,15 @@ export interface Binding {
|
|
|
12
23
|
* `"each"` and `"each-index"` (`item` and `i` in `{#each items as item,
|
|
13
24
|
* i}`), `"let-directive"`, `"snippet"` (its name), `"snippet-param"`,
|
|
14
25
|
* `"const-tag"` (`{@const}`), `"await-value"` and `"await-error"` (`{:then
|
|
15
|
-
* value}` and `{:catch error}`).
|
|
26
|
+
* value}` and `{:catch error}`). With `{ types: true }`, `"type"`,
|
|
27
|
+
* `"interface"` and `"type-param"` (a type parameter or `infer U`), which
|
|
28
|
+
* are in a scope's `types`, not its `declarations`, and `"param"` for a
|
|
29
|
+
* parameter of a function type or signature too.
|
|
16
30
|
*/
|
|
17
31
|
readonly kind: BindingKind;
|
|
18
32
|
/**
|
|
19
|
-
* The `Identifier` that declares it; `null` for an each block's index
|
|
20
|
-
*
|
|
33
|
+
* The `Identifier` that declares it; `null` for an each block's index,
|
|
34
|
+
* `let:x` without a value and a type parameter, whose names are strings.
|
|
21
35
|
*/
|
|
22
36
|
readonly node: Identifier | null;
|
|
23
37
|
/**
|
|
@@ -25,14 +39,17 @@ export interface Binding {
|
|
|
25
39
|
* `VariableDeclarator`, the function or class, the function a
|
|
26
40
|
* parameter belongs to, the `CatchClause`, the `LabeledStatement` of
|
|
27
41
|
* `$:`, the `EachBlock`, `LetDirective`, `SnippetBlock` or `AwaitBlock`,
|
|
28
|
-
* the enum, enum member or namespace, or `import a = b
|
|
42
|
+
* the enum, enum member or namespace, or `import a = b`; the type
|
|
43
|
+
* alias, interface or `TSTypeParameter`, or the function type or
|
|
44
|
+
* signature a parameter belongs to.
|
|
29
45
|
*/
|
|
30
46
|
readonly declaration: AST.SvelteNode;
|
|
31
47
|
/**
|
|
32
48
|
* What it starts as, as svelte's analyzer has it: a variable's
|
|
33
49
|
* initializer, the function or class, the `ImportDeclaration`, the
|
|
34
50
|
* `SnippetBlock` for a snippet's name, the `EachBlock` for an index,
|
|
35
|
-
* the right side of `$: x = ...`, an enum member's initializer
|
|
51
|
+
* the right side of `$: x = ...`, an enum member's initializer, the type
|
|
52
|
+
* alias or interface. For a
|
|
36
53
|
* prop destructured from `$props()`, its default, without `$bindable`:
|
|
37
54
|
* `"md"` in `let { size = "md" } = $props()` or in `let { size =
|
|
38
55
|
* $bindable("md") } = $props()`. `null` otherwise.
|
|
@@ -96,6 +113,12 @@ export interface Reference {
|
|
|
96
113
|
* `$count = 1` mutates it.
|
|
97
114
|
*/
|
|
98
115
|
readonly store: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Whether it's in a type, or in `export type { a }`, where it neither
|
|
118
|
+
* reads, writes nor mutates. Only with `{ types: true }`: `A` in `let
|
|
119
|
+
* a: A`, `a` in `typeof a`, `I` in `implements I`, `N` in `N.T`.
|
|
120
|
+
*/
|
|
121
|
+
readonly type: boolean;
|
|
99
122
|
}
|
|
100
123
|
|
|
101
124
|
/**
|
|
@@ -109,13 +132,26 @@ export interface Scope {
|
|
|
109
132
|
*/
|
|
110
133
|
readonly node: AST.SvelteNode | null;
|
|
111
134
|
readonly parent: Scope | null;
|
|
112
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Its own bindings, by name, in the order they're declared: the values,
|
|
137
|
+
* including imports, classes, enums and namespaces, which are types too.
|
|
138
|
+
*/
|
|
113
139
|
readonly declarations: ReadonlyMap<string, Binding>;
|
|
114
140
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
141
|
+
* Its own type-only bindings, by name: `type`, `interface` and type
|
|
142
|
+
* parameters. Empty unless `{ types: true }`.
|
|
143
|
+
*/
|
|
144
|
+
readonly types: ReadonlyMap<string, Binding>;
|
|
145
|
+
/**
|
|
146
|
+
* The binding `name` refers to here as a value, declared in this scope
|
|
147
|
+
* or one around it; `null` if none does.
|
|
117
148
|
*/
|
|
118
149
|
get(name: string): Binding | null;
|
|
150
|
+
/**
|
|
151
|
+
* The binding `name` refers to here as a type: a `type`, `interface` or
|
|
152
|
+
* type parameter, or an import, class or enum; `null` if none does.
|
|
153
|
+
*/
|
|
154
|
+
getType(name: string): Binding | null;
|
|
119
155
|
}
|
|
120
156
|
|
|
121
157
|
/** What {@link analyzeScopes} found. */
|
|
@@ -171,7 +207,8 @@ export interface Scopes {
|
|
|
171
207
|
* prop is passed as.
|
|
172
208
|
*
|
|
173
209
|
* Names in TypeScript types aren't references, and types aren't
|
|
174
|
-
* declarations: `interface` and `type` declare nothing
|
|
210
|
+
* declarations: `interface` and `type` declare nothing, unless `{ types:
|
|
211
|
+
* true }`, which resolves the names in types too. A top-level
|
|
175
212
|
* snippet is declared in the markup's scope, as in svelte's analyzer, so
|
|
176
213
|
* a `<script>` that uses it refers to a global.
|
|
177
214
|
*
|
|
@@ -188,7 +225,7 @@ export interface Scopes {
|
|
|
188
225
|
*
|
|
189
226
|
* It reads the AST but doesn't change it.
|
|
190
227
|
*/
|
|
191
|
-
export declare function analyzeScopes(ast: AST.Root | Program): Scopes;
|
|
228
|
+
export declare function analyzeScopes(ast: AST.Root | Program, options?: AnalyzeScopesOptions): Scopes;
|
|
192
229
|
|
|
193
230
|
interface BaseNodeWithoutComments {
|
|
194
231
|
type: string;
|
package/scope.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isNode,fieldsOf}from"./shared-m0dcdh24.js";import{extractIdentifiers2,isReference2,valueVisitorKeys2}from"./shared-jpvd0875.js";import{RUNES,RUNE_NAMES}from"./shared-m3dr31c3.js";class ScopeNode{node;parent;porous;index;declarations=new Map;constructor(node,parent,porous,index){this.node=node,this.parent=parent,this.porous=porous,this.index=index}get(name){for(let scope=this;scope;scope=scope.parent){let binding=scope.declarations.get(name);if(binding!==void 0)return binding}return null}}class BindingNode{name;kind;node;declaration;initial;scope;references=[];rune=null;prop=null;constructor(name,kind,node,declaration,initial,scope){this.name=name,this.kind=kind,this.node=node,this.declaration=declaration,this.initial=initial,this.scope=scope}}class ReferenceNode{node;parent;scope;binding=null;reads;writes;mutates;store=!1;constructor(node,parent,scope,reads,writes,mutates){this.node=node,this.parent=parent,this.scope=scope,this.reads=reads,this.writes=writes,this.mutates=mutates}}var keysByType=Object.assign(Object.create(null),valueVisitorKeys2),ELEMENTS=new Set(["SvelteElement","RegularElement","SvelteFragment","Component","SvelteComponent","SvelteSelf","SlotElement"]),NO_BINDINGS=new Map;function analyzeScopes(ast){return new Analysis(ast,!1)}class Analysis{module;instance;instanceProgram=null;component;ast;scopes=[];scopeIn;synthetic=new Map;recorded;made=new Map;declared=new Map;references=new Map;pending=[];declarators=[];implicit=[];stores=new Map;constructor(ast,record){if(this.ast=ast,this.scopeIn=record?new Map:null,ast.type==="Program")this.component=!1,this.module=this.scope(ast,null,!1),this.instance=this.module,this.made.set(ast,this.module),this.visit(ast,null,this.module);else{this.component=!0;let module=ast.module?.content??null,instance=ast.instance?.content??null;this.module=this.scope(module,null,!1),this.instance=this.scope(instance,this.module,!1),this.instanceProgram=instance,this.scopeIn?.set(ast,this.module);for(let[script,scope]of[[ast.module,this.module],[ast.instance,this.instance]]){if(script===void 0)continue;this.scopeIn?.set(script,scope),this.made.set(script.content,scope);for(let attribute of script.attributes)this.visit(attribute,script,scope);this.visit(script.content,script,scope)}this.visit(ast.fragment,ast,this.instance)}this.declareImplicit(),this.resolve(),this.findRunesAndProps()}scopeOf(node){let synthetic=this.synthetic.get(node);if(synthetic!==void 0)return synthetic;if(this.scopeIn!==null)return this.scopeIn.get(node)??null;this.recorded??=new Analysis(this.ast,!0);let recorded=this.recorded.scopeIn?.get(node);return recorded===void 0?null:this.scopes[recorded.index]}scope(node,parent,porous){let scope=new ScopeNode(node,parent,porous,this.scopes.length);return this.scopes.push(scope),scope}bindingOf(node){return this.declared.get(node)??this.references.get(node)?.binding??null}referenceOf(node){return this.references.get(node)??null}declaredIn(node){return this.made.get(node)?.declarations??NO_BINDINGS}child(scope,node,porous){let made=this.scope(node,scope,porous);return this.made.set(node,made),made}declare(scope,node,name,kind,declaration,initial){let target=scope;if(kind==="var")while(target.porous&&target.parent!==null)target=target.parent;let existing=target.declarations.get(name);if(existing!==void 0&&existing.declaration.type!=="TSDeclareFunction"){if(node!==null)this.declared.set(node,existing);return}let binding=new BindingNode(name,kind,node,declaration,initial,target);if(target.declarations.set(name,binding),node!==null)this.declared.set(node,binding)}reference(node,parent,scope,reads,writes,mutates){this.pending.push(new ReferenceNode(node,parent,scope,reads,writes,mutates))}referenceName(name,start,parent,scope){let root=name.split(".")[0],node={type:"Identifier",name:root,start,end:start+root.length};this.synthetic.set(node,scope),this.reference(node,parent,scope,!0,!1,!1)}visit(node,parent,scope){switch(this.scopeIn?.set(node,scope),node.type){case"Identifier":if(parent!==null&&isReference2(node,parent))this.reference(node,parent,scope,!0,!1,!1);this.visitFields(node,scope);return;case"ImportDeclaration":for(let specifier of node.specifiers){if(this.scopeIn?.set(specifier,scope),this.scopeIn?.set(specifier.local,scope),specifier.type==="ImportSpecifier")this.scopeIn?.set(specifier.imported,scope);this.declare(scope,specifier.local,specifier.local.name,"import",specifier,node)}this.visit(node.source,node,scope);for(let attribute of node.attributes??[])this.visit(attribute,node,scope);return;case"ExportNamedDeclaration":if(node.declaration)this.visit(node.declaration,node,scope);for(let specifier of node.specifiers)if(this.scopeIn?.set(specifier,scope),this.scopeIn?.set(specifier.local,scope),this.scopeIn?.set(specifier.exported,scope),!node.source&&specifier.local.type==="Identifier")this.reference(specifier.local,specifier,scope,!0,!1,!1);if(node.source)this.visit(node.source,node,scope);for(let attribute of node.attributes??[])this.visit(attribute,node,scope);return;case"VariableDeclaration":this.visitDeclaration(node,parent,scope);return;case"FunctionDeclaration":if(node.id)this.scopeIn?.set(node.id,scope),this.declare(scope,node.id,node.id.name,"function",node,node);this.visitFunction(node,this.child(scope,node,!0));return;case"FunctionExpression":{let inner=this.child(scope,node,!0);if(node.id)this.scopeIn?.set(node.id,inner),this.declare(inner,node.id,node.id.name,"function",node,node);this.visitFunction(node,inner);return}case"ArrowFunctionExpression":this.visitFunction(node,this.child(scope,node,!0));return;case"ClassDeclaration":case"ClassExpression":{let inner=scope;if(node.id){if(node.type==="ClassExpression")inner=this.child(scope,node,!1);this.scopeIn?.set(node.id,inner),this.declare(inner,node.id,node.id.name,"class",node,node)}for(let decorator of node.decorators??[])this.visit(decorator,node,scope);if(node.superClass)this.visit(node.superClass,node,inner);this.visit(node.body,node,inner);return}case"BlockStatement":this.visitFields(node,this.child(scope,node,!(parent!==null&&isFunction(parent)&&parent.body===node)));return;case"StaticBlock":this.visitFields(node,this.child(scope,node,!1));return;case"ForStatement":case"SwitchStatement":this.visitFields(node,this.child(scope,node,!0));return;case"ForInStatement":case"ForOfStatement":{let inner=this.child(scope,node,!0);if(node.left.type==="VariableDeclaration")this.visit(node.left,node,inner);else this.visitTarget(node.left,node,inner,!1);this.visit(node.right,node,inner),this.visit(node.body,node,inner);return}case"CatchClause":{if(!node.param)break;let inner=this.child(scope,node,!0);this.declarePattern(node.param,node,inner,"catch",node,null),this.visit(node.body,node,inner);return}case"AssignmentExpression":this.visitTarget(node.left,node,scope,node.operator!=="="),this.visit(node.right,node,scope);return;case"UpdateExpression":this.visitTarget(node.argument,node,scope,!0);return;case"LabeledStatement":if(parent===this.instanceProgram&&node.label.name==="$"){this.visitReactive(node,scope);return}break;case"TSEnumDeclaration":{this.scopeIn?.set(node.id,scope),this.declare(scope,node.id,node.id.name,"enum",node,node);let inner=this.child(scope,node,!1);for(let member of node.members)if(this.scopeIn?.set(member,inner),this.scopeIn?.set(member.id,inner),member.id.type==="Identifier")this.declare(inner,member.id,member.id.name,"enum-member",member,member.initializer??null);for(let member of node.members)if(member.initializer)this.visit(member.initializer,member,inner);return}case"TSModuleDeclaration":if(this.scopeIn?.set(node.id,scope),node.id.type==="Identifier"&&!node.global)this.declare(scope,node.id,node.id.name,"namespace",node,node);if(node.body)this.visit(node.body,node,this.child(scope,node,!1));return;case"TSImportEqualsDeclaration":{this.scopeIn?.set(node.id,scope),this.declare(scope,node.id,node.id.name,"import",node,node.moduleReference);let name=node.moduleReference;while(name.type==="TSQualifiedName")this.scopeIn?.set(name,scope),this.scopeIn?.set(name.right,scope),name=name.left;if(name.type==="Identifier")this.scopeIn?.set(name,scope),this.reference(name,node,scope,!0,!1,!1);else this.visit(name,node,scope);return}case"TSDeclareFunction":if(node.id){if(this.scopeIn?.set(node.id,scope),!scope.declarations.has(node.id.name))this.declare(scope,node.id,node.id.name,"function",node,node)}return;case"Fragment":this.visitFields(node,this.child(scope,node,!1));return;case"RegularElement":case"SvelteElement":case"SlotElement":case"SvelteFragment":this.visitFields(node,this.child(scope,node,!1));return;case"Component":case"SvelteComponent":case"SvelteSelf":this.visitComponent(node,scope);return;case"LetDirective":this.visitLet(node,scope);return;case"EachBlock":this.visitEach(node,scope);return;case"AwaitBlock":this.visitAwait(node,scope);return;case"SnippetBlock":{this.scopeIn?.set(node.expression,scope);let{name}=node.expression;this.declare(scope,node.expression,name,"snippet",node,node);let inner=this.child(scope,node,!1);for(let parameter of node.parameters??[])this.declarePattern(parameter,node,inner,"snippet-param",node,null);this.visit(node.body,node,inner);return}case"BindDirective":if(node.expression.type==="SequenceExpression")break;this.visitTarget(node.expression,node,scope,!0);return;case"TransitionDirective":case"AnimateDirective":case"UseDirective":{this.referenceName(node.name,node.start+prefixLength(node),node,scope);break}case"StyleDirective":if(node.value===!0)this.referenceName(node.name,node.start+6,node,scope);break}this.visitFields(node,scope)}visitFields(node,scope){let keys=keysByType[node.type];if(keys===void 0)throw Error(`unknown node type: ${node.type}`);let fields=fieldsOf(node);for(let k=0;k<keys.length;k++){let value=fields[keys[k]];if(Array.isArray(value))for(let i=0;i<value.length;i++){let child=value[i];if(isNode(child))this.visit(child,node,scope)}else if(isNode(value))this.visit(value,node,scope)}}visitDeclaration(node,parent,scope){let kind=node.kind==="await using"?"using":node.kind;if(parent?.type==="ConstTag")kind="const-tag";for(let declarator of node.declarations)if(this.scopeIn?.set(declarator,scope),this.declarePattern(declarator.id,declarator,scope,kind,declarator,declarator.init??null),this.declarators.push([declarator,scope]),declarator.init)this.visit(declarator.init,declarator,scope)}visitFunction(node,scope){for(let param of node.params){if(param.type==="Identifier"&¶m.name==="this"){this.scopeIn?.set(param,scope);continue}this.declarePattern(param,node,scope,"param",node,null)}this.visit(node.body,node,scope)}declarePattern(pattern,parent,scope,kind,declaration,initial){switch(this.scopeIn?.set(pattern,scope),pattern.type){case"Identifier":this.declare(scope,pattern,pattern.name,kind,declaration,initial);break;case"ObjectPattern":for(let property of pattern.properties){if(this.scopeIn?.set(property,scope),property.type==="RestElement"){this.declarePattern(property,pattern,scope,kind,declaration,initial);continue}if(property.computed)this.visit(property.key,property,scope);else this.scopeIn?.set(property.key,scope);this.declarePattern(property.value,property,scope,kind,declaration,initial)}break;case"ArrayPattern":for(let element of pattern.elements)if(element)this.declarePattern(element,pattern,scope,kind,declaration,initial);break;case"RestElement":this.declarePattern(pattern.argument,pattern,scope,kind,declaration,initial);break;case"AssignmentPattern":this.declarePattern(pattern.left,pattern,scope,kind,declaration,initial),this.visit(pattern.right,pattern,scope);break;case"TSParameterProperty":this.declarePattern(pattern.parameter,pattern,scope,kind,declaration,initial);break;default:this.visit(pattern,parent,scope);return}if("decorators"in pattern&&pattern.decorators)for(let decorator of pattern.decorators)this.visit(decorator,pattern,scope)}visitTarget(target,parent,scope,reads){switch(this.scopeIn?.set(target,scope),target.type){case"Identifier":this.reference(target,parent,scope,reads,!0,!1);return;case"MemberExpression":{let object=target,holder=parent;while(object.type==="MemberExpression"){if(this.scopeIn?.set(object,scope),object.computed)this.visit(object.property,object,scope);else this.scopeIn?.set(object.property,scope);holder=object,object=object.object}if(object.type==="Identifier")this.scopeIn?.set(object,scope),this.reference(object,holder,scope,!0,!1,!0);else this.visit(object,holder,scope);return}case"ObjectPattern":for(let property of target.properties){if(this.scopeIn?.set(property,scope),property.type==="RestElement"){this.visitTarget(property,target,scope,!1);continue}if(property.computed)this.visit(property.key,property,scope);else this.scopeIn?.set(property.key,scope);this.visitTarget(property.value,property,scope,!1)}return;case"ArrayPattern":for(let element of target.elements)if(element)this.visitTarget(element,target,scope,!1);return;case"RestElement":this.visitTarget(target.argument,target,scope,!1);return;case"AssignmentPattern":this.visitTarget(target.left,target,scope,!1),this.visit(target.right,target,scope);return}if(target.type==="TSAsExpression"||target.type==="TSSatisfiesExpression"||target.type==="TSNonNullExpression"||target.type==="TSTypeAssertion"){this.visitTarget(target.expression,target,scope,reads);return}this.visit(target,parent,scope)}visitReactive(node,scope){let inner=this.child(scope,node,!1);this.scopeIn?.set(node.label,scope);let{body}=node;if(body.type==="ExpressionStatement"&&body.expression.type==="AssignmentExpression"){let{left,right}=body.expression;for(let id of extractIdentifiers2(left))if(!id.name.startsWith("$"))this.implicit.push([id,node,right])}this.visit(body,node,inner)}visitComponent(node,scope){if(node.type==="Component")this.referenceName(node.name,node.start+1,node,scope);let slotted=slotOf(node)!==null,defaults=this.scope(node,scope,!1),lets=slotted?scope:defaults;if(this.made.set(node,lets),node.type==="SvelteComponent")this.visit(node.expression,node,scope);for(let attribute of node.attributes)this.visit(attribute,node,attribute.type==="LetDirective"?lets:scope);this.scopeIn?.set(node.fragment,defaults);for(let child of node.fragment.nodes){let slot=slotOf(child);this.visit(child,node.fragment,slot===null?defaults:this.child(scope,child,!1))}}visitLet(node,scope){if(node.expression===null){this.declare(scope,null,node.name,"let-directive",node,null);return}let declare=(expression)=>{switch(this.scopeIn?.set(expression,scope),expression.type){case"Identifier":this.declare(scope,expression,expression.name,"let-directive",node,null);return;case"ObjectExpression":for(let property of expression.properties)if(this.scopeIn?.set(property,scope),property.type==="SpreadElement")declare(property.argument);else this.scopeIn?.set(property.key,scope),declare(property.value);return;case"ArrayExpression":for(let element of expression.elements){if(element===null)continue;if(element.type==="SpreadElement")this.scopeIn?.set(element,scope),declare(element.argument);else declare(element)}}};declare(node.expression)}visitEach(node,scope){if(this.visit(node.expression,node,scope),node.fallback)this.visit(node.fallback,node,scope);let inner=this.child(scope,node,!1);if(node.context)this.declarePattern(node.context,node,inner,"each",node,null);if(node.index!==void 0)this.declare(inner,null,node.index,"each-index",node,node);if(node.key)this.visit(node.key,node,inner);this.scopeIn?.set(node.body,inner);for(let child of node.body.nodes)this.visit(child,node.body,inner)}visitAwait(node,scope){if(this.visit(node.expression,node,scope),node.pending)this.visit(node.pending,node,scope);for(let[fragment,pattern,kind]of[[node.then,node.value,"await-value"],[node.catch,node.error,"await-error"]]){if(fragment===null)continue;this.visit(fragment,node,scope);let inner=this.made.get(fragment);if(pattern!==null&&inner!==void 0)this.declarePattern(pattern,node,inner,kind,node,null)}}declareImplicit(){for(let[id,label,right]of this.implicit)if(this.instance.get(id.name)===null)this.declare(this.instance,id,id.name,"reactive",label,right)}resolve(){let unordered=new Set;for(let reference of this.pending){let{node}=reference,declared=this.declared.get(node);if(declared!==void 0&&declared.kind!=="reactive")continue;this.references.set(node,reference);let binding=reference.scope.get(node.name);if(binding===null&&this.component){let store=this.storeOf(node.name);if(store!==!1)reference.store=!0,reference.mutates||=reference.writes,reference.reads=!0,reference.writes=!1,binding=store}if(binding!==null){reference.binding=binding;let last=binding.references.at(-1);if(last!==void 0&&last.node.start>node.start)unordered.add(binding);binding.references.push(reference)}}for(let binding of unordered)binding.references.sort((a,b)=>a.node.start-b.node.start)}storeOf(name){let cached=this.stores.get(name);if(cached!==void 0)return cached;let store=!1;if(name.length>1&&name.startsWith("$")&&!name.startsWith("$$")){let declaration=this.instance.get(name.slice(1));if(!RUNE_NAMES.has(name))store=declaration;else if(declaration!==null){let initial=declaration.initial,rune=runeOf(initial,this.instance,null);if((rune===null||name!=="$props"&&rune==="$props")&&!(name==="$derived"&&initial?.type==="ImportDeclaration"&&initial.source.value==="svelte/store"))store=declaration}}return this.stores.set(name,store),store}findRunesAndProps(){for(let[declarator,scope]of this.declarators){let rune=runeOf(declarator.init??null,scope,this.references);if(rune===null)continue;for(let id of extractIdentifiers2(declarator.id)){let binding=this.declared.get(id);if(binding?.declaration===declarator)binding.rune=rune}if(rune!=="$props")continue;if(declarator.id.type==="Identifier"){let binding=this.declared.get(declarator.id);if(binding)binding.initial=null;continue}if(declarator.id.type!=="ObjectPattern")continue;for(let property of declarator.id.properties){if(property.type==="RestElement"){for(let id of extractIdentifiers2(property)){let binding=this.declared.get(id);if(binding)binding.initial=null}continue}let value=property.value.type==="AssignmentPattern"?property.value.left:property.value,binding=value.type==="Identifier"?this.declared.get(value):void 0;if(binding===void 0||property.computed)continue;binding.prop=keyName(property.key),binding.initial=property.value.type==="AssignmentPattern"?unwrapBindable(property.value.right):null}}this.findLegacyProps()}findLegacyProps(){if(this.instanceProgram===null)return;for(let statement of this.instanceProgram.body){if(statement.type!=="ExportNamedDeclaration")continue;let{declaration}=statement;if(declaration?.type==="VariableDeclaration"){if(declaration.kind!=="let"&&declaration.kind!=="var")continue;for(let declarator of declaration.declarations)for(let id of extractIdentifiers2(declarator.id)){let binding=this.declared.get(id);if(binding)binding.prop=id.name}continue}if(statement.source)continue;for(let specifier of statement.specifiers){if(specifier.local.type!=="Identifier")continue;let binding=this.instance.declarations.get(specifier.local.name);if(binding?.kind!=="let"&&binding?.kind!=="var")continue;binding.prop=specifier.exported.type==="Identifier"?specifier.exported.name:String(specifier.exported.value)}}}}function isFunction(node){return node.type==="ArrowFunctionExpression"||node.type==="FunctionExpression"||node.type==="FunctionDeclaration"}function slotOf(node){if(!ELEMENTS.has(node.type)||!("attributes"in node))return null;for(let attribute of node.attributes??[])if(attribute.type==="Attribute"&&attribute.name==="slot"&&Array.isArray(attribute.value)&&attribute.value.length===1&&attribute.value[0].type==="Text")return attribute.value[0].data;return null}function runeOf(initial,scope,references){if(initial?.type!=="CallExpression")return null;let node=initial.callee,keypath="";while(node.type==="MemberExpression"){if(node.computed||node.property.type!=="Identifier")return null;keypath=`.${node.property.name}${keypath}`,node=node.object}if(node.type==="CallExpression"&&node.callee.type==="Identifier")keypath=`()${keypath}`,node=node.callee;if(node.type!=="Identifier")return null;if(references!==null){let reference=references.get(node);if(reference?.binding!==null||reference.store)return null}else if(scope.get(node.name)!==null)return null;return keypath=node.name+keypath,RUNES.has(keypath)?keypath:null}function unwrapBindable(node){if(node.type==="CallExpression"&&node.callee.type==="Identifier"&&node.callee.name==="$bindable"){let[argument]=node.arguments;return argument===void 0||argument.type==="SpreadElement"?null:argument}return node}function prefixLength(node){if(node.type==="UseDirective")return 4;if(node.type==="AnimateDirective")return 8;if(node.intro&&node.outro)return 11;return node.intro?3:4}function keyName(key){if(key.type==="Identifier")return key.name;return key.type==="Literal"?String(key.value):null}export{analyzeScopes};
|
|
1
|
+
import{isNode,fieldsOf}from"./shared-m0dcdh24.js";import{extractIdentifiers2,isReference2,visitorKeys2,valueVisitorKeys2}from"./shared-jpvd0875.js";import{RUNES,RUNE_NAMES}from"./shared-m3dr31c3.js";class ScopeNode{node;parent;porous;index;declarations=new Map;types=new Map;constructor(node,parent,porous,index){this.node=node,this.parent=parent,this.porous=porous,this.index=index}get(name){for(let scope=this;scope;scope=scope.parent){let binding=scope.declarations.get(name);if(binding!==void 0)return binding}return null}getType(name){return this.lookup(name,TYPE)}lookup(name,meaning){if(meaning===VALUE)return this.get(name);let kinds=meaning===TYPE?TYPE_KINDS:NAMESPACE_KINDS;for(let scope=this;scope;scope=scope.parent){if(meaning===TYPE){let type=scope.types.get(name);if(type!==void 0)return type}let binding=scope.declarations.get(name);if(binding!==void 0&&kinds.has(binding.kind))return binding}return null}}class BindingNode{name;kind;node;declaration;initial;scope;references=[];rune=null;prop=null;constructor(name,kind,node,declaration,initial,scope){this.name=name,this.kind=kind,this.node=node,this.declaration=declaration,this.initial=initial,this.scope=scope}}class ReferenceNode{node;parent;scope;binding=null;reads;writes;mutates;store=!1;type;meaning;constructor(node,parent,scope,reads,writes,mutates,type,meaning){this.node=node,this.parent=parent,this.scope=scope,this.reads=reads,this.writes=writes,this.mutates=mutates,this.type=type,this.meaning=meaning}}var VALUE=0,TYPE=1,NAMESPACE=2,ANY=3,TYPE_KINDS=new Set(["import","class","enum"]),NAMESPACE_KINDS=new Set(["import","enum","namespace"]);function holdsTypes(type){return type==="MethodDefinition"||type.startsWith("TS")}var keysByType=Object.assign(Object.create(null),valueVisitorKeys2),typedKeysByType=Object.create(null);for(let[type,all]of Object.entries(visitorKeys2)){let values=keysByType[type]??[],types=all.filter((key)=>!values.includes(key));typedKeysByType[type]={values,types:types.length>0?types:null,all}}var ELEMENTS=new Set(["SvelteElement","RegularElement","SvelteFragment","Component","SvelteComponent","SvelteSelf","SlotElement"]),NO_BINDINGS=new Map;function analyzeScopes(ast,options){return new Analysis(ast,!1,options?.types===!0)}class Analysis{module;instance;instanceProgram=null;component;ast;scopes=[];scopeIn;synthetic=new Map;recorded;made=new Map;declared=new Map;references=new Map;pending=[];declarators=[];implicit=[];stores=new Map;types;inType=!1;inferScope=null;constructor(ast,record,types){if(this.ast=ast,this.scopeIn=record?new Map:null,this.types=types,ast.type==="Program")this.component=!1,this.module=this.scope(ast,null,!1),this.instance=this.module,this.made.set(ast,this.module),this.visit(ast,null,this.module);else{this.component=!0;let module=ast.module?.content??null,instance=ast.instance?.content??null;this.module=this.scope(module,null,!1),this.instance=this.scope(instance,this.module,!1),this.instanceProgram=instance,this.scopeIn?.set(ast,this.module);for(let[script,scope]of[[ast.module,this.module],[ast.instance,this.instance]]){if(script===void 0)continue;this.scopeIn?.set(script,scope),this.made.set(script.content,scope);for(let attribute of script.attributes)this.visit(attribute,script,scope);this.visit(script.content,script,scope)}this.visit(ast.fragment,ast,this.instance)}this.declareImplicit(),this.resolve(),this.findRunesAndProps()}scopeOf(node){let synthetic=this.synthetic.get(node);if(synthetic!==void 0)return synthetic;if(this.scopeIn!==null)return this.scopeIn.get(node)??null;this.recorded??=new Analysis(this.ast,!0,this.types);let recorded=this.recorded.scopeIn?.get(node);return recorded===void 0?null:this.scopes[recorded.index]}scope(node,parent,porous){let scope=new ScopeNode(node,parent,porous,this.scopes.length);return this.scopes.push(scope),scope}bindingOf(node){return this.declared.get(node)??this.references.get(node)?.binding??null}referenceOf(node){return this.references.get(node)??null}declaredIn(node){return this.made.get(node)?.declarations??NO_BINDINGS}child(scope,node,porous){let made=this.scope(node,scope,porous);return this.made.set(node,made),made}declare(scope,node,name,kind,declaration,initial){let target=scope;if(kind==="var")while(target.porous&&target.parent!==null)target=target.parent;let declarations=kind==="type"||kind==="interface"||kind==="type-param"?target.types:target.declarations,existing=declarations.get(name);if(existing!==void 0&&existing.declaration.type!=="TSDeclareFunction"){if(node!==null)this.declared.set(node,existing);return}let binding=new BindingNode(name,kind,node,declaration,initial,target);if(declarations.set(name,binding),node!==null)this.declared.set(node,binding)}reference(node,parent,scope,reads,writes,mutates,meaning=VALUE,type=this.inType){this.pending.push(type?new ReferenceNode(node,parent,scope,!1,!1,!1,!0,meaning):new ReferenceNode(node,parent,scope,reads,writes,mutates,!1,meaning))}referenceName(name,start,parent,scope){let root=name.split(".")[0],node={type:"Identifier",name:root,start,end:start+root.length};this.synthetic.set(node,scope),this.reference(node,parent,scope,!0,!1,!1)}visit(node,parent,scope){switch(this.scopeIn?.set(node,scope),node.type){case"Identifier":if(parent!==null&&(this.inType?isReferenceInType(node,parent):isReference2(node,parent)))this.reference(node,parent,scope,!0,!1,!1);this.visitFields(node,scope);return;case"ImportDeclaration":for(let specifier of node.specifiers){if(this.scopeIn?.set(specifier,scope),this.scopeIn?.set(specifier.local,scope),specifier.type==="ImportSpecifier")this.scopeIn?.set(specifier.imported,scope);this.declare(scope,specifier.local,specifier.local.name,"import",specifier,node)}this.visit(node.source,node,scope);for(let attribute of node.attributes??[])this.visit(attribute,node,scope);return;case"ExportNamedDeclaration":if(node.declaration)this.visit(node.declaration,node,scope);for(let specifier of node.specifiers)if(this.scopeIn?.set(specifier,scope),this.scopeIn?.set(specifier.local,scope),this.scopeIn?.set(specifier.exported,scope),!node.source&&specifier.local.type==="Identifier")this.reference(specifier.local,specifier,scope,!0,!1,!1,this.types?ANY:VALUE,this.types&&(node.exportKind==="type"||specifier.exportKind==="type"));if(node.source)this.visit(node.source,node,scope);for(let attribute of node.attributes??[])this.visit(attribute,node,scope);return;case"VariableDeclaration":this.visitDeclaration(node,parent,scope);return;case"FunctionDeclaration":if(node.id)this.scopeIn?.set(node.id,scope),this.declare(scope,node.id,node.id.name,"function",node,node);this.visitFunction(node,this.child(scope,node,!0));return;case"FunctionExpression":{let inner=this.child(scope,node,!0);if(node.id)this.scopeIn?.set(node.id,inner),this.declare(inner,node.id,node.id.name,"function",node,node);this.visitFunction(node,inner);return}case"ArrowFunctionExpression":this.visitFunction(node,this.child(scope,node,!0));return;case"ClassDeclaration":case"ClassExpression":{let generic=this.types&&node.typeParameters!==void 0,inner=node.id&&node.type==="ClassExpression"||generic?this.child(scope,node,!1):scope;if(node.id){let at=node.type==="ClassExpression"?inner:scope;this.scopeIn?.set(node.id,at),this.declare(at,node.id,node.id.name,"class",node,node)}for(let decorator of node.decorators??[])this.visit(decorator,node,scope);if(this.declareTypeParameters(node.typeParameters,inner),node.superClass)this.visit(node.superClass,node,inner);this.visitType(node.superTypeParameters,node,inner),this.visitType(node.implements,node,inner),this.visit(node.body,node,inner);return}case"BlockStatement":this.visitFields(node,this.child(scope,node,!(parent!==null&&isFunction(parent)&&parent.body===node)));return;case"StaticBlock":this.visitFields(node,this.child(scope,node,!1));return;case"ForStatement":case"SwitchStatement":this.visitFields(node,this.child(scope,node,!0));return;case"ForInStatement":case"ForOfStatement":{let inner=this.child(scope,node,!0);if(node.left.type==="VariableDeclaration")this.visit(node.left,node,inner);else this.visitTarget(node.left,node,inner,!1);this.visit(node.right,node,inner),this.visit(node.body,node,inner);return}case"CatchClause":{if(!node.param)break;let inner=this.child(scope,node,!0);this.declarePattern(node.param,node,inner,"catch",node,null),this.visit(node.body,node,inner);return}case"AssignmentExpression":this.visitTarget(node.left,node,scope,node.operator!=="="),this.visit(node.right,node,scope);return;case"UpdateExpression":this.visitTarget(node.argument,node,scope,!0);return;case"LabeledStatement":if(parent===this.instanceProgram&&node.label.name==="$"){this.visitReactive(node,scope);return}break;case"TSEnumDeclaration":{this.scopeIn?.set(node.id,scope),this.declare(scope,node.id,node.id.name,"enum",node,node);let inner=this.child(scope,node,!1);for(let member of node.members)if(this.scopeIn?.set(member,inner),this.scopeIn?.set(member.id,inner),member.id.type==="Identifier")this.declare(inner,member.id,member.id.name,"enum-member",member,member.initializer??null);for(let member of node.members)if(member.initializer)this.visit(member.initializer,member,inner);return}case"TSModuleDeclaration":if(this.scopeIn?.set(node.id,scope),node.id.type==="Identifier"&&!node.global)this.declare(scope,node.id,node.id.name,"namespace",node,node);if(node.body)this.visit(node.body,node,this.child(scope,node,!1));return;case"TSImportEqualsDeclaration":{this.scopeIn?.set(node.id,scope),this.declare(scope,node.id,node.id.name,"import",node,node.moduleReference);let name=node.moduleReference;while(name.type==="TSQualifiedName")this.scopeIn?.set(name,scope),this.scopeIn?.set(name.right,scope),name=name.left;if(name.type==="Identifier")this.scopeIn?.set(name,scope),this.reference(name,node,scope,!0,!1,!1);else this.visit(name,node,scope);return}case"TSDeclareFunction":if(node.id){if(this.scopeIn?.set(node.id,scope),!scope.declarations.has(node.id.name))this.declare(scope,node.id,node.id.name,"function",node,node)}if(this.types)this.visitSignature(node,node.typeParameters,node.params,node.returnType,scope);return;case"Fragment":this.visitFields(node,this.child(scope,node,!1));return;case"RegularElement":case"SvelteElement":case"SlotElement":case"SvelteFragment":this.visitFields(node,this.child(scope,node,!1));return;case"Component":case"SvelteComponent":case"SvelteSelf":this.visitComponent(node,scope);return;case"LetDirective":this.visitLet(node,scope);return;case"EachBlock":this.visitEach(node,scope);return;case"AwaitBlock":this.visitAwait(node,scope);return;case"SnippetBlock":{this.scopeIn?.set(node.expression,scope);let{name}=node.expression;this.declare(scope,node.expression,name,"snippet",node,node);let inner=this.child(scope,node,!1);for(let parameter of node.parameters??[])this.declarePattern(parameter,node,inner,"snippet-param",node,null);this.visit(node.body,node,inner);return}case"BindDirective":if(node.expression.type==="SequenceExpression")break;this.visitTarget(node.expression,node,scope,!0);return;case"TransitionDirective":case"AnimateDirective":case"UseDirective":{this.referenceName(node.name,node.start+prefixLength(node),node,scope);break}case"StyleDirective":if(node.value===!0)this.referenceName(node.name,node.start+6,node,scope);break}if(this.types&&holdsTypes(node.type)&&this.visitTyped(node,scope))return;this.visitFields(node,scope)}visitTyped(node,scope){switch(node.type){case"MethodDefinition":{if(node.typeParameters===void 0)return!1;this.visitChild(node.decorators,node,scope),this.visit(node.key,node,scope);let inner=this.child(scope,node,!1);return this.declareTypeParameters(node.typeParameters,inner),this.visit(node.value,node,inner),!0}case"TSDeclareMethod":return this.visitSignature(node,node.typeParameters,node.params,node.returnType,scope),!0;case"TSFunctionType":case"TSConstructorType":case"TSCallSignatureDeclaration":case"TSConstructSignatureDeclaration":return this.visitSignature(node,node.typeParameters,node.parameters,node.typeAnnotation,scope),!0;case"TSMethodSignature":if(node.computed)this.visit(node.key,node,scope);else this.scopeIn?.set(node.key,scope);return this.visitSignature(node,node.typeParameters,node.parameters,node.typeAnnotation,scope),!0;case"TSTypeAliasDeclaration":case"TSInterfaceDeclaration":{let kind=node.type==="TSTypeAliasDeclaration"?"type":"interface";this.scopeIn?.set(node.id,scope),this.declare(scope,node.id,node.id.name,kind,node,node);let inner=node.typeParameters?this.child(scope,node,!1):scope;if(this.declareTypeParameters(node.typeParameters,inner),node.type==="TSTypeAliasDeclaration")this.visitType(node.typeAnnotation,node,inner);else this.visitType(node.extends,node,inner),this.visitType(node.body,node,inner);return!0}case"TSTypeReference":return this.visitEntityName(node.typeName,node,scope,TYPE),this.visitChild(node.typeArguments,node,scope),!0;case"TSExpressionWithTypeArguments":return this.visitEntityName(node.expression,node,scope,TYPE),this.visitChild(node.typeParameters,node,scope),!0;case"TSTypeQuery":return this.visitEntityName(node.exprName,node,scope,VALUE),this.visitChild(node.typeArguments,node,scope),!0;case"TSImportType":{this.visit(node.argument,node,scope);let name=node.qualifier;while(name!==void 0){if(this.scopeIn?.set(name,scope),name.type!=="TSQualifiedName")break;this.scopeIn?.set(name.right,scope),name=name.left}return this.visitChild(node.typeArguments,node,scope),!0}case"TSMappedType":{let parameter=node.typeParameter;this.scopeIn?.set(parameter,scope),this.visitChild(parameter.constraint,parameter,scope);let inner=this.child(scope,node,!1);return this.declare(inner,null,parameter.name,"type-param",parameter,null),this.visitChild(node.nameType,node,inner),this.visitChild(node.typeAnnotation,node,inner),!0}case"TSConditionalType":{this.visit(node.checkType,node,scope);let inner=this.child(scope,node,!1),outer=this.inferScope;return this.inferScope=inner,this.visit(node.extendsType,node,inner),this.inferScope=outer,this.visit(node.trueType,node,inner),this.visit(node.falseType,node,scope),!0}case"TSInferType":{let parameter=node.typeParameter;return this.scopeIn?.set(parameter,scope),this.declare(this.inferScope??scope,null,parameter.name,"type-param",parameter,null),this.visitChild(parameter.constraint,parameter,scope),!0}}return!1}visitFields(node,scope){if(this.types){this.visitTypedFields(node,scope);return}let keys=keysByType[node.type];if(keys===void 0)throw Error(`unknown node type: ${node.type}`);let fields=fieldsOf(node);for(let k=0;k<keys.length;k++){let value=fields[keys[k]];if(Array.isArray(value))for(let i=0;i<value.length;i++){let child=value[i];if(isNode(child))this.visit(child,node,scope)}else if(isNode(value))this.visit(value,node,scope)}}visitTypedFields(node,scope){let keys=typedKeysByType[node.type];if(keys===void 0)throw Error(`unknown node type: ${node.type}`);if(this.inType){this.visitKeys(node,keys.all,scope);return}if(keys.types!==null){let fields=fieldsOf(node);for(let k=0;k<keys.types.length;k++){let value=fields[keys.types[k]];if(value!=null)this.visitType(value,node,scope)}}this.visitKeys(node,keys.values,scope)}visitKeys(node,keys,scope){let fields=fieldsOf(node);for(let k=0;k<keys.length;k++){let value=fields[keys[k]];if(Array.isArray(value))for(let i=0;i<value.length;i++){let child=value[i];if(isNode(child))this.visit(child,node,scope)}else if(isNode(value))this.visit(value,node,scope)}}visitChild(value,parent,scope){if(Array.isArray(value))for(let i=0;i<value.length;i++){let child=value[i];if(isNode(child))this.visit(child,parent,scope)}else if(isNode(value))this.visit(value,parent,scope)}visitType(value,parent,scope){if(!this.types||value===void 0||value===null)return;let outer=this.inType;this.inType=!0,this.visitChild(value,parent,scope),this.inType=outer}declareTypeParameters(declaration,scope){if(!this.types||declaration===void 0)return;this.scopeIn?.set(declaration,scope);for(let parameter of declaration.params)this.scopeIn?.set(parameter,scope),this.declare(scope,null,parameter.name,"type-param",parameter,null);for(let parameter of declaration.params)this.visitType(parameter.constraint,parameter,scope),this.visitType(parameter.default,parameter,scope)}visitSignature(node,typeParameters,parameters,returnType,scope){let inner=this.child(scope,node,!0);this.declareTypeParameters(typeParameters,inner),this.declareParameters(parameters,node,inner),this.visitType(returnType,node,inner)}declareParameters(parameters,node,scope){for(let param of parameters){if(param.type==="Identifier"&¶m.name==="this"){if(this.scopeIn?.set(param,scope),this.types)this.visitType(param.typeAnnotation,param,scope);continue}this.declarePattern(param,node,scope,"param",node,null)}}visitEntityName(entity,parent,scope,meaning){if(entity.type==="TSImportType"){this.visit(entity,parent,scope);return}let name=entity,holder=parent;while(name.type==="TSQualifiedName")this.scopeIn?.set(name,scope),this.scopeIn?.set(name.right,scope),holder=name,name=name.left;if(this.scopeIn?.set(name,scope),name.name==="this")return;let qualified=name!==entity&&meaning===TYPE;this.reference(name,holder,scope,!0,!1,!1,qualified?NAMESPACE:meaning)}visitDeclaration(node,parent,scope){let kind=node.kind==="await using"?"using":node.kind;if(parent?.type==="ConstTag")kind="const-tag";for(let declarator of node.declarations)if(this.scopeIn?.set(declarator,scope),this.declarePattern(declarator.id,declarator,scope,kind,declarator,declarator.init??null),this.declarators.push([declarator,scope]),declarator.init)this.visit(declarator.init,declarator,scope)}visitFunction(node,scope){if(this.types)this.declareTypeParameters(node.typeParameters,scope);if(this.declareParameters(node.params,node,scope),this.types)this.visitType(node.returnType,node,scope);this.visit(node.body,node,scope)}declarePattern(pattern,parent,scope,kind,declaration,initial){switch(this.scopeIn?.set(pattern,scope),pattern.type){case"Identifier":this.declare(scope,pattern,pattern.name,kind,declaration,initial);break;case"ObjectPattern":for(let property of pattern.properties){if(this.scopeIn?.set(property,scope),property.type==="RestElement"){this.declarePattern(property,pattern,scope,kind,declaration,initial);continue}if(property.computed)this.visit(property.key,property,scope);else this.scopeIn?.set(property.key,scope);this.declarePattern(property.value,property,scope,kind,declaration,initial)}break;case"ArrayPattern":for(let element of pattern.elements)if(element)this.declarePattern(element,pattern,scope,kind,declaration,initial);break;case"RestElement":this.declarePattern(pattern.argument,pattern,scope,kind,declaration,initial);break;case"AssignmentPattern":this.declarePattern(pattern.left,pattern,scope,kind,declaration,initial),this.visit(pattern.right,pattern,scope);break;case"TSParameterProperty":this.declarePattern(pattern.parameter,pattern,scope,kind,declaration,initial);break;default:this.visit(pattern,parent,scope);return}if("decorators"in pattern&&pattern.decorators)for(let decorator of pattern.decorators)this.visit(decorator,pattern,scope);if(this.types&&"typeAnnotation"in pattern&&pattern.typeAnnotation)this.visitType(pattern.typeAnnotation,pattern,scope)}visitTarget(target,parent,scope,reads){switch(this.scopeIn?.set(target,scope),target.type){case"Identifier":this.reference(target,parent,scope,reads,!0,!1);return;case"MemberExpression":{let object=target,holder=parent;while(object.type==="MemberExpression"){if(this.scopeIn?.set(object,scope),object.computed)this.visit(object.property,object,scope);else this.scopeIn?.set(object.property,scope);holder=object,object=object.object}if(object.type==="Identifier")this.scopeIn?.set(object,scope),this.reference(object,holder,scope,!0,!1,!0);else this.visit(object,holder,scope);return}case"ObjectPattern":for(let property of target.properties){if(this.scopeIn?.set(property,scope),property.type==="RestElement"){this.visitTarget(property,target,scope,!1);continue}if(property.computed)this.visit(property.key,property,scope);else this.scopeIn?.set(property.key,scope);this.visitTarget(property.value,property,scope,!1)}return;case"ArrayPattern":for(let element of target.elements)if(element)this.visitTarget(element,target,scope,!1);return;case"RestElement":this.visitTarget(target.argument,target,scope,!1);return;case"AssignmentPattern":this.visitTarget(target.left,target,scope,!1),this.visit(target.right,target,scope);return}if(target.type==="TSAsExpression"||target.type==="TSSatisfiesExpression"||target.type==="TSNonNullExpression"||target.type==="TSTypeAssertion"){if(this.visitTarget(target.expression,target,scope,reads),target.type!=="TSNonNullExpression")this.visitType(target.typeAnnotation,target,scope);return}this.visit(target,parent,scope)}visitReactive(node,scope){let inner=this.child(scope,node,!1);this.scopeIn?.set(node.label,scope);let{body}=node;if(body.type==="ExpressionStatement"&&body.expression.type==="AssignmentExpression"){let{left,right}=body.expression;for(let id of extractIdentifiers2(left))if(!id.name.startsWith("$"))this.implicit.push([id,node,right])}this.visit(body,node,inner)}visitComponent(node,scope){if(node.type==="Component")this.referenceName(node.name,node.start+1,node,scope);let slotted=slotOf(node)!==null,defaults=this.scope(node,scope,!1),lets=slotted?scope:defaults;if(this.made.set(node,lets),node.type==="SvelteComponent")this.visit(node.expression,node,scope);for(let attribute of node.attributes)this.visit(attribute,node,attribute.type==="LetDirective"?lets:scope);this.scopeIn?.set(node.fragment,defaults);for(let child of node.fragment.nodes){let slot=slotOf(child);this.visit(child,node.fragment,slot===null?defaults:this.child(scope,child,!1))}}visitLet(node,scope){if(node.expression===null){this.declare(scope,null,node.name,"let-directive",node,null);return}let declare=(expression)=>{switch(this.scopeIn?.set(expression,scope),expression.type){case"Identifier":this.declare(scope,expression,expression.name,"let-directive",node,null);return;case"ObjectExpression":for(let property of expression.properties)if(this.scopeIn?.set(property,scope),property.type==="SpreadElement")declare(property.argument);else this.scopeIn?.set(property.key,scope),declare(property.value);return;case"ArrayExpression":for(let element of expression.elements){if(element===null)continue;if(element.type==="SpreadElement")this.scopeIn?.set(element,scope),declare(element.argument);else declare(element)}}};declare(node.expression)}visitEach(node,scope){if(this.visit(node.expression,node,scope),node.fallback)this.visit(node.fallback,node,scope);let inner=this.child(scope,node,!1);if(node.context)this.declarePattern(node.context,node,inner,"each",node,null);if(node.index!==void 0)this.declare(inner,null,node.index,"each-index",node,node);if(node.key)this.visit(node.key,node,inner);this.scopeIn?.set(node.body,inner);for(let child of node.body.nodes)this.visit(child,node.body,inner)}visitAwait(node,scope){if(this.visit(node.expression,node,scope),node.pending)this.visit(node.pending,node,scope);for(let[fragment,pattern,kind]of[[node.then,node.value,"await-value"],[node.catch,node.error,"await-error"]]){if(fragment===null)continue;this.visit(fragment,node,scope);let inner=this.made.get(fragment);if(pattern!==null&&inner!==void 0)this.declarePattern(pattern,node,inner,kind,node,null)}}declareImplicit(){for(let[id,label,right]of this.implicit)if(this.instance.get(id.name)===null)this.declare(this.instance,id,id.name,"reactive",label,right)}resolve(){let unordered=new Set;for(let reference of this.pending){let{node}=reference,declared=this.declared.get(node);if(declared!==void 0&&declared.kind!=="reactive")continue;this.references.set(node,reference);let{meaning}=reference,binding;if(meaning===VALUE)binding=reference.scope.get(node.name);else if(meaning!==ANY)binding=reference.scope.lookup(node.name,meaning);else if(reference.type)binding=reference.scope.getType(node.name)??reference.scope.get(node.name);else if(binding=reference.scope.get(node.name),binding===null){if(binding=reference.scope.getType(node.name),binding!==null)reference.type=!0,reference.reads=!1}if(binding===null&&this.component&&meaning!==TYPE){let store=this.storeOf(node.name);if(store!==!1)reference.store=!0,reference.mutates||=reference.writes,reference.reads=!reference.type,reference.writes=!1,binding=store}if(binding!==null){reference.binding=binding;let last=binding.references.at(-1);if(last!==void 0&&last.node.start>node.start)unordered.add(binding);binding.references.push(reference)}}for(let binding of unordered)binding.references.sort((a,b)=>a.node.start-b.node.start)}storeOf(name){let cached=this.stores.get(name);if(cached!==void 0)return cached;let store=!1;if(name.length>1&&name.startsWith("$")&&!name.startsWith("$$")){let declaration=this.instance.get(name.slice(1));if(!RUNE_NAMES.has(name))store=declaration;else if(declaration!==null){let initial=declaration.initial,rune=runeOf(initial,this.instance,null);if((rune===null||name!=="$props"&&rune==="$props")&&!(name==="$derived"&&initial?.type==="ImportDeclaration"&&initial.source.value==="svelte/store"))store=declaration}}return this.stores.set(name,store),store}findRunesAndProps(){for(let[declarator,scope]of this.declarators){let rune=runeOf(declarator.init??null,scope,this.references);if(rune===null)continue;for(let id of extractIdentifiers2(declarator.id)){let binding=this.declared.get(id);if(binding?.declaration===declarator)binding.rune=rune}if(rune!=="$props")continue;if(declarator.id.type==="Identifier"){let binding=this.declared.get(declarator.id);if(binding)binding.initial=null;continue}if(declarator.id.type!=="ObjectPattern")continue;for(let property of declarator.id.properties){if(property.type==="RestElement"){for(let id of extractIdentifiers2(property)){let binding=this.declared.get(id);if(binding)binding.initial=null}continue}let value=property.value.type==="AssignmentPattern"?property.value.left:property.value,binding=value.type==="Identifier"?this.declared.get(value):void 0;if(binding===void 0||property.computed)continue;binding.prop=keyName(property.key),binding.initial=property.value.type==="AssignmentPattern"?unwrapBindable(property.value.right):null}}this.findLegacyProps()}findLegacyProps(){if(this.instanceProgram===null)return;for(let statement of this.instanceProgram.body){if(statement.type!=="ExportNamedDeclaration")continue;let{declaration}=statement;if(declaration?.type==="VariableDeclaration"){if(declaration.kind!=="let"&&declaration.kind!=="var")continue;for(let declarator of declaration.declarations)for(let id of extractIdentifiers2(declarator.id)){let binding=this.declared.get(id);if(binding)binding.prop=id.name}continue}if(statement.source)continue;for(let specifier of statement.specifiers){if(specifier.local.type!=="Identifier")continue;let binding=this.instance.declarations.get(specifier.local.name);if(binding?.kind!=="let"&&binding?.kind!=="var")continue;binding.prop=specifier.exported.type==="Identifier"?specifier.exported.name:String(specifier.exported.value)}}}}function isReferenceInType(node,parent){switch(parent.type){case"TSPropertySignature":case"TSMethodSignature":return parent.computed===!0&&node===parent.key;case"TSTypePredicate":return node===parent.parameterName;default:return isReference2(node,parent)}}function isFunction(node){return node.type==="ArrowFunctionExpression"||node.type==="FunctionExpression"||node.type==="FunctionDeclaration"}function slotOf(node){if(!ELEMENTS.has(node.type)||!("attributes"in node))return null;for(let attribute of node.attributes??[])if(attribute.type==="Attribute"&&attribute.name==="slot"&&Array.isArray(attribute.value)&&attribute.value.length===1&&attribute.value[0].type==="Text")return attribute.value[0].data;return null}function runeOf(initial,scope,references){if(initial?.type!=="CallExpression")return null;let node=initial.callee,keypath="";while(node.type==="MemberExpression"){if(node.computed||node.property.type!=="Identifier")return null;keypath=`.${node.property.name}${keypath}`,node=node.object}if(node.type==="CallExpression"&&node.callee.type==="Identifier")keypath=`()${keypath}`,node=node.callee;if(node.type!=="Identifier")return null;if(references!==null){let reference=references.get(node);if(reference?.binding!==null||reference.store)return null}else if(scope.get(node.name)!==null)return null;return keypath=node.name+keypath,RUNES.has(keypath)?keypath:null}function unwrapBindable(node){if(node.type==="CallExpression"&&node.callee.type==="Identifier"&&node.callee.name==="$bindable"){let[argument]=node.arguments;return argument===void 0||argument.type==="SpreadElement"?null:argument}return node}function prefixLength(node){if(node.type==="UseDirective")return 4;if(node.type==="AnimateDirective")return 8;if(node.intro&&node.outro)return 11;return node.intro?3:4}function keyName(key){if(key.type==="Identifier")return key.name;return key.type==="Literal"?String(key.value):null}export{analyzeScopes};
|