sveast 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -163
- package/core.d.ts +1 -1
- package/core.js +1 -1
- package/entities.js +1 -1
- package/index.d.ts +275 -2
- package/index.js +1 -1
- package/is-valid-type.js +1 -1
- package/lexer.d.ts +167 -0
- package/lexer.js +2 -0
- package/module.d.ts +1243 -0
- package/module.js +1 -0
- package/package.json +12 -2
- package/parse-imports-exports.js +1 -1
- package/parse-module.js +1 -1
- package/parse-sections.js +1 -0
- package/parse.js +1 -1
- package/runes.js +1 -0
- package/shared-23m65d6z.js +5 -0
- package/shared-2ahdjk78.js +2 -0
- package/shared-5ewsn6st.js +2 -0
- package/shared-657pk0sg.js +3 -0
- package/shared-918zqd7r.js +2 -0
- package/shared-a5mpxvcm.js +3 -0
- package/shared-d7yvtm6q.js +2 -0
- package/shared-e15f58b0.js +2 -0
- package/{shared-f8ty80r9.js → shared-e8rqjefv.js} +8 -8
- package/shared-j2msb2xj.js +9 -0
- package/shared-j3kp940c.js +2 -0
- package/shared-j60qxzy3.js +3 -0
- package/shared-p0ybqcs7.js +2 -0
- package/{shared-c4vs4cam.js → shared-qc7kjfqj.js} +2 -2
- package/shared-tscn5fn7.js +2 -0
- package/shared-xj75g925.js +2 -0
- package/shared-zn0h0cz3.js +2 -0
- package/typescript.js +1 -1
- package/walk.d.ts +80 -2
- package/walk.js +1 -1
- package/shared-0ehch67h.js +0 -2
- package/shared-3xek95jd.js +0 -12
- package/shared-88pt6me6.js +0 -2
- package/shared-9f69x2q9.js +0 -2
- package/shared-c1jf0gfc.js +0 -2
- package/shared-etx1q7m5.js +0 -3
- package/shared-nqsechtt.js +0 -2
- package/shared-rfyyd11j.js +0 -3
- package/shared-y4gayx8p.js +0 -2
package/index.d.ts
CHANGED
|
@@ -15,6 +15,174 @@ export declare function isValidType(text: string, options?: {
|
|
|
15
15
|
inline?: boolean;
|
|
16
16
|
}): boolean;
|
|
17
17
|
|
|
18
|
+
/** A module specifier: the string after `from`, or after `import` in `import "a"`. */
|
|
19
|
+
export interface LexedSource {
|
|
20
|
+
/** The string's value, with escapes decoded. */
|
|
21
|
+
value: string;
|
|
22
|
+
/** The offset of the opening quote. */
|
|
23
|
+
start: number;
|
|
24
|
+
/** The offset after the closing quote. */
|
|
25
|
+
end: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** A name an `import` binds. */
|
|
29
|
+
export interface LexedImportSpecifier {
|
|
30
|
+
/** `"default"` for `a` in `import a from`, `"namespace"` for `* as a`, `"named"` for a name in braces. */
|
|
31
|
+
kind: "default" | "namespace" | "named";
|
|
32
|
+
/** The name in the imported module: `"default"`, `"*"` for a namespace, or the name before `as`, with a string's value for `"a-b" as c`. */
|
|
33
|
+
imported: string;
|
|
34
|
+
/** The name it's bound to in this module. */
|
|
35
|
+
local: string;
|
|
36
|
+
/** Whether it's only a type: in `import type`, or with `type` before it. */
|
|
37
|
+
typeOnly: boolean;
|
|
38
|
+
/** The offset of the name, of `*`, or of `type` before the name. */
|
|
39
|
+
start: number;
|
|
40
|
+
/** The offset after the local name. */
|
|
41
|
+
end: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** A name an `export … from` re-exports. */
|
|
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`. */
|
|
49
|
+
local: string;
|
|
50
|
+
/** The name it's exported as, or `null` for `export *`. */
|
|
51
|
+
exported: string | null;
|
|
52
|
+
/** Whether it's only a type: in `export type`, or with `type` before it. */
|
|
53
|
+
typeOnly: boolean;
|
|
54
|
+
/** The offset of the name, of `*`, or of `type` before the name. */
|
|
55
|
+
start: number;
|
|
56
|
+
/** The offset after the exported name, or after `*` for `export *`. */
|
|
57
|
+
end: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface LexedStatementBase {
|
|
61
|
+
/** The offset of `import` or `export`. */
|
|
62
|
+
start: number;
|
|
63
|
+
/** The offset after the statement's `;`, or its last token without one. */
|
|
64
|
+
end: number;
|
|
65
|
+
/** The module it imports from, or `null` for a statement the lexer doesn't recognize. */
|
|
66
|
+
source: LexedSource | null;
|
|
67
|
+
/** Whether it's `import type` or `export type`. */
|
|
68
|
+
typeOnly: boolean;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** An `import` statement. */
|
|
72
|
+
export interface LexedImport extends LexedStatementBase {
|
|
73
|
+
kind: "import";
|
|
74
|
+
specifiers: LexedImportSpecifier[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** An `export … from` statement. */
|
|
78
|
+
export interface LexedExport extends LexedStatementBase {
|
|
79
|
+
kind: "export";
|
|
80
|
+
specifiers: LexedExportSpecifier[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type LexedStatement = LexedImport | LexedExport;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A module's top-level `import` statements and `export … from`
|
|
87
|
+
* re-exports, read without a parser: each statement's offsets, its
|
|
88
|
+
* source and the names it imports or re-exports. It finds statements as
|
|
89
|
+
* {@link parseImportsExports} does with `localExports: false`, and on
|
|
90
|
+
* every statement that accepts, gives the same offsets, sources and names,
|
|
91
|
+
* but it doesn't check syntax and never throws. A statement it can't read,
|
|
92
|
+
* including TypeScript's `import a = require("a")`, is returned with
|
|
93
|
+
* `source: null` and no specifiers, ending where it stopped reading.
|
|
94
|
+
* TypeScript's `type` forms are always read.
|
|
95
|
+
*/
|
|
96
|
+
export declare function lexImportsExports(source: string): LexedStatement[];
|
|
97
|
+
|
|
98
|
+
/** An attribute of a top-level `<script>`, `<style>` or `<svelte:options>`. */
|
|
99
|
+
export interface LexedAttribute {
|
|
100
|
+
name: string;
|
|
101
|
+
/**
|
|
102
|
+
* The value as written, without its quotes: character references
|
|
103
|
+
* aren't decoded, and an expression keeps its braces, as in `"{true}"`
|
|
104
|
+
* for `runes={true}`. `true` for an attribute without a value.
|
|
105
|
+
*/
|
|
106
|
+
value: string | true;
|
|
107
|
+
/** The offset of the name. */
|
|
108
|
+
start: number;
|
|
109
|
+
/** The offset after the value, or after the name without one. */
|
|
110
|
+
end: number;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The text between a top-level element's tags. */
|
|
114
|
+
export interface LexedContent {
|
|
115
|
+
start: number;
|
|
116
|
+
end: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** A top-level `<script>`. */
|
|
120
|
+
export interface LexedScript {
|
|
121
|
+
/** The offset of `<script`. */
|
|
122
|
+
start: number;
|
|
123
|
+
/** The offset after `</script>`. */
|
|
124
|
+
end: number;
|
|
125
|
+
/** `"module"` for `<script module>` or `<script context="module">`. */
|
|
126
|
+
context: "default" | "module";
|
|
127
|
+
attributes: LexedAttribute[];
|
|
128
|
+
content: LexedContent;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** The top-level `<style>`. */
|
|
132
|
+
export interface LexedStyle {
|
|
133
|
+
/** The offset of `<style`. */
|
|
134
|
+
start: number;
|
|
135
|
+
/** The offset after `</style>`. */
|
|
136
|
+
end: number;
|
|
137
|
+
attributes: LexedAttribute[];
|
|
138
|
+
content: LexedContent;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** `<svelte:options>`. */
|
|
142
|
+
export interface LexedOptions {
|
|
143
|
+
/** The offset of `<svelte:options`. */
|
|
144
|
+
start: number;
|
|
145
|
+
/** The offset after `/>` or `</svelte:options>`. */
|
|
146
|
+
end: number;
|
|
147
|
+
attributes: LexedAttribute[];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** A component's top-level sections, as {@link lexComponent} finds them. */
|
|
151
|
+
export interface LexedComponent {
|
|
152
|
+
/**
|
|
153
|
+
* Whether `parse` reads the component as TypeScript, which needs the
|
|
154
|
+
* TypeScript plugin: svelte decides it from the first `<script>` with a
|
|
155
|
+
* `lang`, so this is `true` when that one has `lang="ts"`.
|
|
156
|
+
*/
|
|
157
|
+
typescript: boolean;
|
|
158
|
+
/** The `<script>` without `module`, as `parse`'s `instance`. */
|
|
159
|
+
instance: LexedScript | null;
|
|
160
|
+
/** The `<script module>`, as `parse`'s `module`. */
|
|
161
|
+
module: LexedScript | null;
|
|
162
|
+
/** The `<style>`, as `parse`'s `css`. */
|
|
163
|
+
css: LexedStyle | null;
|
|
164
|
+
/** `<svelte:options>`, as `parse`'s `options`. */
|
|
165
|
+
options: LexedOptions | null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* A component's top-level `<script>`, `<script module>`, `<style>` and
|
|
170
|
+
* `<svelte:options>`, with their attributes and the offsets of their tags
|
|
171
|
+
* and content, read without a parser: e.g. to find a component's
|
|
172
|
+
* language or imports, or to rewrite its scripts, without parsing the
|
|
173
|
+
* markup. The offsets are `parse`'s, so they're into the source without
|
|
174
|
+
* a leading byte order mark.
|
|
175
|
+
*
|
|
176
|
+
* The markup is skipped by tracking only tags, attribute values, blocks
|
|
177
|
+
* and the brackets, strings, comments and templates of each `{…}`
|
|
178
|
+
* expression, so a `<script>` inside an element, a block, a string or a
|
|
179
|
+
* comment isn't one. It stops after the last `<script`, `<style` or
|
|
180
|
+
* `<svelte:options`. Where `parse` accepts the component, the sections
|
|
181
|
+
* are the same as its `instance`, `module`, `css` and `options`; it
|
|
182
|
+
* doesn't check syntax and never throws.
|
|
183
|
+
*/
|
|
184
|
+
export declare function lexComponent(input: string): LexedComponent;
|
|
185
|
+
|
|
18
186
|
/**
|
|
19
187
|
* Options for {@link parse}. The defaults give svelte's own output, minus
|
|
20
188
|
* `loc` and `name_loc`.
|
|
@@ -1776,6 +1944,56 @@ interface Location {
|
|
|
1776
1944
|
character: number;
|
|
1777
1945
|
}
|
|
1778
1946
|
|
|
1947
|
+
/**
|
|
1948
|
+
* A function from an offset in `text` to its line, from 1, and column,
|
|
1949
|
+
* from 0, in UTF-16 code units: what `loc: true` gives the node that
|
|
1950
|
+
* starts there, without parsing with `loc`. Lines end at `\n`, as in
|
|
1951
|
+
* svelte's markup `loc` and in `ParseError`; acorn's `loc` in
|
|
1952
|
+
* scripts and modules also ends them at a `\r` not followed by `\n`, at
|
|
1953
|
+
* U+2028 and at U+2029. `parse` drops a leading byte order mark, so pass
|
|
1954
|
+
* the text without it. Lines are found on the first call; lookups in
|
|
1955
|
+
* source order are fastest.
|
|
1956
|
+
*
|
|
1957
|
+
* ```ts
|
|
1958
|
+
* import { createLocator, parse, walk } from "sveast";
|
|
1959
|
+
*
|
|
1960
|
+
* const locate = createLocator(source);
|
|
1961
|
+
* walk(parse(source), {
|
|
1962
|
+
* enter(node) {
|
|
1963
|
+
* if (node.type === "Component") console.log(node.name, locate(node.start).line);
|
|
1964
|
+
* },
|
|
1965
|
+
* });
|
|
1966
|
+
* ```
|
|
1967
|
+
*/
|
|
1968
|
+
export declare function createLocator(text: string): (offset: number) => Position;
|
|
1969
|
+
|
|
1970
|
+
/**
|
|
1971
|
+
* Parses a component's top-level `<script>`s, `<style>` and
|
|
1972
|
+
* `<svelte:options>` as {@link parse} does, and skips the markup between
|
|
1973
|
+
* them as `lexComponent` skips it: `fragment` has no nodes, `comments`
|
|
1974
|
+
* only the scripts' comments, and errors in the markup aren't reported.
|
|
1975
|
+
* The rest is `parse`'s, offsets included. For a pass that only reads the
|
|
1976
|
+
* scripts, such as a component's props or its module script's exports.
|
|
1977
|
+
*
|
|
1978
|
+
* Throws a {@link ParseError} on a syntax error in a section.
|
|
1979
|
+
*/
|
|
1980
|
+
export declare function parseSections(source: string, options?: ParseOptions): AST.Root;
|
|
1981
|
+
|
|
1982
|
+
/**
|
|
1983
|
+
* Whether svelte compiles the component in runes mode, as
|
|
1984
|
+
* `compile(source).metadata.runes` says: `<svelte:options runes>` if it
|
|
1985
|
+
* has one, otherwise whether it uses a rune, such as `$state` or
|
|
1986
|
+
* `$props`, or `await` outside a function in its instance script or
|
|
1987
|
+
* markup. A `$state` that subscribes to a store named `state` isn't a
|
|
1988
|
+
* rune, as in svelte.
|
|
1989
|
+
*
|
|
1990
|
+
* It reads `<svelte:options>` without parsing, and a component that has
|
|
1991
|
+
* no rune's name and no `await` isn't parsed either. Otherwise it parses
|
|
1992
|
+
* the scripts, and the markup only if one of them is in it, and throws a
|
|
1993
|
+
* `ParseError` on a syntax error there.
|
|
1994
|
+
*/
|
|
1995
|
+
export declare function isRunesMode(source: string): boolean;
|
|
1996
|
+
|
|
1779
1997
|
/**
|
|
1780
1998
|
* The fields of each node type that hold child nodes, in source order.
|
|
1781
1999
|
* Typed against the AST, so a node type without an entry, or a key that
|
|
@@ -1982,6 +2200,58 @@ export declare const visitorKeys: {
|
|
|
1982
2200
|
readonly TSInstantiationExpression: readonly ["expression", "typeArguments"];
|
|
1983
2201
|
};
|
|
1984
2202
|
|
|
2203
|
+
/** A table of the fields of each node type that {@link walk} visits, such as {@link visitorKeys} or {@link markupVisitorKeys}. */
|
|
2204
|
+
export type VisitorKeys = Readonly<Partial<Record<string, readonly string[]>>>;
|
|
2205
|
+
|
|
2206
|
+
/**
|
|
2207
|
+
* The fields of the markup's nodes that hold other markup nodes, for a
|
|
2208
|
+
* {@link walk} that never enters the scripts, the styles or the
|
|
2209
|
+
* expressions: `Root` holds only its `fragment`, an `ExpressionTag` or a
|
|
2210
|
+
* directive has no children, and a block holds only its fragments.
|
|
2211
|
+
*/
|
|
2212
|
+
export declare const markupVisitorKeys: {
|
|
2213
|
+
readonly Root: readonly ["fragment"];
|
|
2214
|
+
readonly Fragment: readonly ["nodes"];
|
|
2215
|
+
readonly Text: readonly [];
|
|
2216
|
+
readonly Comment: readonly [];
|
|
2217
|
+
readonly ExpressionTag: readonly [];
|
|
2218
|
+
readonly HtmlTag: readonly [];
|
|
2219
|
+
readonly ConstTag: readonly [];
|
|
2220
|
+
readonly DeclarationTag: readonly [];
|
|
2221
|
+
readonly DebugTag: readonly [];
|
|
2222
|
+
readonly RenderTag: readonly [];
|
|
2223
|
+
readonly AttachTag: readonly [];
|
|
2224
|
+
readonly Attribute: readonly ["value"];
|
|
2225
|
+
readonly SpreadAttribute: readonly [];
|
|
2226
|
+
readonly AnimateDirective: readonly [];
|
|
2227
|
+
readonly BindDirective: readonly [];
|
|
2228
|
+
readonly ClassDirective: readonly [];
|
|
2229
|
+
readonly LetDirective: readonly [];
|
|
2230
|
+
readonly OnDirective: readonly [];
|
|
2231
|
+
readonly StyleDirective: readonly ["value"];
|
|
2232
|
+
readonly TransitionDirective: readonly [];
|
|
2233
|
+
readonly UseDirective: readonly [];
|
|
2234
|
+
readonly Component: readonly ["attributes", "fragment"];
|
|
2235
|
+
readonly TitleElement: readonly ["attributes", "fragment"];
|
|
2236
|
+
readonly SlotElement: readonly ["attributes", "fragment"];
|
|
2237
|
+
readonly RegularElement: readonly ["attributes", "fragment"];
|
|
2238
|
+
readonly SvelteBody: readonly ["attributes", "fragment"];
|
|
2239
|
+
readonly SvelteBoundary: readonly ["attributes", "fragment"];
|
|
2240
|
+
readonly SvelteComponent: readonly ["attributes", "fragment"];
|
|
2241
|
+
readonly SvelteDocument: readonly ["attributes", "fragment"];
|
|
2242
|
+
readonly SvelteElement: readonly ["attributes", "fragment"];
|
|
2243
|
+
readonly SvelteFragment: readonly ["attributes", "fragment"];
|
|
2244
|
+
readonly SvelteHead: readonly ["attributes", "fragment"];
|
|
2245
|
+
readonly SvelteOptions: readonly ["attributes", "fragment"];
|
|
2246
|
+
readonly SvelteSelf: readonly ["attributes", "fragment"];
|
|
2247
|
+
readonly SvelteWindow: readonly ["attributes", "fragment"];
|
|
2248
|
+
readonly IfBlock: readonly ["consequent", "alternate"];
|
|
2249
|
+
readonly EachBlock: readonly ["body", "fallback"];
|
|
2250
|
+
readonly AwaitBlock: readonly ["pending", "then", "catch"];
|
|
2251
|
+
readonly KeyBlock: readonly ["fragment"];
|
|
2252
|
+
readonly SnippetBlock: readonly ["body"];
|
|
2253
|
+
};
|
|
2254
|
+
|
|
1985
2255
|
/**
|
|
1986
2256
|
* Return it from `enter` or `leave` to end the walk: no further `enter` or
|
|
1987
2257
|
* `leave` calls, including `leave` on the node's ancestors.
|
|
@@ -2014,9 +2284,12 @@ export interface Visitor {
|
|
|
2014
2284
|
* Visits `node` and its descendants depth-first, in source order, calling
|
|
2015
2285
|
* `visitor.enter` before a node's children and `visitor.leave` after them.
|
|
2016
2286
|
* `parent[key]` is the node, or `parent[key][index]` when the field is an
|
|
2017
|
-
* array; all three are `null` for `node` itself.
|
|
2287
|
+
* array; all three are `null` for `node` itself. `keys` says which fields
|
|
2288
|
+
* of each node type to visit, {@link visitorKeys} by default; with
|
|
2289
|
+
* {@link markupVisitorKeys}, only the markup is visited. A node whose
|
|
2290
|
+
* type it has no entry for throws.
|
|
2018
2291
|
*/
|
|
2019
|
-
export declare function walk(node: AST.SvelteNode, visitor: Visitor): void;
|
|
2292
|
+
export declare function walk(node: AST.SvelteNode, visitor: Visitor, keys?: VisitorKeys): void;
|
|
2020
2293
|
|
|
2021
2294
|
/**
|
|
2022
2295
|
* The `Identifier` nodes a pattern binds, in source order: `a`, `c`, `d`,
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isValidType as t}from"./is-valid-type.js";import{
|
|
1
|
+
import{isValidType as t}from"./is-valid-type.js";import{lexComponent as p,lexImportsExports as s}from"./lexer.js";import{parse as i}from"./parse.js";import{parseImportsExports as f}from"./parse-imports-exports.js";import{ParseError as d,parseModule as n}from"./parse-module.js";import{parseSections as L}from"./parse-sections.js";import{isRunesMode as l}from"./runes.js";import{createLocator as I,extractIdentifiers as u,isReference as E,markupVisitorKeys as P,SKIP as O,STOP as K,visitorKeys as V,walk as k}from"./walk.js";export{d as ParseError,O as SKIP,K as STOP,I as createLocator,u as extractIdentifiers,E as isReference,l as isRunesMode,t as isValidType,p as lexComponent,s as lexImportsExports,P as markupVisitorKeys,i as parse,f as parseImportsExports,n as parseModule,L as parseSections,V as visitorKeys,k as walk};
|
package/is-valid-type.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t}from"./shared-
|
|
1
|
+
import{t}from"./shared-e8rqjefv.js";import{R}from"./shared-qc7kjfqj.js";var a=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(" ")),c=new Set("any bigint boolean false never null number object string symbol true undefined unknown void".split(" ")),d=new Set("get set new readonly static public private protected".split(" "));function u(e){return e>=97&&e<=122||e>=65&&e<=90||e===95||e===36}function o(e){return e>=48&&e<=57}function h(e){return u(e)||o(e)}class l{text;pos=0;constructor(e){this.text=e}readAll(){if(!this.type())return!1;return this.peek(),this.pos===this.text.length}peek(){let e=this.text,s=this.pos,r=e.charCodeAt(s);while(r===32||r===9)r=e.charCodeAt(++s);return this.pos=s,r}eat(e){if(this.peek()!==e.charCodeAt(0))return!1;return this.pos++,!0}word(){if(!u(this.peek()))return;let e=this.pos,s=e+1;while(h(this.text.charCodeAt(s)))s++;return this.pos=s,this.text.slice(e,s)}name(){let e=this.word();return e!==void 0&&!a.has(e)}string(){let e=this.peek();if(e!==34&&e!==39)return!1;let s=this.text;for(let r=this.pos+1;r<s.length;r++){let i=s.charCodeAt(r);if(i===e)return this.pos=r+1,!0;if(i===92||i===10||i===13||i===8232||i===8233)return!1}return!1}number(){let e=this.text,s=this.pos;if(e.charCodeAt(s)===45)s++;let r=s;while(o(e.charCodeAt(s)))s++;if(s===r||s-r>1&&e.charCodeAt(r)===48)return!1;if(e.charCodeAt(s)===46){let n=++s;while(o(e.charCodeAt(s)))s++;if(s===n)return!1}let i=e.charCodeAt(s);if(h(i)||i===46)return!1;return this.pos=s,!0}type(){if(this.peek()===40){let e=this.pos;if(this.functionType())return!0;this.pos=e}do do if(!this.operatorType())return!1;while(this.eat("&"));while(this.eat("|"));return!0}operatorType(){let e=this.pos;if(this.word()==="keyof")return this.operatorType();if(this.pos=e,!this.primaryType())return!1;while(this.eat("[")){if(this.eat("]"))continue;if(!this.type()||!this.eat("]"))return!1}return!0}primaryType(){let e=this.peek();if(e===40)return this.pos++,this.type()&&this.eat(")");if(e===123)return this.objectType();if(e===91)return this.tupleType();if(e===34||e===39)return this.string();if(e===45||o(e))return this.number();let s=this.word();if(s===void 0)return!1;if(s==="typeof")return this.typeQuery();if(s==="import")return this.importType(!0);if(c.has(s)){let r=this.peek();return r!==46&&r!==60}if(a.has(s))return!1;while(this.eat("."))if(this.word()===void 0)return!1;return!this.eat("<")||this.typeArguments()}typeArguments(){do if(!this.type())return!1;while(this.eat(","));return this.eat(">")}typeQuery(){let e=this.pos;if(this.word()==="import")return this.importType(!1);this.pos=e;do if(!this.name())return!1;while(this.eat("."));return!0}importType(e){if(!this.eat("(")||!this.string()||!this.eat(")"))return!1;while(this.eat("."))if(!this.name())return!1;return!e||!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 e=this.peek();if(this.eat("[")){let s=this.peek();if(s===34||s===39){if(!this.string()||!this.eat("]"))return!1}else return this.name()&&this.eat(":")&&this.type()&&this.eat("]")&&this.eat(":")&&this.type()}else if(e===34||e===39){if(!this.string())return!1}else{let s=this.word();if(s===void 0||d.has(s))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 e=new Set;for(;;){this.peek();let s=this.text.startsWith("...",this.pos);if(s)this.pos+=3;let r=this.word();if(r===void 0||a.has(r)||e.has(r))return!1;if(e.add(r),!s)this.eat("?");if(!this.eat(":")||!this.type())return!1;if(s||!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 f(e){return new l(e).readAll()}var y=t.extend(R);function C(e,s={}){return f(e)||m(e,s.inline??!1)}function m(e,s){let r=!1,i=new y(s?{ecmaVersion:16,sourceType:"module",onComment:(n,b,T,p)=>{if(!n&&p===e.length)r=!0}}:{ecmaVersion:16,sourceType:"module"},e);try{return i.parseWholeType(),!r}catch(n){if(n instanceof SyntaxError)return!1;throw n}}export{C as isValidType,m as parsesAsType};
|
package/lexer.d.ts
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/** A module specifier: the string after `from`, or after `import` in `import "a"`. */
|
|
2
|
+
export interface LexedSource {
|
|
3
|
+
/** The string's value, with escapes decoded. */
|
|
4
|
+
value: string;
|
|
5
|
+
/** The offset of the opening quote. */
|
|
6
|
+
start: number;
|
|
7
|
+
/** The offset after the closing quote. */
|
|
8
|
+
end: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** A name an `import` binds. */
|
|
12
|
+
export interface LexedImportSpecifier {
|
|
13
|
+
/** `"default"` for `a` in `import a from`, `"namespace"` for `* as a`, `"named"` for a name in braces. */
|
|
14
|
+
kind: "default" | "namespace" | "named";
|
|
15
|
+
/** The name in the imported module: `"default"`, `"*"` for a namespace, or the name before `as`, with a string's value for `"a-b" as c`. */
|
|
16
|
+
imported: string;
|
|
17
|
+
/** The name it's bound to in this module. */
|
|
18
|
+
local: string;
|
|
19
|
+
/** Whether it's only a type: in `import type`, or with `type` before it. */
|
|
20
|
+
typeOnly: boolean;
|
|
21
|
+
/** The offset of the name, of `*`, or of `type` before the name. */
|
|
22
|
+
start: number;
|
|
23
|
+
/** The offset after the local name. */
|
|
24
|
+
end: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** A name an `export … from` re-exports. */
|
|
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`. */
|
|
32
|
+
local: string;
|
|
33
|
+
/** The name it's exported as, or `null` for `export *`. */
|
|
34
|
+
exported: string | null;
|
|
35
|
+
/** Whether it's only a type: in `export type`, or with `type` before it. */
|
|
36
|
+
typeOnly: boolean;
|
|
37
|
+
/** The offset of the name, of `*`, or of `type` before the name. */
|
|
38
|
+
start: number;
|
|
39
|
+
/** The offset after the exported name, or after `*` for `export *`. */
|
|
40
|
+
end: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface LexedStatementBase {
|
|
44
|
+
/** The offset of `import` or `export`. */
|
|
45
|
+
start: number;
|
|
46
|
+
/** The offset after the statement's `;`, or its last token without one. */
|
|
47
|
+
end: number;
|
|
48
|
+
/** The module it imports from, or `null` for a statement the lexer doesn't recognize. */
|
|
49
|
+
source: LexedSource | null;
|
|
50
|
+
/** Whether it's `import type` or `export type`. */
|
|
51
|
+
typeOnly: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** An `import` statement. */
|
|
55
|
+
export interface LexedImport extends LexedStatementBase {
|
|
56
|
+
kind: "import";
|
|
57
|
+
specifiers: LexedImportSpecifier[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** An `export … from` statement. */
|
|
61
|
+
export interface LexedExport extends LexedStatementBase {
|
|
62
|
+
kind: "export";
|
|
63
|
+
specifiers: LexedExportSpecifier[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type LexedStatement = LexedImport | LexedExport;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A module's top-level `import` statements and `export … from`
|
|
70
|
+
* re-exports, read without a parser: each statement's offsets, its
|
|
71
|
+
* source and the names it imports or re-exports. It finds statements as
|
|
72
|
+
* {@link parseImportsExports} does with `localExports: false`, and on
|
|
73
|
+
* every statement that accepts, gives the same offsets, sources and names,
|
|
74
|
+
* but it doesn't check syntax and never throws. A statement it can't read,
|
|
75
|
+
* including TypeScript's `import a = require("a")`, is returned with
|
|
76
|
+
* `source: null` and no specifiers, ending where it stopped reading.
|
|
77
|
+
* TypeScript's `type` forms are always read.
|
|
78
|
+
*/
|
|
79
|
+
export declare function lexImportsExports(source: string): LexedStatement[];
|
|
80
|
+
|
|
81
|
+
/** An attribute of a top-level `<script>`, `<style>` or `<svelte:options>`. */
|
|
82
|
+
export interface LexedAttribute {
|
|
83
|
+
name: string;
|
|
84
|
+
/**
|
|
85
|
+
* The value as written, without its quotes: character references
|
|
86
|
+
* aren't decoded, and an expression keeps its braces, as in `"{true}"`
|
|
87
|
+
* for `runes={true}`. `true` for an attribute without a value.
|
|
88
|
+
*/
|
|
89
|
+
value: string | true;
|
|
90
|
+
/** The offset of the name. */
|
|
91
|
+
start: number;
|
|
92
|
+
/** The offset after the value, or after the name without one. */
|
|
93
|
+
end: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** The text between a top-level element's tags. */
|
|
97
|
+
export interface LexedContent {
|
|
98
|
+
start: number;
|
|
99
|
+
end: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** A top-level `<script>`. */
|
|
103
|
+
export interface LexedScript {
|
|
104
|
+
/** The offset of `<script`. */
|
|
105
|
+
start: number;
|
|
106
|
+
/** The offset after `</script>`. */
|
|
107
|
+
end: number;
|
|
108
|
+
/** `"module"` for `<script module>` or `<script context="module">`. */
|
|
109
|
+
context: "default" | "module";
|
|
110
|
+
attributes: LexedAttribute[];
|
|
111
|
+
content: LexedContent;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** The top-level `<style>`. */
|
|
115
|
+
export interface LexedStyle {
|
|
116
|
+
/** The offset of `<style`. */
|
|
117
|
+
start: number;
|
|
118
|
+
/** The offset after `</style>`. */
|
|
119
|
+
end: number;
|
|
120
|
+
attributes: LexedAttribute[];
|
|
121
|
+
content: LexedContent;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** `<svelte:options>`. */
|
|
125
|
+
export interface LexedOptions {
|
|
126
|
+
/** The offset of `<svelte:options`. */
|
|
127
|
+
start: number;
|
|
128
|
+
/** The offset after `/>` or `</svelte:options>`. */
|
|
129
|
+
end: number;
|
|
130
|
+
attributes: LexedAttribute[];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** A component's top-level sections, as {@link lexComponent} finds them. */
|
|
134
|
+
export interface LexedComponent {
|
|
135
|
+
/**
|
|
136
|
+
* Whether `parse` reads the component as TypeScript, which needs the
|
|
137
|
+
* TypeScript plugin: svelte decides it from the first `<script>` with a
|
|
138
|
+
* `lang`, so this is `true` when that one has `lang="ts"`.
|
|
139
|
+
*/
|
|
140
|
+
typescript: boolean;
|
|
141
|
+
/** The `<script>` without `module`, as `parse`'s `instance`. */
|
|
142
|
+
instance: LexedScript | null;
|
|
143
|
+
/** The `<script module>`, as `parse`'s `module`. */
|
|
144
|
+
module: LexedScript | null;
|
|
145
|
+
/** The `<style>`, as `parse`'s `css`. */
|
|
146
|
+
css: LexedStyle | null;
|
|
147
|
+
/** `<svelte:options>`, as `parse`'s `options`. */
|
|
148
|
+
options: LexedOptions | null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* A component's top-level `<script>`, `<script module>`, `<style>` and
|
|
153
|
+
* `<svelte:options>`, with their attributes and the offsets of their tags
|
|
154
|
+
* and content, read without a parser: e.g. to find a component's
|
|
155
|
+
* language or imports, or to rewrite its scripts, without parsing the
|
|
156
|
+
* markup. The offsets are `parse`'s, so they're into the source without
|
|
157
|
+
* a leading byte order mark.
|
|
158
|
+
*
|
|
159
|
+
* The markup is skipped by tracking only tags, attribute values, blocks
|
|
160
|
+
* and the brackets, strings, comments and templates of each `{…}`
|
|
161
|
+
* expression, so a `<script>` inside an element, a block, a string or a
|
|
162
|
+
* comment isn't one. It stops after the last `<script`, `<style` or
|
|
163
|
+
* `<svelte:options`. Where `parse` accepts the component, the sections
|
|
164
|
+
* are the same as its `instance`, `module`, `css` and `options`; it
|
|
165
|
+
* doesn't check syntax and never throws.
|
|
166
|
+
*/
|
|
167
|
+
export declare function lexComponent(input: string): LexedComponent;
|
package/lexer.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r,M,h,d,N}from"./shared-j60qxzy3.js";import"./shared-2ahdjk78.js";import{G}from"./shared-a5mpxvcm.js";function g(e){let t=new m(e),n=[];return M(e,!1,(i,s)=>{let o=t.statement(s);return n.push(o),o.end}),n}class m{source;pos=0;end=0;escapeEnd=0;constructor(e){this.source=e}statement(e){this.pos=this.end=e+6;let t=this.source.charCodeAt(e)===105?{kind:"import",start:e,end:0,source:null,typeOnly:!1,specifiers:[]}:{kind:"export",start:e,end:0,source:null,typeOnly:!1,specifiers:[]};if(!(t.kind==="import"?this.import(t):this.export(t)))t.source=null,t.specifiers=[];return t.end=this.end,t}import(e){let t=this.string();if(t!==null)return e.source=t,this.finish();if(this.isWord("type")){let o=this.peek(4);if(o===123||o===42||c(o)&&!this.isWordAfter(4,"from"))e.typeOnly=!0,this.advance(4)}let{specifiers:n,typeOnly:i}=e,s=this.at();if(s!==123&&s!==42){let o=this.pos,a=this.name();if(a===null)return!1;if(this.at()===61)return this.importEquals();if(n.push({kind:"default",imported:"default",local:a,typeOnly:i,start:o,end:this.end}),!this.eat(44))return this.from(e);s=this.at()}if(s===42){let o=this.pos;if(this.advance(1),!this.eatWord("as"))return!1;let a=this.name();if(a===null)return!1;return n.push({kind:"namespace",imported:"*",local:a,typeOnly:i,start:o,end:this.end}),this.from(e)}if(!this.eat(123))return!1;while(!this.eat(125)){let o=this.skip(),a=this.typeModifier()||i,u=this.name(),f=u??this.string()?.value;if(f===void 0)return!1;let l=u;if(this.eatWord("as"))l=this.name();if(l===null)return!1;if(n.push({kind:"named",imported:f,local:l,typeOnly:a,start:o,end:this.end}),!this.eat(44)&&this.at()!==125)return!1}return this.from(e)}export(e){if(this.eatWord("import")){if(this.isWord("type")&&c(this.peek(4))&&!this.isWordAfter(4,"from"))e.typeOnly=!0,this.advance(4);return this.name()!==null&&this.at()===61&&this.importEquals()}if(this.isWord("type")){let i=this.peek(4);if(i===123||i===42)e.typeOnly=!0,this.advance(4)}let{specifiers:t,typeOnly:n}=e;if(this.at()===42){let i=this.pos;this.advance(1);let s=null;if(this.eatWord("as")){if(s=this.moduleExportName(),s===null)return!1}return t.push({kind:s===null?"all":"namespace",local:"*",exported:s,typeOnly:n,start:i,end:this.end}),this.from(e)}if(!this.eat(123))return!1;while(!this.eat(125)){let i=this.skip(),s=this.typeModifier()||n,o=this.moduleExportName();if(o===null)return!1;let a=o;if(this.eatWord("as"))a=this.moduleExportName();if(a===null)return!1;if(t.push({kind:"named",local:o,exported:a,typeOnly:s,start:i,end:this.end}),!this.eat(44)&&this.at()!==125)return!1}return this.from(e)}typeModifier(){if(!this.isWord("type"))return!1;let e=this.peek(4);if(e===34||e===39||c(e)&&!this.isWordAfter(4,"as"))return this.advance(4),!0;return!1}importEquals(){if(this.advance(1),this.isWord("require")&&this.peek(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(e){if(!this.eatWord("from"))return!1;return e.source=this.string(),e.source!==null&&this.finish()}finish(){let e=this.isWord("with")?4:0;if(this.isWord("assert")&&!x(this.source,this.end,this.pos))e=6;if(e!==0&&this.peek(e)===123){this.advance(e),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=d(this.source,this.pos),this.pos}at(){return this.source.charCodeAt(this.skip())}advance(e){this.pos+=e,this.end=this.pos}peek(e){return this.source.charCodeAt(d(this.source,this.pos+e))}isWordAfter(e,t){return N(this.source,d(this.source,this.pos+e),t)}eat(e){if(this.at()!==e)return!1;return this.advance(1),!0}isWord(e){return N(this.source,this.skip(),e)}eatWord(e){if(!this.isWord(e))return!1;return this.advance(e.length),!0}moduleExportName(){return this.name()??this.string()?.value??null}name(){let e=this.source,t=this.skip();if(!r(e.charCodeAt(t))||h(e.charCodeAt(t)))return null;let n="",i=t,s=t;while(s<e.length){let o=e.charCodeAt(s);if(o===92){if(e.charCodeAt(s+1)!==117)return null;let a=this.unicodeEscape(s+2);if(a===null)return null;n+=e.slice(i,s)+a,s=i=this.escapeEnd}else if(r(o))s++;else break}return this.advance(s-t),n+e.slice(i,s)}string(){let e=this.source,t=this.skip(),n=e.charCodeAt(t);if(n!==34&&n!==39)return null;let i="",s=t+1;for(let o=s;o<e.length;){let a=e.charCodeAt(o);if(a===n)return this.advance(o+1-t),{value:i+e.slice(s,o),start:t,end:o+1};if(a===10||a===13)return null;if(a===92){let u=this.escape(o+1);if(u===null)return null;i+=e.slice(s,o)+u,o=s=this.escapeEnd}else o++}return null}escape(e){let t=this.source.charCodeAt(e);switch(this.escapeEnd=e+1,t){case 110:return`
|
|
2
|
+
`;case 114:return"\r";case 116:return"\t";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 48:return h(this.source.charCodeAt(e+1))?null:"\x00";case 120:return this.hexEscape(e+1,2);case 117:return this.unicodeEscape(e+1);case 13:if(this.source.charCodeAt(e+1)===10)this.escapeEnd++;return"";case 10:case 8232:case 8233:return"";default:return h(t)||e>=this.source.length?null:String.fromCharCode(t)}}unicodeEscape(e){if(this.source.charCodeAt(e)!==123)return this.hexEscape(e,4);let t=0,n=e+1;for(;this.source.charCodeAt(n)!==125;n++){let i=p(this.source.charCodeAt(n));if(i===-1)return null;if(t=t*16+i,t>1114111)return null}if(n===e+1)return null;return this.escapeEnd=n+1,String.fromCodePoint(t)}hexEscape(e,t){let n=0;for(let i=e;i<e+t;i++){let s=p(this.source.charCodeAt(i));if(s===-1)return null;n=n*16+s}return this.escapeEnd=e+t,String.fromCharCode(n)}}function c(e){return e!==92&&r(e)&&!h(e)}function p(e){if(h(e))return e-48;let t=e|32;return t>=97&&t<=102?t-87:-1}function x(e,t,n){for(let i=t;i<n;i++){let s=e.charCodeAt(i);if(s===10||s===13||s===8232||s===8233)return!0}return!1}export{G as lexComponent,g as lexImportsExports};
|