@backtickjs/compiler 0.1.9 → 0.1.11
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 +1 -1
- package/dist/compileScript.js +4 -2
- package/dist/compileScript.js.map +1 -1
- package/dist/emitScript.js +14 -5
- package/dist/emitScript.js.map +1 -1
- package/dist/inTypePosition.d.ts +1 -0
- package/dist/inTypePosition.js +14 -4
- package/dist/inTypePosition.js.map +1 -1
- package/dist/isClass.d.ts +2 -0
- package/dist/isClass.js +7 -0
- package/dist/isClass.js.map +1 -0
- package/dist/printVirtualCode.js +1 -1
- package/dist/printVirtualCode.js.map +1 -1
- package/dist/resolveBindings.d.ts +15 -6
- package/dist/resolveBindings.js +76 -32
- package/dist/resolveBindings.js.map +1 -1
- package/dist/rewriteFile.d.ts +1 -0
- package/dist/rewriteFile.js +2 -2
- package/dist/rewriteFile.js.map +1 -1
- package/dist/rewriteScript.d.ts +1 -1
- package/dist/rewriteScript.js +16 -8
- package/dist/rewriteScript.js.map +1 -1
- package/dist/virtualScript.d.ts +10 -3
- package/dist/virtualScript.js +11 -58
- package/dist/virtualScript.js.map +1 -1
- package/package.json +2 -2
- package/src/compileScript.ts +4 -2
- package/src/emitScript.ts +32 -6
- package/src/inTypePosition.ts +20 -6
- package/src/isClass.ts +11 -0
- package/src/printVirtualCode.ts +1 -1
- package/src/resolveBindings.ts +105 -40
- package/src/rewriteFile.ts +5 -3
- package/src/rewriteScript.ts +19 -9
- package/src/virtualScript.ts +12 -71
package/src/resolveBindings.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type ts from "typescript";
|
|
2
2
|
import { inTypePosition } from "./inTypePosition.js";
|
|
3
|
-
import type { ClientScript } from "./parseFile.js";
|
|
3
|
+
import type { ClientScript, ParsedFile } from "./parseFile.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Every client script in a file, its scopes resolved by TypeScript's checker,
|
|
7
7
|
* so any syntax TypeScript reads is resolved as the language does. It produces
|
|
8
|
-
*
|
|
8
|
+
* three things:
|
|
9
9
|
*
|
|
10
10
|
* - `bindings`: every *bound* variable identifier — a declaration, an arrow
|
|
11
11
|
* parameter, or a reference that resolves to one of those — mapped to a
|
|
@@ -31,10 +31,18 @@ import type { ClientScript } from "./parseFile.js";
|
|
|
31
31
|
* captured by something, somewhere: a binding no fragment ever wants is
|
|
32
32
|
* dead weight in every thunk written for that hole.
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* - `hostReferences`: every script identifier that resolves to a host
|
|
35
|
+
* binding — a name the host file declares in scope around the script,
|
|
36
|
+
* imports and all, and no script does. The client has no such binding, so
|
|
37
|
+
* the virtual code reports the read: it has to be spliced. A name that
|
|
38
|
+
* resolves to nothing is the client's global, read as written.
|
|
39
|
+
*
|
|
40
|
+
* The file is checked as one text: the host code as written, each script
|
|
41
|
+
* `(() => …)` where its template stands, a nested script where it stands in
|
|
42
|
+
* its splice's host expression, as it lands at runtime. A reference is free
|
|
36
43
|
* for the script it appears in exactly when the binding it resolves to was
|
|
37
|
-
* declared in an *enclosing* script (or in none at all)
|
|
44
|
+
* declared in an *enclosing* script (or in none at all); it is the host's when
|
|
45
|
+
* no script declares it.
|
|
38
46
|
*
|
|
39
47
|
* Uniqueness of keys has two axes. A per-file counter distinguishes bindings
|
|
40
48
|
* *within* a file; a hash of the file's text (see `hashText`) distinguishes
|
|
@@ -56,6 +64,8 @@ export type BindingResolution = Map<ts.Identifier, string>;
|
|
|
56
64
|
|
|
57
65
|
export interface ResolvedScopes {
|
|
58
66
|
bindings: BindingResolution;
|
|
67
|
+
// the scripts' identifiers that read a host binding
|
|
68
|
+
hostReferences: Set<ts.Identifier>;
|
|
59
69
|
// `params.get(script)[i]` is the script's parameter `i` (`$splice<i>`,
|
|
60
70
|
// `$capture<i>`): splices in the order the script first reads them, then
|
|
61
71
|
// captures
|
|
@@ -111,20 +121,25 @@ interface Combined {
|
|
|
111
121
|
|
|
112
122
|
export function resolveBindings(
|
|
113
123
|
ts: typeof import("typescript"),
|
|
114
|
-
scripts:
|
|
124
|
+
{ sourceFile, scripts }: ParsedFile,
|
|
115
125
|
fileHash: string,
|
|
116
126
|
): ResolvedScopes {
|
|
117
|
-
const combined = combine(ts, scripts);
|
|
127
|
+
const combined = combine(ts, sourceFile, scripts);
|
|
118
128
|
const file = ts.createSourceFile(
|
|
119
|
-
|
|
129
|
+
sourceFile.fileName,
|
|
120
130
|
combined.text,
|
|
121
131
|
ts.ScriptTarget.Latest,
|
|
122
132
|
true,
|
|
123
|
-
ts.ScriptKind.TSX,
|
|
124
133
|
);
|
|
125
134
|
const checker = checkerOf(ts, file);
|
|
126
135
|
const binding =
|
|
127
136
|
ts.SymbolFlags.Variable | ts.SymbolFlags.Function | ts.SymbolFlags.Class;
|
|
137
|
+
// what the host declares by a name: the above, an enum, a namespace, an import
|
|
138
|
+
const hostBinding =
|
|
139
|
+
binding |
|
|
140
|
+
ts.SymbolFlags.Enum |
|
|
141
|
+
ts.SymbolFlags.Module |
|
|
142
|
+
ts.SymbolFlags.Alias;
|
|
128
143
|
|
|
129
144
|
const scriptAt = (position: number): ClientScript | undefined =>
|
|
130
145
|
combined.pieces.find(
|
|
@@ -179,39 +194,56 @@ export function resolveBindings(
|
|
|
179
194
|
}
|
|
180
195
|
return key;
|
|
181
196
|
};
|
|
182
|
-
//
|
|
183
|
-
const
|
|
197
|
+
// What a name resolves to, and where it is declared.
|
|
198
|
+
const resolve = (
|
|
184
199
|
identifier: ts.Identifier,
|
|
185
|
-
): ts.Declaration | undefined => {
|
|
200
|
+
): { symbol: ts.Symbol; declaration: ts.Declaration } | undefined => {
|
|
186
201
|
const symbol =
|
|
187
202
|
ts.isShorthandPropertyAssignment(identifier.parent) &&
|
|
188
203
|
identifier.parent.name === identifier
|
|
189
204
|
? checker.getShorthandAssignmentValueSymbol(identifier.parent)
|
|
190
205
|
: checker.getSymbolAtLocation(identifier);
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
206
|
+
const declaration = symbol?.declarations?.find(
|
|
207
|
+
(declaration) => declaration.getSourceFile() === file,
|
|
208
|
+
);
|
|
209
|
+
return symbol !== undefined && declaration !== undefined
|
|
210
|
+
? { symbol, declaration }
|
|
195
211
|
: undefined;
|
|
196
212
|
};
|
|
197
213
|
|
|
198
214
|
// Every binding some nested script captures, whatever hole it was written at.
|
|
199
215
|
const escaped = new Set<string>();
|
|
216
|
+
const hostReferences = new Set<ts.Identifier>();
|
|
200
217
|
|
|
201
218
|
const visit = (node: ts.Node): void => {
|
|
202
219
|
// A type's names are never runtime bindings, but for a `typeof`, however
|
|
203
220
|
// deep in a type, and a class's `extends`, which read values.
|
|
204
221
|
if (ts.isIdentifier(node) && !inTypePosition(ts, node)) {
|
|
205
222
|
const script = scriptAt(node.getStart(file));
|
|
206
|
-
const declaration = declarationOf(node);
|
|
207
223
|
if (script === undefined) {
|
|
208
224
|
return;
|
|
209
225
|
}
|
|
210
|
-
|
|
226
|
+
const resolved = resolve(node);
|
|
227
|
+
if (resolved === undefined) {
|
|
211
228
|
return;
|
|
212
229
|
}
|
|
213
|
-
const
|
|
230
|
+
const { symbol, declaration } = resolved;
|
|
214
231
|
const identifier = identifierAt(node.getStart(file));
|
|
232
|
+
if (scriptAt(declaration.getStart(file)) === undefined) {
|
|
233
|
+
// The host's, unless a `declare global` declares it: that is a global.
|
|
234
|
+
if (
|
|
235
|
+
(symbol.flags & hostBinding) !== 0 &&
|
|
236
|
+
!inGlobalAugmentation(ts, declaration) &&
|
|
237
|
+
identifier !== undefined
|
|
238
|
+
) {
|
|
239
|
+
hostReferences.add(identifier);
|
|
240
|
+
}
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if ((symbol.flags & binding) === 0) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const key = keyOf(declaration);
|
|
215
247
|
if (identifier !== undefined) {
|
|
216
248
|
bindings.set(identifier, key);
|
|
217
249
|
}
|
|
@@ -277,13 +309,16 @@ export function resolveBindings(
|
|
|
277
309
|
params.set(script, [...splices, ...captures.values()]);
|
|
278
310
|
}
|
|
279
311
|
|
|
280
|
-
return { bindings, params };
|
|
312
|
+
return { bindings, hostReferences, params };
|
|
281
313
|
}
|
|
282
314
|
|
|
283
|
-
// The
|
|
284
|
-
// its
|
|
315
|
+
// The file as one text: the host code as written, each script `(() => text)`
|
|
316
|
+
// where its template stands, a braced splice's host expression where its
|
|
317
|
+
// placeholder stands, parenthesized, with the scripts nested in it written the
|
|
318
|
+
// same way.
|
|
285
319
|
function combine(
|
|
286
320
|
ts: typeof import("typescript"),
|
|
321
|
+
sourceFile: ts.SourceFile,
|
|
287
322
|
scripts: ClientScript[],
|
|
288
323
|
): Combined {
|
|
289
324
|
const combined: Combined = {
|
|
@@ -292,49 +327,64 @@ function combine(
|
|
|
292
327
|
parents: new Map(),
|
|
293
328
|
positions: new Map(),
|
|
294
329
|
};
|
|
330
|
+
// Host text up to an offset, from where the last host text ended.
|
|
331
|
+
let at = 0;
|
|
332
|
+
const host = (to: number): void => {
|
|
333
|
+
combined.text += sourceFile.text.slice(at, to);
|
|
334
|
+
at = to;
|
|
335
|
+
};
|
|
295
336
|
const emit = (script: ClientScript, parent?: ClientScript): void => {
|
|
296
337
|
combined.parents.set(script, parent);
|
|
297
338
|
const identifiers = identifiersOf(ts, script.fileWithPlaceholders);
|
|
298
|
-
const holes = [...identifiers.values()].filter(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
});
|
|
339
|
+
const holes = [...identifiers.values()].filter(
|
|
340
|
+
(identifier) => script.splices[identifier.text]?.kind === "braced",
|
|
341
|
+
);
|
|
302
342
|
combined.text += "(() => ";
|
|
303
|
-
let
|
|
343
|
+
let cursor = 0;
|
|
304
344
|
const copy = (to: number): void => {
|
|
305
345
|
const start = combined.text.length;
|
|
306
|
-
combined.pieces.push({
|
|
346
|
+
combined.pieces.push({
|
|
347
|
+
start,
|
|
348
|
+
length: to - cursor,
|
|
349
|
+
script,
|
|
350
|
+
from: cursor,
|
|
351
|
+
});
|
|
307
352
|
for (const [offset, identifier] of identifiers) {
|
|
308
|
-
if (offset >=
|
|
309
|
-
combined.positions.set(identifier, start + offset -
|
|
353
|
+
if (offset >= cursor && offset < to) {
|
|
354
|
+
combined.positions.set(identifier, start + offset - cursor);
|
|
310
355
|
}
|
|
311
356
|
}
|
|
312
|
-
combined.text += script.textWithPlaceholders.slice(
|
|
313
|
-
|
|
357
|
+
combined.text += script.textWithPlaceholders.slice(cursor, to);
|
|
358
|
+
cursor = to;
|
|
314
359
|
};
|
|
315
360
|
for (const hole of holes) {
|
|
316
361
|
copy(hole.getStart(script.fileWithPlaceholders));
|
|
317
362
|
combined.positions.set(hole, combined.text.length);
|
|
318
363
|
const splice = script.splices[hole.text]!;
|
|
319
|
-
combined.text += "
|
|
320
|
-
splice.
|
|
321
|
-
|
|
364
|
+
combined.text += "(";
|
|
365
|
+
at = splice.expression.getStart(sourceFile);
|
|
366
|
+
for (const nested of splice.scripts) {
|
|
367
|
+
host(nested.sourceNode.getStart(sourceFile));
|
|
322
368
|
emit(nested, script);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
369
|
+
at = nested.sourceNode.getEnd();
|
|
370
|
+
}
|
|
371
|
+
host(splice.expression.getEnd());
|
|
372
|
+
combined.text += ")";
|
|
373
|
+
cursor = hole.getEnd();
|
|
326
374
|
}
|
|
327
375
|
copy(script.textWithPlaceholders.length);
|
|
328
376
|
combined.text += ")";
|
|
329
377
|
};
|
|
330
378
|
for (const script of scripts) {
|
|
379
|
+
host(script.sourceNode.getStart(sourceFile));
|
|
331
380
|
emit(script);
|
|
332
|
-
|
|
381
|
+
at = script.sourceNode.getEnd();
|
|
333
382
|
}
|
|
383
|
+
host(sourceFile.text.length);
|
|
334
384
|
return combined;
|
|
335
385
|
}
|
|
336
386
|
|
|
337
|
-
// A checker over the one file: no libraries, as only the
|
|
387
|
+
// A checker over the one file: no libraries, as only the file's own
|
|
338
388
|
// bindings are asked about.
|
|
339
389
|
function checkerOf(
|
|
340
390
|
ts: typeof import("typescript"),
|
|
@@ -360,6 +410,21 @@ function checkerOf(
|
|
|
360
410
|
.getTypeChecker();
|
|
361
411
|
}
|
|
362
412
|
|
|
413
|
+
function inGlobalAugmentation(
|
|
414
|
+
ts: typeof import("typescript"),
|
|
415
|
+
declaration: ts.Declaration,
|
|
416
|
+
): boolean {
|
|
417
|
+
for (let node: ts.Node | undefined = declaration; node; node = node.parent) {
|
|
418
|
+
if (
|
|
419
|
+
ts.isModuleDeclaration(node) &&
|
|
420
|
+
(node.flags & ts.NodeFlags.GlobalAugmentation) !== 0
|
|
421
|
+
) {
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
|
|
363
428
|
// A script's own identifiers, by where they start in its placeholder text.
|
|
364
429
|
function identifiersOf(
|
|
365
430
|
ts: typeof import("typescript"),
|
package/src/rewriteFile.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface RewrittenFile {
|
|
|
12
12
|
scripts: Map<ts.TaggedTemplateExpression, RewrittenScript>;
|
|
13
13
|
// every script's own bindings, by identifier (see `resolveBindings`)
|
|
14
14
|
bindings: BindingResolution;
|
|
15
|
+
// the scripts' identifiers that read a host binding (see `resolveBindings`)
|
|
16
|
+
hostReferences: Set<ts.Identifier>;
|
|
15
17
|
diagnostics: Diagnostic[];
|
|
16
18
|
}
|
|
17
19
|
|
|
@@ -28,9 +30,9 @@ export function rewriteFile(
|
|
|
28
30
|
// to distinguish this file from a same-named file in another codebase.
|
|
29
31
|
const fileHash = hashText(sourceFile.text);
|
|
30
32
|
|
|
31
|
-
const { bindings, params } = resolveBindings(
|
|
33
|
+
const { bindings, hostReferences, params } = resolveBindings(
|
|
32
34
|
ts,
|
|
33
|
-
parsedFile
|
|
35
|
+
parsedFile,
|
|
34
36
|
fileHash,
|
|
35
37
|
);
|
|
36
38
|
|
|
@@ -48,5 +50,5 @@ export function rewriteFile(
|
|
|
48
50
|
|
|
49
51
|
diagnostics.push(...hostElementDiagnostics(ts, sourceFile));
|
|
50
52
|
|
|
51
|
-
return { sourceFile, scripts, bindings, diagnostics };
|
|
53
|
+
return { sourceFile, scripts, bindings, hostReferences, diagnostics };
|
|
52
54
|
}
|
package/src/rewriteScript.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
paramName,
|
|
8
8
|
scriptEdits,
|
|
9
9
|
} from "./emitScript.js";
|
|
10
|
+
import { isClass } from "./isClass.js";
|
|
10
11
|
import { isComponentTag } from "./isComponentTag.js";
|
|
11
12
|
import { call } from "./nodeFactory.js";
|
|
12
13
|
import type { ClientScript } from "./parseFile.js";
|
|
@@ -18,7 +19,7 @@ import { tagRoot } from "./tagRoot.js";
|
|
|
18
19
|
export interface RuntimeScript {
|
|
19
20
|
id: string;
|
|
20
21
|
// the module's `kind`
|
|
21
|
-
kind: "function" | "expression" | "block";
|
|
22
|
+
kind: "function" | "class" | "expression" | "block";
|
|
22
23
|
// the module's `params`, an array literal of literals
|
|
23
24
|
params: ts.Expression;
|
|
24
25
|
// the script's `args`, an array literal of host expressions
|
|
@@ -153,30 +154,39 @@ export function rewriteScript(
|
|
|
153
154
|
);
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
// A script is one expression or one block: statements go in
|
|
157
|
+
// A script is one expression, one class or one block: statements go in
|
|
158
|
+
// braces. A class is written as a declaration, `class Foo {}`.
|
|
157
159
|
const [statement] = fileWithPlaceholders.statements;
|
|
158
160
|
if (
|
|
159
161
|
fileWithPlaceholders.statements.length !== 1 ||
|
|
160
|
-
!(
|
|
162
|
+
!(
|
|
163
|
+
ts.isExpressionStatement(statement!) ||
|
|
164
|
+
ts.isBlock(statement!) ||
|
|
165
|
+
isClass(ts, statement!)
|
|
166
|
+
)
|
|
161
167
|
) {
|
|
162
168
|
return leftAsWritten([
|
|
163
169
|
{
|
|
164
170
|
range: scriptRange,
|
|
165
171
|
message:
|
|
166
|
-
"A `cs` client script is one expression or one block:
|
|
167
|
-
"statements in braces, e.g. cs`{ a(); b(); }`.",
|
|
172
|
+
"A `cs` client script is one expression, one class or one block: " +
|
|
173
|
+
"write statements in braces, e.g. cs`{ a(); b(); }`.",
|
|
168
174
|
category: ts.DiagnosticCategory.Error,
|
|
169
175
|
code: 0,
|
|
170
176
|
},
|
|
171
177
|
]);
|
|
172
178
|
}
|
|
173
179
|
|
|
180
|
+
const expression = ts.isExpressionStatement(statement!)
|
|
181
|
+
? skipParentheses(ts, statement.expression)
|
|
182
|
+
: undefined;
|
|
174
183
|
const kind = ts.isBlock(statement!)
|
|
175
184
|
? "block"
|
|
176
|
-
: ts.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
185
|
+
: expression === undefined || ts.isClassExpression(expression)
|
|
186
|
+
? "class"
|
|
187
|
+
: ts.isArrowFunction(expression) || ts.isFunctionExpression(expression)
|
|
188
|
+
? "function"
|
|
189
|
+
: "expression";
|
|
180
190
|
|
|
181
191
|
// A `${…}` written where the script has text rather than code is no splice.
|
|
182
192
|
const unspliced = unsplicedSpans(ts, clientScript);
|
package/src/virtualScript.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type ts from "typescript";
|
|
2
2
|
import type { CodeInformation } from "./CodeInformation.js";
|
|
3
3
|
import type { ClientScript, Splice } from "./parseFile.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { RewrittenFile } from "./rewriteFile.js";
|
|
5
5
|
import type { Segment } from "./segmentsToString.js";
|
|
6
6
|
import { inTypePosition } from "./inTypePosition.js";
|
|
7
7
|
import { tagRoot } from "./tagRoot.js";
|
|
@@ -26,7 +26,14 @@ const TAG_NAME: CodeInformation = {
|
|
|
26
26
|
*
|
|
27
27
|
* - its own binding, renamed (`x` to `__cs_x`), so it can't hide a host binding
|
|
28
28
|
* a splice names; a shorthand keeps its property name (`x: __cs_x`)
|
|
29
|
-
* - a
|
|
29
|
+
* - a host binding, renamed the same way, as a HACK: `__cs_x` is declared
|
|
30
|
+
* nowhere, so TypeScript reports "Cannot find name '__cs_x'" where it is
|
|
31
|
+
* read, which `unmangle` turns into "Cannot find name 'x'": true of the
|
|
32
|
+
* client, and the nearest TypeScript gets to "splice it". Nothing says that
|
|
33
|
+
* the name is right there in the host, or that `$x` is the fix.
|
|
34
|
+
* - a name nothing declares, the client's global: written as it is. A global
|
|
35
|
+
* declared with `const` or `let`, as React Native's `__DEV__` is, is no
|
|
36
|
+
* property of `typeof globalThis`, so only its bare name reads it.
|
|
30
37
|
* - a splice, as the host value the client is handed: `$x` as
|
|
31
38
|
* `cs.splice((x))`, `${…}` as `cs.splice(…)` around the host code
|
|
32
39
|
* - a splice written as a tag, `<$Card>`, as JSX on a name the host value is
|
|
@@ -40,7 +47,7 @@ const TAG_NAME: CodeInformation = {
|
|
|
40
47
|
export function virtualScript(
|
|
41
48
|
ts: typeof import("typescript"),
|
|
42
49
|
script: ClientScript,
|
|
43
|
-
bindings:
|
|
50
|
+
{ bindings, hostReferences }: RewrittenFile,
|
|
44
51
|
renderSplice: (splice: Splice) => Segment[],
|
|
45
52
|
): Segment[] {
|
|
46
53
|
const file = script.fileWithPlaceholders;
|
|
@@ -139,7 +146,8 @@ export function virtualScript(
|
|
|
139
146
|
parent.propertyName === undefined &&
|
|
140
147
|
parent.dotDotDotToken === undefined &&
|
|
141
148
|
ts.isObjectBindingPattern(parent.parent));
|
|
142
|
-
|
|
149
|
+
// A host reference is renamed like a binding on purpose: see the HACK above.
|
|
150
|
+
if (bindings.has(node) || hostReferences.has(node)) {
|
|
143
151
|
if (shorthand) {
|
|
144
152
|
mapped(node.text, node);
|
|
145
153
|
added(": ");
|
|
@@ -147,15 +155,6 @@ export function virtualScript(
|
|
|
147
155
|
mapped(mangle(node.text), node);
|
|
148
156
|
return;
|
|
149
157
|
}
|
|
150
|
-
if (node.text !== "undefined" && isReference(ts, node)) {
|
|
151
|
-
if (shorthand) {
|
|
152
|
-
mapped(node.text, node);
|
|
153
|
-
added(": ");
|
|
154
|
-
}
|
|
155
|
-
added("cs.globalThis.");
|
|
156
|
-
mapped(node.text, node);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
158
|
verbatim(node.getStart(file), node.getEnd());
|
|
160
159
|
};
|
|
161
160
|
|
|
@@ -265,61 +264,3 @@ export function virtualScript(
|
|
|
265
264
|
out.push([")())", undefined, closed, 1, WRAPPER]);
|
|
266
265
|
return out;
|
|
267
266
|
}
|
|
268
|
-
|
|
269
|
-
// Whether a name is read as a value where it stands, rather than naming a
|
|
270
|
-
// property, an attribute, a label or what a declaration declares.
|
|
271
|
-
function isReference(
|
|
272
|
-
ts: typeof import("typescript"),
|
|
273
|
-
node: ts.Identifier,
|
|
274
|
-
): boolean {
|
|
275
|
-
const parent = node.parent;
|
|
276
|
-
if (
|
|
277
|
-
(ts.isPropertyAccessExpression(parent) ||
|
|
278
|
-
ts.isPropertyAssignment(parent) ||
|
|
279
|
-
ts.isMethodDeclaration(parent) ||
|
|
280
|
-
ts.isPropertyDeclaration(parent) ||
|
|
281
|
-
ts.isGetAccessorDeclaration(parent) ||
|
|
282
|
-
ts.isSetAccessorDeclaration(parent) ||
|
|
283
|
-
ts.isPropertySignature(parent) ||
|
|
284
|
-
ts.isMethodSignature(parent) ||
|
|
285
|
-
ts.isEnumMember(parent) ||
|
|
286
|
-
ts.isJsxAttribute(parent) ||
|
|
287
|
-
ts.isVariableDeclaration(parent) ||
|
|
288
|
-
ts.isParameter(parent) ||
|
|
289
|
-
ts.isFunctionDeclaration(parent) ||
|
|
290
|
-
ts.isFunctionExpression(parent) ||
|
|
291
|
-
ts.isClassDeclaration(parent) ||
|
|
292
|
-
ts.isClassExpression(parent) ||
|
|
293
|
-
ts.isTypeAliasDeclaration(parent) ||
|
|
294
|
-
ts.isInterfaceDeclaration(parent) ||
|
|
295
|
-
ts.isEnumDeclaration(parent) ||
|
|
296
|
-
ts.isTypeParameterDeclaration(parent)) &&
|
|
297
|
-
parent.name === node
|
|
298
|
-
) {
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
if (ts.isBindingElement(parent)) {
|
|
302
|
-
return false; // its name declares, its property name names a property
|
|
303
|
-
}
|
|
304
|
-
if (
|
|
305
|
-
(ts.isLabeledStatement(parent) ||
|
|
306
|
-
ts.isBreakStatement(parent) ||
|
|
307
|
-
ts.isContinueStatement(parent)) &&
|
|
308
|
-
parent.label === node
|
|
309
|
-
) {
|
|
310
|
-
return false;
|
|
311
|
-
}
|
|
312
|
-
if (
|
|
313
|
-
(ts.isJsxOpeningElement(parent) ||
|
|
314
|
-
ts.isJsxSelfClosingElement(parent) ||
|
|
315
|
-
ts.isJsxClosingElement(parent)) &&
|
|
316
|
-
parent.tagName === node
|
|
317
|
-
) {
|
|
318
|
-
return false; // an intrinsic element's name, or a host tag's (above)
|
|
319
|
-
}
|
|
320
|
-
return !(
|
|
321
|
-
ts.isQualifiedName(parent) ||
|
|
322
|
-
ts.isMetaProperty(parent) ||
|
|
323
|
-
ts.isJsxNamespacedName(parent)
|
|
324
|
-
);
|
|
325
|
-
}
|