sveast 0.9.4 → 0.9.6
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 +28 -5
- package/core.js +1 -1
- package/entities.js +1 -1
- package/index.d.ts +42 -8
- package/index.js +1 -1
- package/is-valid-type.js +1 -1
- package/lexer.d.ts +39 -7
- package/lexer.js +3 -3
- package/module.js +1 -1
- package/package.json +1 -1
- package/parse-imports-exports.js +1 -1
- package/parse-module.js +1 -1
- package/parse-sections.js +1 -1
- package/parse.js +1 -1
- package/runes.js +1 -1
- package/scope.d.ts +3 -1
- package/scope.js +1 -1
- package/shared-2pngd0mg.js +10 -0
- package/shared-5tpb3h6x.js +2 -0
- package/shared-a23q4q40.js +3 -0
- package/shared-as9z0pac.js +2 -0
- package/shared-bzqbnvee.js +2 -0
- package/shared-cs1ezg1f.js +2 -0
- package/shared-dgdrqgdn.js +2 -0
- package/shared-drb44hb9.js +2 -0
- package/shared-e4gbs4rb.js +3 -0
- package/shared-h6z1kjbb.js +2 -0
- package/shared-jpvd0875.js +2 -0
- package/shared-ke0fgd3r.js +2 -0
- package/shared-m0dcdh24.js +5 -0
- package/shared-m3dr31c3.js +2 -0
- package/shared-nan648gn.js +10 -0
- package/shared-qkp49nav.js +2 -0
- package/shared-tapcgcpr.js +2 -0
- package/shared-xwzsb4m8.js +3 -0
- package/shared-z9y4mrek.js +2 -0
- package/typescript.js +1 -1
- package/walk.js +1 -1
- package/shared-2by923ar.js +0 -3
- package/shared-3371ehgf.js +0 -2
- package/shared-4wqe6a27.js +0 -5
- package/shared-4zk9ntab.js +0 -2
- package/shared-artd3d80.js +0 -2
- package/shared-c9gzmr05.js +0 -2
- package/shared-h6c4cer7.js +0 -2
- package/shared-hjcsmz9f.js +0 -2
- package/shared-jxkrk6hx.js +0 -10
- package/shared-n0fpkmn8.js +0 -2
- package/shared-n1wnwhk8.js +0 -3
- package/shared-nbaaegmc.js +0 -2
- package/shared-rh41v5ez.js +0 -3
- package/shared-shxvsq2a.js +0 -2
- package/shared-stdj6se1.js +0 -2
- package/shared-v0nj05q2.js +0 -2
- package/shared-vjpq32kx.js +0 -2
- package/shared-xyqvjc3m.js +0 -10
- package/shared-znzncsf2.js +0 -2
package/README.md
CHANGED
|
@@ -25,7 +25,8 @@ ast.fragment.nodes; // [Text, RegularElement]
|
|
|
25
25
|
| [`parseSections`](#parsesectionssource-options--astroot) | A component's AST without the markup: its `<script>`s, `<style>` and `<svelte:options>` | `sveast` |
|
|
26
26
|
| [`parseModule`](#parsemodulesource-options--program) | A `.js` or `.ts` module's AST, the same as a component's `<script>` | `sveast` |
|
|
27
27
|
| [`parseImportsExports`](#parseimportsexportssource-options--moduledeclaration) | A module's `import` and `export` statements, without parsing the rest | `sveast` |
|
|
28
|
-
| [`lexImportsExports`](#leximportsexportssource--lexedstatement) | Their offsets, sources and names, without loading a parser | `sveast/lexer` |
|
|
28
|
+
| [`lexImportsExports`](#leximportsexportssource-options--lexedstatement) | Their offsets, sources and names, without loading a parser | `sveast/lexer` |
|
|
29
|
+
| [`lexDynamicImports`](#lexdynamicimportssource--lexeddynamicimport) | A module's `import(…)`, `require(…)` and `import.meta.glob(…)`, with their offsets and sources, without loading a parser | `sveast/lexer` |
|
|
29
30
|
| [`lexComponent`](#lexcomponentsource--lexedcomponent) | A component's `<script>`s, `<style>` and `<svelte:options>`, with their attributes and offsets, without loading a parser | `sveast/lexer` |
|
|
30
31
|
| [`lexStrings`](#lexstringssource--lexedstring) | A module's string and template literals, with their offsets and values, without loading a parser | `sveast/lexer` |
|
|
31
32
|
| [`createParser`, `createModuleParser`](#smaller-bundles-sveastcore-and-sveastmodule) | The parsers without TypeScript, named HTML entities or the template parser, for a smaller bundle | `sveast/core`, `sveast/module` |
|
|
@@ -145,7 +146,7 @@ Parses a JavaScript or TypeScript module, such as a `.ts` file a component impor
|
|
|
145
146
|
|
|
146
147
|
### `parseImportsExports(source, options?) => ModuleDeclaration[]`
|
|
147
148
|
|
|
148
|
-
A module's top-level `import` and `export` statements, without parsing the rest, e.g. to rewrite a component's imports or follow a module graph. Each node is the one `parseModule(source, { comments: false })` has for that statement: `ImportDeclaration`, `ExportNamedDeclaration`, `ExportDefaultDeclaration` and `ExportAllDeclaration`, and, in TypeScript, `TSImportEqualsDeclaration`, `TSExportAssignment` and `TSNamespaceExportDeclaration`. `import(...)` and `import.meta` are expressions, so they aren't returned. Unlike a regex, it never matches an `import` in a comment, a string, a template or a nested block such as `declare module "a" { ... }`.
|
|
149
|
+
A module's top-level `import` and `export` statements, without parsing the rest, e.g. to rewrite a component's imports or follow a module graph. Each node is the one `parseModule(source, { comments: false })` has for that statement: `ImportDeclaration`, `ExportNamedDeclaration`, `ExportDefaultDeclaration` and `ExportAllDeclaration`, and, in TypeScript, `TSImportEqualsDeclaration`, `TSExportAssignment` and `TSNamespaceExportDeclaration`. `import(...)` and `import.meta` are expressions, so they aren't returned; [`lexDynamicImports`](#lexdynamicimportssource--lexeddynamicimport) finds them. Unlike a regex, it never matches an `import` in a comment, a string, a template or a nested block such as `declare module "a" { ... }`.
|
|
149
150
|
|
|
150
151
|
It stops after the last `import` or `export` that could start a statement, so the code after a component's imports is never read: on Carbon's component scripts, it takes a third of `parseModule`'s time, and about a seventh with `localExports: false`. A syntax error in a statement it returns throws a `ParseError`, including a name exported twice; errors elsewhere aren't reported.
|
|
151
152
|
|
|
@@ -164,12 +165,14 @@ function dependencies(source: string, typescript = false): string[] {
|
|
|
164
165
|
}
|
|
165
166
|
```
|
|
166
167
|
|
|
167
|
-
### `lexImportsExports(source) => LexedStatement[]`
|
|
168
|
+
### `lexImportsExports(source, options?) => LexedStatement[]`
|
|
168
169
|
|
|
169
170
|
From `sveast/lexer`, and also `sveast`. A module's top-level `import` statements and `export … from` re-exports, read by hand instead of parsed, for a tool on a hot or eagerly loaded path, such as a preprocessor that rewrites a component's imports, that needs each statement's offsets, source and names, but not the AST. `sveast/lexer` loads no parser, so a fresh process imports it in 1.4 ms, and on Carbon's component scripts it takes 40% of the time `parseImportsExports` takes with `localExports: false`.
|
|
170
171
|
|
|
171
172
|
It finds the statements `parseImportsExports` returns with `localExports: false`, with the same offsets, sources and names. It doesn't check syntax and never throws: a statement it can't read, such as `import { a from "a"` or `import a = require("a")`, has `source: null` and no specifiers, and ends where it stopped reading. `import type` and `type` before a name are always read.
|
|
172
173
|
|
|
174
|
+
With `exportLists: true`, it also returns each top-level `export { a, b as c }` without `from`, e.g. to follow a binding through an `index.js` that imports it and exports it again: `source` is `null`, and each specifier has kind `local`, with `local` the binding in this module. Those are the `ExportNamedDeclaration`s without a declaration that `parseImportsExports` returns with `localExports: true`; `export const a`, `export function b` and `export default` still aren't returned. A module that ends with an export list is read to its end.
|
|
175
|
+
|
|
173
176
|
```ts
|
|
174
177
|
import { lexImportsExports } from "sveast/lexer";
|
|
175
178
|
|
|
@@ -181,7 +184,7 @@ for (const statement of lexImportsExports(source)) {
|
|
|
181
184
|
statement.typeOnly; // `import type …` or `export type …`
|
|
182
185
|
statement.specifiers;
|
|
183
186
|
// import: { kind: "default" | "namespace" | "named", imported, local, typeOnly, start, end }
|
|
184
|
-
// export: { kind: "all" | "namespace" | "named", local, exported, typeOnly, start, end }
|
|
187
|
+
// export: { kind: "all" | "namespace" | "named" | "local", local, exported, typeOnly, start, end }
|
|
185
188
|
}
|
|
186
189
|
```
|
|
187
190
|
|
|
@@ -191,9 +194,29 @@ for (const statement of lexImportsExports(source)) {
|
|
|
191
194
|
| `* as a` | `namespace`, `imported: "*"`, `local: "a"` | `namespace`, `local: "*"`, `exported: "a"` |
|
|
192
195
|
| `*` | | `all`, `local: "*"`, `exported: null` |
|
|
193
196
|
| `b as c`, `"b-c" as d` | `named`, `imported: "b"`, `local: "c"` | `named`, `local: "b"`, `exported: "c"` |
|
|
197
|
+
| `b as c` in `export { … }`, with `exportLists` | | `local`, `local: "b"`, `exported: "c"` |
|
|
194
198
|
|
|
195
199
|
Names are as the module sees them: escapes decoded, and a string name without its quotes. A specifier's `typeOnly` is also `true` in an `import type` or `export type`. Its `start` is that of `type` before the name, if any, and `end` is after the last name; for `export *`, after the `*`.
|
|
196
200
|
|
|
201
|
+
### `lexDynamicImports(source) => LexedDynamicImport[]`
|
|
202
|
+
|
|
203
|
+
From `sveast/lexer`, and also `sveast`. A module's `import(…)` and `require(…)` calls and Vite's `import.meta.glob(…)`, at any depth, in source order, read without parsing, e.g. to follow the lazily loaded part of a module graph. Unlike a regular expression, it never matches in a comment, a string, a template or a regular expression, and it tells a literal argument from a computed one. `lexImportsExports` finds the static imports; together they're a module's dependencies.
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { lexDynamicImports } from "sveast/lexer";
|
|
207
|
+
|
|
208
|
+
for (const call of lexDynamicImports(source)) {
|
|
209
|
+
call.kind; // "import" | "require" | "glob"
|
|
210
|
+
call.start; // offset of `import` or `require`
|
|
211
|
+
call.end; // after the `)`
|
|
212
|
+
call.source; // { value: "./Chart.svelte", start, end } (quotes or backticks included), or null
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`source` is the first argument if it's a string or a template without `${…}` and it's followed by `)` or `,`, as in `import("a", { with: { type: "json" } })`; it's `null` for a computed argument such as `` import(`./${name}.js`) `` or `import.meta.glob(["a", "b"])`, and for a call without arguments. Type arguments are skipped, as in `import.meta.glob<Module>("./*.ts")`.
|
|
217
|
+
|
|
218
|
+
Where `parseModule` accepts the module, the calls are its `ImportExpression`s, its calls of an identifier `require`, `new require(…)` included, and of `import.meta.glob`, and in TypeScript also its `import("a")` types, as in `typeof import("a")`, and the `require("a")` of `import a = require("a")`. A method named `import` or `require`, such as `{ import() {} }`, isn't a call, and neither are `a.require(…)`, `require?.(…)` or `(require)(…)`. It doesn't check syntax and never throws. It matched `parseModule` on all 33,001 modules and component scripts it accepts from the projects under [Parity and performance](#parity-and-performance), svelte's tests and TypeScript's conformance tests.
|
|
219
|
+
|
|
197
220
|
### `lexComponent(source) => LexedComponent`
|
|
198
221
|
|
|
199
222
|
From `sveast/lexer`, and also `sveast`. A component's top-level `<script>`, `<script module>`, `<style>` and `<svelte:options>`, with their attributes and the offsets of their tags and content, found without parsing: e.g. to read a component's scripts and their imports, its language or its options, or to rewrite a script, on a path that can't afford a parser. On the benchmark corpus it's about 50× faster than `parse`.
|
|
@@ -385,7 +408,7 @@ size?.references.some((reference) => reference.writes || reference.mutates); //
|
|
|
385
408
|
It returns:
|
|
386
409
|
|
|
387
410
|
- **`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.
|
|
388
|
-
- **`scopeOf(node)`**, the scope a node is in; `null` in a type, the `<style>` or another AST.
|
|
411
|
+
- **`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.
|
|
389
412
|
- **`bindingOf(identifier)`**, the binding an `Identifier` declares or refers to; `null` for a global, a property key or a name in a type.
|
|
390
413
|
- **`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.
|
|
391
414
|
- **`declaredIn(node)`**, the bindings of the scope a node makes: a function's parameters (its body's declarations are its body's), a block's or an each block's declarations, a snippet's parameters, or an element's `let:` names.
|
package/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./shared-
|
|
1
|
+
import"./shared-dgdrqgdn.js";import"./shared-m0dcdh24.js";import"./shared-2pngd0mg.js";import{ParseError2}from"./shared-nan648gn.js";import"./shared-5tpb3h6x.js";import{xmlEntityNames}from"./shared-bzqbnvee.js";import{parseComponent}from"./shared-xwzsb4m8.js";import"./shared-e4gbs4rb.js";import{parseModuleWith}from"./shared-z9y4mrek.js";import{parseImportsExportsWith}from"./shared-tapcgcpr.js";import{typeScriptParser,entityNamesOf}from"./shared-h6z1kjbb.js";function createParser(support={}){let typescript=typeScriptParser(support.typescript),internal={typescript,entityNames:entityNamesOf(support.entities)??xmlEntityNames};return{parse:(source,options)=>parseComponent(source,options,internal),parseModule:(source,options={})=>parseModuleWith(source,options,typescript),parseImportsExports:(source,options={})=>parseImportsExportsWith(source,options,typescript)}}export{ParseError2 as ParseError,createParser};
|
package/entities.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./shared-
|
|
1
|
+
import"./shared-bzqbnvee.js";import{htmlEntityNames}from"./shared-drb44hb9.js";import{entitySupport}from"./shared-h6z1kjbb.js";var entities=entitySupport(htmlEntityNames);export{entities};
|
package/index.d.ts
CHANGED
|
@@ -41,11 +41,11 @@ export interface LexedImportSpecifier {
|
|
|
41
41
|
end: number;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
/** A name an `export … from` re-exports. */
|
|
44
|
+
/** A name an `export … from` re-exports, or, with `exportLists`, one an `export { … }` without `from` exports. */
|
|
45
45
|
export interface LexedExportSpecifier {
|
|
46
|
-
/** `"all"` for `export *`, `"namespace"` for `export * as a`, `"named"` for a name in braces
|
|
47
|
-
kind: "all" | "namespace" | "named";
|
|
48
|
-
/** The name in the other module: `"*"` for `all` and `namespace`, or the name before `as`, with a string's value for `"a-b" as c
|
|
46
|
+
/** `"all"` for `export *`, `"namespace"` for `export * as a`, `"named"` for a name in braces, `"local"` for a name in an `export { … }` without `from`. */
|
|
47
|
+
kind: "all" | "namespace" | "named" | "local";
|
|
48
|
+
/** The name in the other module: `"*"` for `all` and `namespace`, or the name before `as`, with a string's value for `"a-b" as c`; for `local`, the binding in this module. */
|
|
49
49
|
local: string;
|
|
50
50
|
/** The name it's exported as, or `null` for `export *`. */
|
|
51
51
|
exported: string | null;
|
|
@@ -62,7 +62,7 @@ interface LexedStatementBase {
|
|
|
62
62
|
start: number;
|
|
63
63
|
/** The offset after the statement's `;`, or its last token without one. */
|
|
64
64
|
end: number;
|
|
65
|
-
/** The module it imports from, or `null` for a statement the lexer doesn't recognize. */
|
|
65
|
+
/** The module it imports from, or `null` for an `export { … }` without `from`, or a statement the lexer doesn't recognize. */
|
|
66
66
|
source: LexedSource | null;
|
|
67
67
|
/** Whether it's `import type` or `export type`. */
|
|
68
68
|
typeOnly: boolean;
|
|
@@ -74,7 +74,7 @@ export interface LexedImport extends LexedStatementBase {
|
|
|
74
74
|
specifiers: LexedImportSpecifier[];
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/** An `export … from` statement
|
|
77
|
+
/** An `export … from` statement, or, with `exportLists`, an `export { … }` without `from`. */
|
|
78
78
|
export interface LexedExport extends LexedStatementBase {
|
|
79
79
|
kind: "export";
|
|
80
80
|
specifiers: LexedExportSpecifier[];
|
|
@@ -82,6 +82,24 @@ export interface LexedExport extends LexedStatementBase {
|
|
|
82
82
|
|
|
83
83
|
export type LexedStatement = LexedImport | LexedExport;
|
|
84
84
|
|
|
85
|
+
/** Options for {@link lexImportsExports}. */
|
|
86
|
+
export interface LexImportsExportsOptions {
|
|
87
|
+
/** Also return the module's `export { a, b as c }` statements without `from`, whose specifiers have kind `"local"`. Default `false`. */
|
|
88
|
+
exportLists?: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** An `import(…)`, a `require(…)` or Vite's `import.meta.glob(…)`. */
|
|
92
|
+
export interface LexedDynamicImport {
|
|
93
|
+
/** `"import"` for `import(…)`, `"require"` for `require(…)`, `"glob"` for `import.meta.glob(…)`. */
|
|
94
|
+
kind: "import" | "require" | "glob";
|
|
95
|
+
/** The first argument, if it's a string or a template without `${…}` followed by `)` or `,`; `null` for a computed one. A template's `start` and `end` include its backticks. */
|
|
96
|
+
source: LexedSource | null;
|
|
97
|
+
/** The offset of `import` or `require`. */
|
|
98
|
+
start: number;
|
|
99
|
+
/** The offset after the closing `)`, or the end of the module without one. */
|
|
100
|
+
end: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
85
103
|
/** A string literal, or the text of a template literal between two of its delimiters. */
|
|
86
104
|
export interface LexedString {
|
|
87
105
|
/** `"string"` for a string literal, where `parseModule` has a `Literal`; `"template"` for a template's text, where it has a `TemplateElement`. */
|
|
@@ -105,7 +123,21 @@ export interface LexedString {
|
|
|
105
123
|
* `source: null` and no specifiers, ending where it stopped reading.
|
|
106
124
|
* TypeScript's `type` forms are always read.
|
|
107
125
|
*/
|
|
108
|
-
export declare function lexImportsExports(source: string): LexedStatement[];
|
|
126
|
+
export declare function lexImportsExports(source: string, options?: LexImportsExportsOptions): LexedStatement[];
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* A module's `import(…)` and `require(…)` calls and Vite's
|
|
130
|
+
* `import.meta.glob(…)`, at any depth, in source order, read without a
|
|
131
|
+
* parser: each call's offsets and its first argument, if it's a string or
|
|
132
|
+
* a template without `${…}`. Comments, strings, templates and regular
|
|
133
|
+
* expressions are skipped, as {@link lexStrings} skips them, and it never
|
|
134
|
+
* throws. Where {@link parseModule} accepts the module, they are its
|
|
135
|
+
* `ImportExpression`s, its calls of an identifier `require` and of
|
|
136
|
+
* `import.meta.glob`, and, in TypeScript, its `import("a")` types and
|
|
137
|
+
* `import a = require("a")`. A method named `import` or `require` isn't a
|
|
138
|
+
* call.
|
|
139
|
+
*/
|
|
140
|
+
export declare function lexDynamicImports(source: string): LexedDynamicImport[];
|
|
109
141
|
|
|
110
142
|
/**
|
|
111
143
|
* A module's string literals and the text of its template literals, in
|
|
@@ -2147,7 +2179,9 @@ export interface Scopes {
|
|
|
2147
2179
|
/**
|
|
2148
2180
|
* The scope `node` is in: for a function, the scope around it, while
|
|
2149
2181
|
* its parameters are in its own. `null` for a node in a type, in the
|
|
2150
|
-
* `<style>` or outside the AST.
|
|
2182
|
+
* `<style>` or outside the AST. The first call walks the AST again to
|
|
2183
|
+
* record every node's scope, which the rest of the analysis doesn't
|
|
2184
|
+
* need.
|
|
2151
2185
|
*/
|
|
2152
2186
|
scopeOf(node: AST.SvelteNode): Scope | null;
|
|
2153
2187
|
/**
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isValidType
|
|
1
|
+
import{isValidType}from"./is-valid-type.js";import{lexComponent,lexDynamicImports,lexImportsExports,lexStrings}from"./lexer.js";import{parse}from"./parse.js";import{parseImportsExports}from"./parse-imports-exports.js";import{ParseError,parseModule}from"./parse-module.js";import{parseSections}from"./parse-sections.js";import{isRunesMode}from"./runes.js";import{analyzeScopes}from"./scope.js";import{children,createLocator,extractIdentifiers,forEachChild,isReference,locate,markupVisitorKeys,SKIP,STOP,skipTypeWrappers,valueVisitorKeys,visitorKeys,walk}from"./walk.js";export{ParseError,SKIP,STOP,analyzeScopes,children,createLocator,extractIdentifiers,forEachChild,isReference,isRunesMode,isValidType,lexComponent,lexDynamicImports,lexImportsExports,lexStrings,locate,markupVisitorKeys,parse,parseImportsExports,parseModule,parseSections,skipTypeWrappers,valueVisitorKeys,visitorKeys,walk};
|
package/is-valid-type.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{Parser}from"./shared-2pngd0mg.js";import{tsPlugin}from"./shared-cs1ezg1f.js";var RESERVED_WORDS=new Set("abstract accessor arguments as asserts async await break case catch class const continue debugger declare default delete do else enum eval export extends false finally for function get global if implements import in infer instanceof interface intrinsic is keyof let module namespace new null of out override package private protected public readonly return satisfies set static super switch this throw true try type typeof unique var void while with yield".split(" ")),STANDALONE_WORDS=new Set("any bigint boolean false never null number object string symbol true undefined unknown void".split(" ")),MODIFIER_KEYS=new Set("get set new readonly static public private protected".split(" "));function isWordStart(code){return code>=97&&code<=122||code>=65&&code<=90||code===95||code===36}function isDigit(code){return code>=48&&code<=57}function isWordPart(code){return isWordStart(code)||isDigit(code)}class CommonTypeReader{text;pos=0;constructor(text){this.text=text}readAll(){if(!this.type())return!1;return this.peek(),this.pos===this.text.length}peek(){let text=this.text,pos=this.pos,code=text.charCodeAt(pos);while(code===32||code===9)code=text.charCodeAt(++pos);return this.pos=pos,code}eat(char){if(this.peek()!==char.charCodeAt(0))return!1;return this.pos++,!0}word(){let start=this.pos;return this.skipWord()?this.text.slice(start,this.pos):void 0}skipWord(){if(!isWordStart(this.peek()))return!1;let end=this.pos+1;while(isWordPart(this.text.charCodeAt(end)))end++;return this.pos=end,!0}keyword(word){this.peek();let end=this.pos+word.length;if(!this.text.startsWith(word,this.pos)||isWordPart(this.text.charCodeAt(end)))return!1;return this.pos=end,!0}name(){let word=this.word();return word!==void 0&&!RESERVED_WORDS.has(word)}string(){let quote=this.peek();if(quote!==34&"e!==39)return!1;let text=this.text;for(let i=this.pos+1;i<text.length;i++){let code=text.charCodeAt(i);if(code===quote)return this.pos=i+1,!0;if(code===92||code===10||code===13||code===8232||code===8233)return!1}return!1}number(){let text=this.text,i=this.pos;if(text.charCodeAt(i)===45)i++;let digits=i;while(isDigit(text.charCodeAt(i)))i++;if(i===digits||i-digits>1&&text.charCodeAt(digits)===48)return!1;if(text.charCodeAt(i)===46){let fraction=++i;while(isDigit(text.charCodeAt(i)))i++;if(i===fraction)return!1}let next=text.charCodeAt(i);if(isWordPart(next)||next===46)return!1;return this.pos=i,!0}type(){if(this.peek()===40){let start=this.pos;if(this.functionType())return!0;this.pos=start}do do if(!this.operatorType())return!1;while(this.eat("&"));while(this.eat("|"));return!0}operatorType(){if(this.keyword("keyof"))return this.operatorType();if(!this.primaryType())return!1;while(this.eat("[")){if(this.eat("]"))continue;if(!this.type()||!this.eat("]"))return!1}return!0}primaryType(){let code=this.peek();if(code===40)return this.pos++,this.type()&&this.eat(")");if(code===123)return this.objectType();if(code===91)return this.tupleType();if(code===34||code===39)return this.string();if(code===45||isDigit(code))return this.number();let word=this.word();if(word===void 0)return!1;if(word==="typeof")return this.typeQuery();if(word==="import")return this.importType(!0);if(STANDALONE_WORDS.has(word)){let next=this.peek();return next!==46&&next!==60}if(RESERVED_WORDS.has(word))return!1;while(this.eat("."))if(!this.skipWord())return!1;return!this.eat("<")||this.typeArguments()}typeArguments(){do if(!this.type())return!1;while(this.eat(","));return this.eat(">")}typeQuery(){if(this.keyword("import"))return this.importType(!1);do if(!this.name())return!1;while(this.eat("."));return!0}importType(allowTypeArguments){if(!this.eat("(")||!this.string()||!this.eat(")"))return!1;while(this.eat("."))if(!this.name())return!1;return!allowTypeArguments||!this.eat("<")||this.typeArguments()}objectType(){this.pos++;while(!this.eat("}")){if(!this.typeMember())return!1;if(!this.eat(";")&&!this.eat(",")&&this.peek()!==125)return!1}return!0}typeMember(){let code=this.peek();if(this.eat("[")){let next=this.peek();if(next===34||next===39){if(!this.string()||!this.eat("]"))return!1}else return this.name()&&this.eat(":")&&this.type()&&this.eat("]")&&this.eat(":")&&this.type()}else if(code===34||code===39){if(!this.string())return!1}else{let key=this.word();if(key===void 0||MODIFIER_KEYS.has(key))return!1}return this.eat("?"),this.eat(":")&&this.type()}tupleType(){if(this.pos++,this.eat("]"))return!0;do if(!this.type())return!1;while(this.eat(","));return this.eat("]")}functionType(){if(this.pos++,!this.eat(")")){let names=new Set;for(;;){this.peek();let rest=this.text.startsWith("...",this.pos);if(rest)this.pos+=3;let name=this.word();if(name===void 0||RESERVED_WORDS.has(name)||names.has(name))return!1;if(names.add(name),!rest)this.eat("?");if(!this.eat(":")||!this.type())return!1;if(rest||!this.eat(","))break}if(!this.eat(")"))return!1}if(this.peek(),!this.text.startsWith("=>",this.pos))return!1;return this.pos+=2,this.type()}}function isCommonType(text){return new CommonTypeReader(text).readAll()}var TypeParser=Parser.extend(tsPlugin);function isValidType(text,options={}){return isCommonType(text)||parsesAsType(text,options.inline??!1)}function parsesAsType(text,inline){let lineCommentAtEnd=!1,parser=new TypeParser(inline?{ecmaVersion:16,sourceType:"module",onComment:(block,_text,_start,end)=>{if(!block&&end===text.length)lineCommentAtEnd=!0}}:{ecmaVersion:16,sourceType:"module"},text);try{return parser.parseWholeType(),!lineCommentAtEnd}catch(error){if(error instanceof SyntaxError)return!1;throw error}}export{isValidType,parsesAsType};
|
package/lexer.d.ts
CHANGED
|
@@ -24,11 +24,11 @@ export interface LexedImportSpecifier {
|
|
|
24
24
|
end: number;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/** A name an `export … from` re-exports. */
|
|
27
|
+
/** A name an `export … from` re-exports, or, with `exportLists`, one an `export { … }` without `from` exports. */
|
|
28
28
|
export interface LexedExportSpecifier {
|
|
29
|
-
/** `"all"` for `export *`, `"namespace"` for `export * as a`, `"named"` for a name in braces
|
|
30
|
-
kind: "all" | "namespace" | "named";
|
|
31
|
-
/** The name in the other module: `"*"` for `all` and `namespace`, or the name before `as`, with a string's value for `"a-b" as c
|
|
29
|
+
/** `"all"` for `export *`, `"namespace"` for `export * as a`, `"named"` for a name in braces, `"local"` for a name in an `export { … }` without `from`. */
|
|
30
|
+
kind: "all" | "namespace" | "named" | "local";
|
|
31
|
+
/** The name in the other module: `"*"` for `all` and `namespace`, or the name before `as`, with a string's value for `"a-b" as c`; for `local`, the binding in this module. */
|
|
32
32
|
local: string;
|
|
33
33
|
/** The name it's exported as, or `null` for `export *`. */
|
|
34
34
|
exported: string | null;
|
|
@@ -45,7 +45,7 @@ interface LexedStatementBase {
|
|
|
45
45
|
start: number;
|
|
46
46
|
/** The offset after the statement's `;`, or its last token without one. */
|
|
47
47
|
end: number;
|
|
48
|
-
/** The module it imports from, or `null` for a statement the lexer doesn't recognize. */
|
|
48
|
+
/** The module it imports from, or `null` for an `export { … }` without `from`, or a statement the lexer doesn't recognize. */
|
|
49
49
|
source: LexedSource | null;
|
|
50
50
|
/** Whether it's `import type` or `export type`. */
|
|
51
51
|
typeOnly: boolean;
|
|
@@ -57,7 +57,7 @@ export interface LexedImport extends LexedStatementBase {
|
|
|
57
57
|
specifiers: LexedImportSpecifier[];
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/** An `export … from` statement
|
|
60
|
+
/** An `export … from` statement, or, with `exportLists`, an `export { … }` without `from`. */
|
|
61
61
|
export interface LexedExport extends LexedStatementBase {
|
|
62
62
|
kind: "export";
|
|
63
63
|
specifiers: LexedExportSpecifier[];
|
|
@@ -65,6 +65,24 @@ export interface LexedExport extends LexedStatementBase {
|
|
|
65
65
|
|
|
66
66
|
export type LexedStatement = LexedImport | LexedExport;
|
|
67
67
|
|
|
68
|
+
/** Options for {@link lexImportsExports}. */
|
|
69
|
+
export interface LexImportsExportsOptions {
|
|
70
|
+
/** Also return the module's `export { a, b as c }` statements without `from`, whose specifiers have kind `"local"`. Default `false`. */
|
|
71
|
+
exportLists?: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** An `import(…)`, a `require(…)` or Vite's `import.meta.glob(…)`. */
|
|
75
|
+
export interface LexedDynamicImport {
|
|
76
|
+
/** `"import"` for `import(…)`, `"require"` for `require(…)`, `"glob"` for `import.meta.glob(…)`. */
|
|
77
|
+
kind: "import" | "require" | "glob";
|
|
78
|
+
/** The first argument, if it's a string or a template without `${…}` followed by `)` or `,`; `null` for a computed one. A template's `start` and `end` include its backticks. */
|
|
79
|
+
source: LexedSource | null;
|
|
80
|
+
/** The offset of `import` or `require`. */
|
|
81
|
+
start: number;
|
|
82
|
+
/** The offset after the closing `)`, or the end of the module without one. */
|
|
83
|
+
end: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
68
86
|
/** A string literal, or the text of a template literal between two of its delimiters. */
|
|
69
87
|
export interface LexedString {
|
|
70
88
|
/** `"string"` for a string literal, where `parseModule` has a `Literal`; `"template"` for a template's text, where it has a `TemplateElement`. */
|
|
@@ -88,7 +106,21 @@ export interface LexedString {
|
|
|
88
106
|
* `source: null` and no specifiers, ending where it stopped reading.
|
|
89
107
|
* TypeScript's `type` forms are always read.
|
|
90
108
|
*/
|
|
91
|
-
export declare function lexImportsExports(source: string): LexedStatement[];
|
|
109
|
+
export declare function lexImportsExports(source: string, options?: LexImportsExportsOptions): LexedStatement[];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A module's `import(…)` and `require(…)` calls and Vite's
|
|
113
|
+
* `import.meta.glob(…)`, at any depth, in source order, read without a
|
|
114
|
+
* parser: each call's offsets and its first argument, if it's a string or
|
|
115
|
+
* a template without `${…}`. Comments, strings, templates and regular
|
|
116
|
+
* expressions are skipped, as {@link lexStrings} skips them, and it never
|
|
117
|
+
* throws. Where {@link parseModule} accepts the module, they are its
|
|
118
|
+
* `ImportExpression`s, its calls of an identifier `require` and of
|
|
119
|
+
* `import.meta.glob`, and, in TypeScript, its `import("a")` types and
|
|
120
|
+
* `import a = require("a")`. A method named `import` or `require` isn't a
|
|
121
|
+
* call.
|
|
122
|
+
*/
|
|
123
|
+
export declare function lexDynamicImports(source: string): LexedDynamicImport[];
|
|
92
124
|
|
|
93
125
|
/**
|
|
94
126
|
* A module's string literals and the text of its template literals, in
|
package/lexer.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`,
|
|
3
|
-
`;case 114:return"\r";case 116:return"\t";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 48:return
|
|
1
|
+
import{isDigit}from"./shared-5tpb3h6x.js";import{isWordCode,scan,scanLiterals,scanCalls,closingBracket,lineEnd,skipTrivia,isWordAt}from"./shared-e4gbs4rb.js";import"./shared-dgdrqgdn.js";import{lexComponent2}from"./shared-a23q4q40.js";function lexImportsExports(source,options={}){let lexer=new Lexer(source);lexer.exportLists=options.exportLists??!1;let statements=[];return scan(source,!1,(_start,keyword)=>{let statement=lexer.statement(keyword);return statements.push(statement),statement.end},lexer.exportLists),statements}function lexDynamicImports(source){let lexer=new Lexer(source),imports=[];return scanCalls(source,(start,member)=>{let call=lexer.dynamicImport(start,member);if(call!==null)imports.push(call)}),imports}function lexStrings(source){let lexer=new Lexer(source),strings=[];return scanLiterals(source,(start,end,template)=>{let quote=template?0:1;strings.push({kind:template?"template":"string",value:lexer.cooked(start+quote,end-quote,template),start,end})}),strings}class Lexer{source;pos=0;end=0;escapeEnd=0;exportLists=!1;constructor(source){this.source=source}statement(keyword){this.pos=this.end=keyword+6;let statement={kind:this.source.charCodeAt(keyword)===105?"import":"export",start:keyword,end:0,source:null,typeOnly:!1,specifiers:[]};if(!(statement.kind==="import"?this.import(statement):this.export(statement)))statement.source=null,statement.specifiers=[];return statement.end=this.end,statement}import(statement){let module=this.string();if(module!==null)return statement.source=module,this.finish();if(this.isWord("type")){let next=this.peekAfter(4);if(next===123||next===42||isIdentifierStart(next)&&!this.isWordAfter(4,"from"))statement.typeOnly=!0,this.advance(4)}let{specifiers,typeOnly}=statement,next=this.at();if(next!==123&&next!==42){let start=this.pos,local=this.name();if(local===null)return!1;if(this.at()===61)return this.importEquals();if(specifiers.push({kind:"default",imported:"default",local,typeOnly,start,end:this.end}),!this.eat(44))return this.from(statement);next=this.at()}if(next===42){let start=this.pos;if(this.advance(1),!this.eatWord("as"))return!1;let local=this.name();if(local===null)return!1;return specifiers.push({kind:"namespace",imported:"*",local,typeOnly,start,end:this.end}),this.from(statement)}if(!this.eat(123))return!1;while(!this.eat(125)){let start=this.skip(),named=this.typeModifier()||typeOnly,name=this.name(),imported=name??this.string()?.value;if(imported===void 0)return!1;let local=name;if(this.eatWord("as"))local=this.name();if(local===null)return!1;if(specifiers.push({kind:"named",imported,local,typeOnly:named,start,end:this.end}),!this.eat(44)&&this.at()!==125)return!1}return this.from(statement)}export(statement){if(this.eatWord("import")){if(this.isWord("type")&&isIdentifierStart(this.peekAfter(4))&&!this.isWordAfter(4,"from"))statement.typeOnly=!0,this.advance(4);return this.name()!==null&&this.at()===61&&this.importEquals()}if(this.isWord("type")){let next=this.peekAfter(4);if(next===123||next===42)statement.typeOnly=!0,this.advance(4)}let{specifiers,typeOnly}=statement;if(this.at()===42){let start=this.pos;this.advance(1);let exported=null;if(this.eatWord("as")){if(exported=this.moduleExportName(),exported===null)return!1}return specifiers.push({kind:exported===null?"all":"namespace",local:"*",exported,typeOnly,start,end:this.end}),this.from(statement)}if(!this.eat(123))return!1;while(!this.eat(125)){let start=this.skip(),named=this.typeModifier()||typeOnly,local=this.moduleExportName();if(local===null)return!1;let exported=local;if(this.eatWord("as"))exported=this.moduleExportName();if(exported===null)return!1;if(specifiers.push({kind:"named",local,exported,typeOnly:named,start,end:this.end}),!this.eat(44)&&this.at()!==125)return!1}if(this.exportLists&&!this.isWord("from")){for(let specifier of specifiers)specifier.kind="local";return this.eat(59),!0}return this.from(statement)}dynamicImport(start,member){let isImport=this.source.charCodeAt(start)===105;this.pos=this.end=start+(isImport?6:7);let kind=isImport?"import":"require";if(isImport&&this.eat(46)){if(!this.eatWord("meta")||!this.eat(46)||!this.eatWord("glob")||!this.typeArguments())return null;kind="glob"}if(!this.eat(40))return null;let argument=this.skip(),source=this.string()??this.template(),close=this.at()===41?this.pos:-1;if(close===-1){if(this.at()!==44)source=null;close=closingBracket(this.source,argument)}if(member&&kind!=="glob"){let after=this.source.charCodeAt(skipTrivia(this.source,close+1));if(after===123||after===58)return null}return{kind,source,start,end:Math.min(close+1,this.source.length)}}typeArguments(){if(this.at()!==60)return!0;let source=this.source,depth=0;for(let i=this.pos;i<source.length;i=skipTrivia(source,i+1)){let code=source.charCodeAt(i);if(code===34||code===39||code===96){let end=source.indexOf(source[i],i+1);if(end===-1)return!1;i=end}else if(code===60)depth++;else if(code===62&&source.charCodeAt(i-1)!==61){if(--depth===0)return this.advance(i+1-this.pos),!0}}return!1}template(){let source=this.source,start=this.skip();if(source.charCodeAt(start)!==96)return null;for(let i=start+1;i<source.length;i++){let code=source.charCodeAt(i);if(code===96){let value=this.cooked(start+1,i,!0);if(value===null)return null;return this.advance(i+1-start),{value,start,end:i+1}}if(code===92)i++;else if(code===36&&source.charCodeAt(i+1)===123)return null}return null}typeModifier(){if(!this.isWord("type"))return!1;let next=this.peekAfter(4);if(next===34||next===39||isIdentifierStart(next)&&!this.isWordAfter(4,"as"))return this.advance(4),!0;return!1}importEquals(){if(this.advance(1),this.isWord("require")&&this.peekAfter(7)===40){if(this.advance(7),this.eat(40),this.string()===null||!this.eat(41))return!1}else do if(this.name()===null)return!1;while(this.eat(46));return this.eat(59),!0}from(statement){if(!this.eatWord("from"))return!1;return statement.source=this.string(),statement.source!==null&&this.finish()}finish(){let keyword=this.isWord("with")?4:0;if(this.isWord("assert")&&lineEnd(this.source,this.end)>=this.pos)keyword=6;if(keyword!==0&&this.peekAfter(keyword)===123){this.advance(keyword),this.eat(123);while(!this.eat(125))if(this.string()===null&&this.name()===null&&!this.eat(58)&&!this.eat(44))return!1}return this.eat(59),!0}skip(){return this.pos=skipTrivia(this.source,this.pos),this.pos}at(){return this.source.charCodeAt(this.skip())}advance(length){this.pos+=length,this.end=this.pos}peekAfter(length){return this.source.charCodeAt(skipTrivia(this.source,this.pos+length))}isWordAfter(length,word){return isWordAt(this.source,skipTrivia(this.source,this.pos+length),word)}eat(code){if(this.at()!==code)return!1;return this.advance(1),!0}isWord(word){return isWordAt(this.source,this.skip(),word)}eatWord(word){if(!this.isWord(word))return!1;return this.advance(word.length),!0}moduleExportName(){return this.name()??this.string()?.value??null}name(){let source=this.source,start=this.skip();if(!isWordCode(source.charCodeAt(start))||isDigit(source.charCodeAt(start)))return null;let value="",chunk=start,i=start;while(i<source.length){let code=source.charCodeAt(i);if(code===92){if(source.charCodeAt(i+1)!==117)return null;let escaped=this.unicodeEscape(i+2);if(escaped===null)return null;value+=source.slice(chunk,i)+escaped,i=chunk=this.escapeEnd}else if(isWordCode(code))i++;else break}return this.advance(i-start),value+source.slice(chunk,i)}string(){let source=this.source,start=this.skip(),quote=source.charCodeAt(start);if(quote!==34&"e!==39)return null;let value="",chunk=start+1;for(let i=chunk;i<source.length;){let code=source.charCodeAt(i);if(code===quote)return this.advance(i+1-start),{value:value+source.slice(chunk,i),start,end:i+1};if(code===10||code===13)return null;if(code===92){let escaped=this.escape(i+1);if(escaped===null)return null;value+=source.slice(chunk,i)+escaped,i=chunk=this.escapeEnd}else i++}return null}cooked(from,to,template){let source=this.source,value="",chunk=from;for(let i=from;i<to;){let code=source.charCodeAt(i);if(code===92){let escaped=this.escape(i+1);if(escaped===null)return null;value+=source.slice(chunk,i)+escaped,i=chunk=this.escapeEnd}else if(code===13&&template)value+=`${source.slice(chunk,i)}
|
|
2
|
+
`,i+=source.charCodeAt(i+1)===10?2:1,chunk=i;else i++}return value+source.slice(chunk,to)}escape(pos){let code=this.source.charCodeAt(pos);switch(this.escapeEnd=pos+1,code){case 110:return`
|
|
3
|
+
`;case 114:return"\r";case 116:return"\t";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 48:return isDigit(this.source.charCodeAt(pos+1))?null:"\x00";case 120:return this.hexEscape(pos+1,2);case 117:return this.unicodeEscape(pos+1);case 13:if(this.source.charCodeAt(pos+1)===10)this.escapeEnd++;return"";case 10:case 8232:case 8233:return"";default:return isDigit(code)||pos>=this.source.length?null:String.fromCharCode(code)}}unicodeEscape(pos){if(this.source.charCodeAt(pos)!==123)return this.hexEscape(pos,4);let value=0,i=pos+1;for(;this.source.charCodeAt(i)!==125;i++){let digit=hexValue(this.source.charCodeAt(i));if(digit===-1)return null;if(value=value*16+digit,value>1114111)return null}if(i===pos+1)return null;return this.escapeEnd=i+1,String.fromCodePoint(value)}hexEscape(pos,length){let value=0;for(let i=pos;i<pos+length;i++){let digit=hexValue(this.source.charCodeAt(i));if(digit===-1)return null;value=value*16+digit}return this.escapeEnd=pos+length,String.fromCharCode(value)}}function isIdentifierStart(code){return code!==92&&isWordCode(code)&&!isDigit(code)}function hexValue(code){if(isDigit(code))return code-48;let lower=code|32;return lower>=97&&lower<=102?lower-87:-1}export{lexComponent2 as lexComponent,lexDynamicImports,lexImportsExports,lexStrings};
|
package/module.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./shared-
|
|
1
|
+
import"./shared-2pngd0mg.js";import"./shared-m0dcdh24.js";import{ParseError2}from"./shared-nan648gn.js";import"./shared-5tpb3h6x.js";import"./shared-e4gbs4rb.js";import{parseModuleWith}from"./shared-z9y4mrek.js";import{parseImportsExportsWith}from"./shared-tapcgcpr.js";import{typeScriptParser}from"./shared-h6z1kjbb.js";function createModuleParser(support={}){let typescript=typeScriptParser(support.typescript);return{parseModule:(source,options={})=>parseModuleWith(source,options,typescript),parseImportsExports:(source,options={})=>parseImportsExportsWith(source,options,typescript)}}export{ParseError2 as ParseError,createModuleParser};
|
package/package.json
CHANGED
package/parse-imports-exports.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./shared-
|
|
1
|
+
import"./shared-2pngd0mg.js";import"./shared-m0dcdh24.js";import"./shared-nan648gn.js";import"./shared-5tpb3h6x.js";import"./shared-e4gbs4rb.js";import"./shared-cs1ezg1f.js";import{TypeScriptParser}from"./shared-ke0fgd3r.js";import{parseImportsExportsWith}from"./shared-tapcgcpr.js";function parseImportsExports(source,options={}){return parseImportsExportsWith(source,options,TypeScriptParser)}export{parseImportsExports};
|
package/parse-module.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./shared-
|
|
1
|
+
import"./shared-2pngd0mg.js";import"./shared-m0dcdh24.js";import{ParseError2}from"./shared-nan648gn.js";import"./shared-cs1ezg1f.js";import{TypeScriptParser}from"./shared-ke0fgd3r.js";import{parseModuleWith}from"./shared-z9y4mrek.js";function parseModule(source,options={}){return parseModuleWith(source,options,TypeScriptParser)}export{ParseError2 as ParseError,parseModule};
|
package/parse-sections.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{parseSections2}from"./shared-as9z0pac.js";import"./shared-a23q4q40.js";import"./shared-drb44hb9.js";import"./shared-ke0fgd3r.js";import"./shared-cs1ezg1f.js";import"./shared-xwzsb4m8.js";import"./shared-bzqbnvee.js";import"./shared-dgdrqgdn.js";import"./shared-e4gbs4rb.js";import"./shared-5tpb3h6x.js";import"./shared-nan648gn.js";import"./shared-m0dcdh24.js";import"./shared-2pngd0mg.js";export{parseSections2 as parseSections};
|
package/parse.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{parse2}from"./shared-qkp49nav.js";import"./shared-drb44hb9.js";import"./shared-ke0fgd3r.js";import"./shared-cs1ezg1f.js";import"./shared-xwzsb4m8.js";import"./shared-bzqbnvee.js";import"./shared-dgdrqgdn.js";import"./shared-5tpb3h6x.js";import"./shared-nan648gn.js";import"./shared-m0dcdh24.js";import"./shared-2pngd0mg.js";export{parse2 as parse};
|
package/runes.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./shared-
|
|
1
|
+
import"./shared-dgdrqgdn.js";import{withoutByteOrderMark,isWhitespace,skipWhitespace}from"./shared-5tpb3h6x.js";import{isWordCode,closingBracket,wordCodesEnd}from"./shared-e4gbs4rb.js";import"./shared-m0dcdh24.js";import"./shared-2pngd0mg.js";import"./shared-nan648gn.js";import"./shared-bzqbnvee.js";import"./shared-xwzsb4m8.js";import"./shared-cs1ezg1f.js";import{parse2}from"./shared-qkp49nav.js";import{parseSections2}from"./shared-as9z0pac.js";import{extractIdentifiers2,isReference2,STOP2,SKIP2,walk2}from"./shared-jpvd0875.js";import{RUNES,RUNE_NAMES}from"./shared-m3dr31c3.js";import{lexComponent2}from"./shared-a23q4q40.js";import"./shared-drb44hb9.js";import"./shared-ke0fgd3r.js";var REGEX_CANDIDATE=/(?<![\w$])(?:\$(?:state|derived|props|bindable|effect|inspect|host)(?![\w$])|await(?![\w$]))|\\u/g,BOOLEAN_EXPRESSION=/^\{\s*(true|false)\s*\}$/;function isRunesMode(source){let lexed=lexComponent2(source),option=lexed.options?.attributes.find((attribute)=>attribute.name==="runes"),fromOption=option&&booleanValue(option);if(fromOption!==void 0)return fromOption;let text=withoutByteOrderMark(source),scripts=[lexed.instance,lexed.module].flatMap((script)=>script?[script.content]:[]),candidates=!1,inMarkup=!1,onlyAwait=!0;REGEX_CANDIDATE.lastIndex=0;for(let match=REGEX_CANDIDATE.exec(text);match!==null&&!(inMarkup&&!onlyAwait);match=REGEX_CANDIDATE.exec(text)){let at=match.index;candidates=!0,onlyAwait&&=match[0]==="await",inMarkup||=!scripts.some(({start,end})=>at>=start&&at<end)}if(!candidates)return!1;if(!onlyAwait&&option===void 0&&!text.includes("\\u")&&callsRune(text,scripts))return!0;let options={css:!1,comments:!1},ast=inMarkup?parse2(source,options):parseSections2(source,options);if(ast.options?.runes!==void 0)return ast.options.runes;if(onlyAwait)return ast.instance!==void 0&&awaitsOutsideFunctions(ast.instance.content)||awaitsOutsideFunctions(ast.fragment);return usesRunes(ast)}function awaitsOutsideFunctions(root){let awaits=!1;return walk2(root,{enter(node){if(isFunction(node))return SKIP2;if(node.type!=="AwaitExpression")return;return awaits=!0,STOP2}}),awaits}function booleanValue(attribute){if(attribute.value===!0)return!0;let match=BOOLEAN_EXPRESSION.exec(attribute.value);return match?match[1]==="true":void 0}var STORE_NAMES=new Map([...RUNE_NAMES].map((name)=>[name,new RegExp(`(?<![\\w$.])${name.slice(1)}(?![\\w$])`)])),DECLARING_WORDS=new Set("abstract accessor as async class const declare enum export extends function get implements import infer interface is keyof let module namespace new override private protected public readonly satisfies set static type typeof unique var".split(" "));function callsRune(source,scripts){let calls=new Map;for(let{start,end}of scripts){let script=source.slice(0,end);if(closingBracket(script,start,(wordStart,wordEnd)=>{if(script.charCodeAt(wordStart)!==36)return!1;let name=script.slice(wordStart,wordEnd);if(RUNE_NAMES.has(name)&&calls.get(name)!==!1)calls.set(name,isRuneCall(script,wordStart,wordEnd));return!1})!==script.length)return!1}for(let[name,call]of calls)if(call&&!STORE_NAMES.get(name)?.test(source))return!0;return!1}function isRuneCall(source,start,end){let before=start-1;while(before>=0&&isWhitespace(source.charCodeAt(before)))before--;let previous=source.charCodeAt(before);if(previous===35||previous===42||previous===46||previous===58||previous===60||previous===64)return!1;if(isWordCode(previous)){let wordStart=before;while(wordStart>0&&isWordCode(source.charCodeAt(wordStart-1)))wordStart--;if(DECLARING_WORDS.has(source.slice(wordStart,before+1)))return!1}let i=skipWhitespace(source,end);while(source.charCodeAt(i)===46){let wordStart=skipWhitespace(source,i+1),wordEnd=wordCodesEnd(source,wordStart);if(wordEnd===wordStart)return!1;i=skipWhitespace(source,wordEnd)}if(source.charCodeAt(i)===60){if(i=typeArgumentsEnd(source,i),i===-1)return!1;i=skipWhitespace(source,i)}if(source.charCodeAt(i)!==40)return!1;let close=closingBracket(source,i+1);if(source.charCodeAt(close)!==41)return!1;let next=source.charCodeAt(skipWhitespace(source,close+1));return next!==123&&next!==58}function typeArgumentsEnd(source,from){let depth=0,limit=Math.min(source.length,from+2000);for(let i=from;i<limit;i++){let code=source.charCodeAt(i);if(code===34||code===39||code===96||code===47)return-1;if(code===60)depth++;else if(code===62&&source.charCodeAt(i-1)!==61){if(depth--,depth===0)return i+1}}return-1}function usesRunes(ast){let module=ast.module?.content,instance=ast.instance?.content,declared=new Map;if(instance)declare(instance,declared,!0);let moduleDeclared=new Map;if(module)declare(module,moduleDeclared,!1);for(let[name,initial]of moduleDeclared)if(!declared.has(name))declared.set(name,initial);let referenced=[],reference=(name)=>{if(!referenced.includes(name))referenced.push(name)};if(module)collectReferences(module,moduleDeclared,reference);if(instance&&collectReferences(instance,declared,reference))return!0;if(collectReferences(ast.fragment,declared,reference))return!0;for(let name of referenced){let store=name.slice(1);if(!declared.has(store))return!0;let initial=declared.get(store)??null,rune=runeOf(initial,declared);if(!((rune===null||store!=="props"&&rune==="$props")&&!(name==="$derived"&&initial?.type==="ImportDeclaration"&&initial.source.value==="svelte/store")))return!0;declared.set(name,null)}return!1}function collectReferences(root,outer,reference){let ancestors=[],scopes=new Map,unresolved=(name)=>RUNE_NAMES.has(name)&&!outer.has(name)&&!ancestors.some((ancestor)=>declaredIn(ancestor,scopes).has(name)),functions=0,awaits=!1;return walk2(root,{enter(node,parent){if(isFunction(node))functions++;else if(node.type==="AwaitExpression")awaits||=functions===0;let name;if(node.type==="Identifier"&&parent&&!parent.type.startsWith("TS")&&isReference2(node,parent))name=node.name;else if(node.type==="TransitionDirective"||node.type==="AnimateDirective"||node.type==="UseDirective")name=node.name.split(".")[0];else if(node.type==="StyleDirective"&&node.value===!0)name=node.name;if(name!==void 0&&unresolved(name))reference(name);ancestors.push(node)},leave(node){if(ancestors.pop(),isFunction(node))functions--}}),awaits}var NO_NAMES=new Set;function declaredIn(node,scopes){let cached=scopes.get(node);if(cached)return cached;let patterns=[];if(isFunction(node)){if(patterns.push(...node.params),node.type==="FunctionExpression"&&node.id)patterns.push(node.id)}else if(node.type==="CatchClause"&&node.param)patterns.push(node.param);else if(node.type==="SnippetBlock")patterns.push(...node.parameters??[]);else if(node.type==="EachBlock"&&node.context)patterns.push(node.context);if(patterns.length===0&&!isFunction(node))return scopes.set(node,NO_NAMES),NO_NAMES;let names=new Set(patterns.flatMap((pattern)=>extractIdentifiers2(pattern)).map((id)=>id.name));if(isFunction(node)){let{body}=node;walk2(body,{enter(inner){if(inner===body)return;if(inner.type==="VariableDeclaration")for(let declarator of inner.declarations)for(let id of extractIdentifiers2(declarator.id))names.add(id.name);else if((inner.type==="FunctionDeclaration"||inner.type==="ClassDeclaration")&&inner.id)names.add(inner.id.name);return isFunction(inner)?SKIP2:void 0}})}return scopes.set(node,names),names}function isFunction(node){return node.type==="ArrowFunctionExpression"||node.type==="FunctionExpression"||node.type==="FunctionDeclaration"}function declare(program,into,instance){let implicit=[];walk2(program,{enter(node,parent){if(isFunction(node)&&node.type!=="FunctionDeclaration")return SKIP2;let topLevel=parent===program||parent?.type==="ExportNamedDeclaration"||parent?.type==="ExportDefaultDeclaration";if(node.type==="ImportDeclaration"){for(let specifier of node.specifiers)into.set(specifier.local.name,node);return SKIP2}if(node.type==="FunctionDeclaration"||node.type==="ClassDeclaration"){if(topLevel&&node.id)into.set(node.id.name,node);return SKIP2}if(node.type==="VariableDeclaration"){if(node.kind!=="var"&&!topLevel)return SKIP2;for(let declarator of node.declarations)for(let id of extractIdentifiers2(declarator.id))into.set(id.name,topLevel?declarator.init??null:null);return SKIP2}if(instance&&parent===program&&node.type==="LabeledStatement"&&node.label.name==="$"&&node.body.type==="ExpressionStatement"&&node.body.expression.type==="AssignmentExpression"){for(let id of extractIdentifiers2(node.body.expression.left))if(!id.name.startsWith("$"))implicit.push(id)}return}});for(let id of implicit)if(!into.has(id.name))into.set(id.name,null)}function runeOf(initial,declared){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"||declared.has(node.name))return null;return keypath=node.name+keypath,RUNES.has(keypath)?keypath:null}export{isRunesMode};
|
package/scope.d.ts
CHANGED
|
@@ -127,7 +127,9 @@ export interface Scopes {
|
|
|
127
127
|
/**
|
|
128
128
|
* The scope `node` is in: for a function, the scope around it, while
|
|
129
129
|
* its parameters are in its own. `null` for a node in a type, in the
|
|
130
|
-
* `<style>` or outside the AST.
|
|
130
|
+
* `<style>` or outside the AST. The first call walks the AST again to
|
|
131
|
+
* record every node's scope, which the rest of the analysis doesn't
|
|
132
|
+
* need.
|
|
131
133
|
*/
|
|
132
134
|
scopeOf(node: AST.SvelteNode): Scope | null;
|
|
133
135
|
/**
|