@velarscript/compiler 0.12.0 → 0.13.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/dist/advisory-suppression.d.ts +62 -0
- package/dist/advisory-suppression.d.ts.map +1 -0
- package/dist/advisory-suppression.js +179 -0
- package/dist/advisory-suppression.js.map +1 -0
- package/dist/analyzer.d.ts +405 -17
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +1755 -211
- package/dist/analyzer.js.map +1 -1
- package/dist/ast.d.ts +6 -3
- package/dist/ast.d.ts.map +1 -1
- package/dist/ast.js.map +1 -1
- package/dist/binding-stability.d.ts +22 -0
- package/dist/binding-stability.d.ts.map +1 -0
- package/dist/binding-stability.js +63 -0
- package/dist/binding-stability.js.map +1 -0
- package/dist/collection-lowering-runtime.d.ts +1 -1
- package/dist/collection-lowering-runtime.d.ts.map +1 -1
- package/dist/collection-lowering-runtime.js +183 -56
- package/dist/collection-lowering-runtime.js.map +1 -1
- package/dist/diagnostic.d.ts +34 -0
- package/dist/diagnostic.d.ts.map +1 -1
- package/dist/diagnostic.js +11 -1
- package/dist/diagnostic.js.map +1 -1
- package/dist/embedded-javascript.d.ts +12 -1
- package/dist/embedded-javascript.d.ts.map +1 -1
- package/dist/embedded-javascript.js +111 -2
- package/dist/embedded-javascript.js.map +1 -1
- package/dist/embedded-module.d.ts.map +1 -1
- package/dist/embedded-module.js +22 -0
- package/dist/embedded-module.js.map +1 -1
- package/dist/emitter.d.ts +83 -1
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +518 -41
- package/dist/emitter.js.map +1 -1
- package/dist/error-runtime.d.ts +9 -0
- package/dist/error-runtime.d.ts.map +1 -1
- package/dist/error-runtime.js +21 -0
- package/dist/error-runtime.js.map +1 -1
- package/dist/extension.d.ts +5 -2
- package/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +2 -1
- package/dist/extension.js.map +1 -1
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +222 -91
- package/dist/formatter.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -5
- package/dist/index.js.map +1 -1
- package/dist/interpolated-string.d.ts.map +1 -1
- package/dist/interpolated-string.js +29 -2
- package/dist/interpolated-string.js.map +1 -1
- package/dist/json-runtime.d.ts.map +1 -1
- package/dist/json-runtime.js +27 -3
- package/dist/json-runtime.js.map +1 -1
- package/dist/lexer.d.ts +217 -1
- package/dist/lexer.d.ts.map +1 -1
- package/dist/lexer.js +799 -37
- package/dist/lexer.js.map +1 -1
- package/dist/limits.d.ts +9 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +9 -0
- package/dist/limits.js.map +1 -1
- package/dist/mechanical-fix.d.ts.map +1 -1
- package/dist/mechanical-fix.js +38 -0
- package/dist/mechanical-fix.js.map +1 -1
- package/dist/parser.d.ts +30 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +137 -21
- package/dist/parser.js.map +1 -1
- package/dist/promise-runtime.d.ts +20 -1
- package/dist/promise-runtime.d.ts.map +1 -1
- package/dist/promise-runtime.js +38 -3
- package/dist/promise-runtime.js.map +1 -1
- package/dist/reactive-bridge-runtime.d.ts.map +1 -1
- package/dist/reactive-bridge-runtime.js +7 -1
- package/dist/reactive-bridge-runtime.js.map +1 -1
- package/dist/runtime-abi.d.ts +21 -1
- package/dist/runtime-abi.d.ts.map +1 -1
- package/dist/runtime-abi.js +23 -3
- package/dist/runtime-abi.js.map +1 -1
- package/dist/source-names.d.ts +26 -0
- package/dist/source-names.d.ts.map +1 -1
- package/dist/source-names.js +49 -5
- package/dist/source-names.js.map +1 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +13 -0
- package/dist/source.js.map +1 -1
- package/dist/stable-order.d.ts +16 -0
- package/dist/stable-order.d.ts.map +1 -0
- package/dist/stable-order.js +18 -0
- package/dist/stable-order.js.map +1 -0
- package/dist/text-runtime.d.ts.map +1 -1
- package/dist/text-runtime.js +182 -41
- package/dist/text-runtime.js.map +1 -1
- package/dist/token.d.ts +11 -0
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js.map +1 -1
- package/dist/type-registry-runtime.d.ts.map +1 -1
- package/dist/type-registry-runtime.js +8 -1
- package/dist/type-registry-runtime.js.map +1 -1
- package/dist/type-validation-runtime.d.ts.map +1 -1
- package/dist/type-validation-runtime.js +129 -1
- package/dist/type-validation-runtime.js.map +1 -1
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +161 -17
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/dist/analyzer.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Expression, FunctionDeclaration, Program, Statement, TypeParameterDeclaration, TypeReference, TypeSyntax } from "./ast.ts";
|
|
2
2
|
import { type PermanentNamespaceName } from "./core-vocabulary.ts";
|
|
3
|
-
import { type Diagnostic, type DiagnosticFix } from "./diagnostic.ts";
|
|
3
|
+
import { type Advisory, type Diagnostic, type DiagnosticFix } from "./diagnostic.ts";
|
|
4
4
|
import type { CompilerAnalysisExtension } from "./extension.ts";
|
|
5
5
|
import { type Span } from "./source.ts";
|
|
6
6
|
import { type EnumInfo, type BinaryStorageKind, type ExtensionValueType, type GenericTypeInfo, type TypeEnvironment, type TypeParameterBound, type ValueType } from "./types.ts";
|
|
@@ -12,6 +12,12 @@ interface Binding {
|
|
|
12
12
|
readonly storageBinding?: Binding;
|
|
13
13
|
readonly span: Span;
|
|
14
14
|
narrowingFrame: number | null;
|
|
15
|
+
/**
|
|
16
|
+
* The scope depth this binding was created at. A flow snapshot only visits
|
|
17
|
+
* bindings whose facts have actually moved, and this is how the set of those
|
|
18
|
+
* is emptied again when the scope holding them exits.
|
|
19
|
+
*/
|
|
20
|
+
readonly flowScope?: number;
|
|
15
21
|
/**
|
|
16
22
|
* D44 rule 71: true while the active narrowing was established by an
|
|
17
23
|
* assignment (or a declaration initializer) rather than a check. Only
|
|
@@ -42,6 +48,8 @@ interface AnalyzableFunctionDeclaration {
|
|
|
42
48
|
readonly body: FunctionDeclaration["body"];
|
|
43
49
|
readonly span: Span;
|
|
44
50
|
readonly asynchronous?: boolean;
|
|
51
|
+
readonly exported?: boolean;
|
|
52
|
+
readonly private?: boolean;
|
|
45
53
|
}
|
|
46
54
|
export interface ClassField {
|
|
47
55
|
readonly mutable: boolean;
|
|
@@ -58,6 +66,14 @@ export interface ClassInfo {
|
|
|
58
66
|
* than composes.
|
|
59
67
|
*/
|
|
60
68
|
readonly iterate?: ValueType;
|
|
69
|
+
/**
|
|
70
|
+
* D90 R18: the element the class's asynchronous `@iterate:` form answers
|
|
71
|
+
* with. The block is the declared spelling of the pull contract `async for`
|
|
72
|
+
* consumes — pulled once per element, it may await, it answers `T?`, and
|
|
73
|
+
* null is exhaustion. A class declares one form or the other; the answer's
|
|
74
|
+
* shape (a collection against `T?`) is what tells them apart.
|
|
75
|
+
*/
|
|
76
|
+
readonly iterateAsync?: ValueType;
|
|
61
77
|
readonly parameters: readonly ValueType[];
|
|
62
78
|
readonly parameterNames?: readonly string[];
|
|
63
79
|
readonly requiredParameters: number;
|
|
@@ -206,6 +222,18 @@ export interface LoweringHints {
|
|
|
206
222
|
* returns and every consumer keeps the lowering it already had.
|
|
207
223
|
*/
|
|
208
224
|
readonly iterationContracts: ReadonlySet<string>;
|
|
225
|
+
/**
|
|
226
|
+
* D90 R18: start offsets of `async for` statements whose source's class
|
|
227
|
+
* declares the asynchronous `@iterate:` form. The emitter pulls these
|
|
228
|
+
* through the declared member instead of capturing a structural `next`.
|
|
229
|
+
*/
|
|
230
|
+
readonly asyncIterationStatements: ReadonlySet<number>;
|
|
231
|
+
/**
|
|
232
|
+
* D90 R18: span identities of the `@iterate:` blocks that are the
|
|
233
|
+
* asynchronous pull form, keyed by their keyword span, so the emitter lands
|
|
234
|
+
* each one as an async method under its own key.
|
|
235
|
+
*/
|
|
236
|
+
readonly asyncIterateBlocks: ReadonlySet<string>;
|
|
209
237
|
/**
|
|
210
238
|
* Span identities of JavaScript-boundary calls in synchronous
|
|
211
239
|
* module-initialization position. A non-Error value thrown there would
|
|
@@ -275,6 +303,14 @@ export declare const disposeMemberKey = "__velar:dispose";
|
|
|
275
303
|
* member can answer it by accident and no author call can reach it.
|
|
276
304
|
*/
|
|
277
305
|
export declare const iterateMemberKey = "__velar:iterate";
|
|
306
|
+
/**
|
|
307
|
+
* The emitted member behind the asynchronous `@iterate:` form (D90 R18). It is
|
|
308
|
+
* a separate key because the two forms answer different questions — the
|
|
309
|
+
* synchronous member returns the finished collection once, this one is an
|
|
310
|
+
* async method `async for` pulls once per element — so no lowering can confuse
|
|
311
|
+
* one for the other.
|
|
312
|
+
*/
|
|
313
|
+
export declare const iterateAsyncMemberKey = "__velar:iterateAsync";
|
|
278
314
|
/** How a `using` binding releases its value at scope exit. */
|
|
279
315
|
export interface DisposalContract {
|
|
280
316
|
readonly member: string;
|
|
@@ -293,8 +329,22 @@ export declare function permanentNamespaceCoveringModule(source: string, exports
|
|
|
293
329
|
export declare function isCorePrimitiveName(name: string): boolean;
|
|
294
330
|
export declare class Analyzer implements TypeEnvironment {
|
|
295
331
|
protected readonly diagnostics: Diagnostic[];
|
|
332
|
+
protected readonly advisories: Advisory[];
|
|
333
|
+
private readonly advisedIdentities;
|
|
296
334
|
private readonly scopes;
|
|
297
335
|
private readonly memberNarrowings;
|
|
336
|
+
/** Per scope depth, the names a narrowing has written there; see `narrowingsForVisibleBindings`. */
|
|
337
|
+
private readonly narrowedNames;
|
|
338
|
+
/** How many loop back-edge passes are running; see `reanalyzeLoopBackEdge`. */
|
|
339
|
+
private loopReanalysisDepth;
|
|
340
|
+
/** The "did you mean" roster, and the names each scope depth contributed to it. */
|
|
341
|
+
private readonly nearestNames;
|
|
342
|
+
private readonly scopedNames;
|
|
343
|
+
private nearestNamesSeeded;
|
|
344
|
+
/** Per scope depth, the bindings flow analysis has written; see `snapshotFlowFacts`. */
|
|
345
|
+
private readonly flowTouched;
|
|
346
|
+
/** What each of those held before its first write, or null for a shadow born mid-flow. */
|
|
347
|
+
private readonly flowOrigins;
|
|
298
348
|
private readonly namedTypes;
|
|
299
349
|
private readonly namedTypeReadonlyFields;
|
|
300
350
|
private readonly namedTypeIdentities;
|
|
@@ -345,12 +395,10 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
345
395
|
private readonly classDisposeChains;
|
|
346
396
|
/** D68 rule 177: expression spans a consumer iterates through `@iterate:`. */
|
|
347
397
|
private readonly iterationContracts;
|
|
348
|
-
/**
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
*/
|
|
353
|
-
private readonly iterateContractDepths;
|
|
398
|
+
/** D90 R18: `async for` statements pulling a declared asynchronous `@iterate:`. */
|
|
399
|
+
private readonly asyncIterationStatements;
|
|
400
|
+
/** D90 R18: `@iterate:` blocks that are the asynchronous pull form, by keyword span. */
|
|
401
|
+
private readonly asyncIterateBlocks;
|
|
354
402
|
/** D51 rule 101: arrows that read a `using`-owned binding, by arrow span. */
|
|
355
403
|
private readonly arrowOwnedCaptures;
|
|
356
404
|
private readonly arrowCaptureFrames;
|
|
@@ -413,6 +461,22 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
413
461
|
private readonly inferredFunctionResultSeeds;
|
|
414
462
|
private readonly inferredFunctionResultTypes;
|
|
415
463
|
private readonly finalizeFunctionResultInference;
|
|
464
|
+
/**
|
|
465
|
+
* D85 rule 209: one mistake is reported once. A reported VEL4039 hands its
|
|
466
|
+
* position `invalidType`, and an invalid body-inferred result is otherwise a
|
|
467
|
+
* convergence failure — so the four collections below carry the *reported*
|
|
468
|
+
* hole forward, and only that hole, to the place VEL4025 is decided.
|
|
469
|
+
* `reportedCollectionHoles` are the names bound to one, `reportedResultHoles`
|
|
470
|
+
* the local function results that are one, `functionResultKeys` maps a
|
|
471
|
+
* callable name to the result a call to it reaches, and
|
|
472
|
+
* `deferredConvergenceReports` holds the reports whose answer needs a callee
|
|
473
|
+
* that may be declared further down the module.
|
|
474
|
+
*/
|
|
475
|
+
private readonly reportedCollectionHoles;
|
|
476
|
+
private readonly bindingHoleCauses;
|
|
477
|
+
private readonly reportedResultHoles;
|
|
478
|
+
private readonly functionResultKeys;
|
|
479
|
+
private readonly deferredConvergenceReports;
|
|
416
480
|
private readonly logicalConditionNarrowings;
|
|
417
481
|
private readonly privateFields;
|
|
418
482
|
private readonly privateGetters;
|
|
@@ -438,8 +502,27 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
438
502
|
/** Namespace import locals by name, known before signature validation runs (ENM-I9 teaching). */
|
|
439
503
|
private readonly namespaceImportLocals;
|
|
440
504
|
private readonly initializationImportReadSites;
|
|
505
|
+
/**
|
|
506
|
+
* D31 item 23's recorded residual: a top-level call of a module-local
|
|
507
|
+
* function runs that body during module evaluation, so a read of an imported
|
|
508
|
+
* binding inside it is an initialization-position read reached through one
|
|
509
|
+
* hop. The stack is the function frame a deferred read belongs to; the map
|
|
510
|
+
* is that frame by the name it was bound to, so a call resolves to it after
|
|
511
|
+
* the whole module is analyzed and hoisting order stops mattering.
|
|
512
|
+
*/
|
|
513
|
+
private readonly deferredReadFrames;
|
|
514
|
+
private readonly localFunctionFrames;
|
|
515
|
+
private readonly arrowDeferredFrames;
|
|
516
|
+
private readonly initializationLocalCalls;
|
|
441
517
|
/** Local class bindings mapped to the source offset where their `class` statement evaluates (CLS-D8). */
|
|
442
518
|
private readonly hoistedClassDeclarations;
|
|
519
|
+
/**
|
|
520
|
+
* D90 R12: public class members whose omitted annotation inferred an output
|
|
521
|
+
* `any`. Whether the member is at an export position depends on whether a
|
|
522
|
+
* consumer can reach its class, which is not settled until the whole module
|
|
523
|
+
* is analyzed, so the report waits for reportExportPositionAny.
|
|
524
|
+
*/
|
|
525
|
+
private readonly exportPositionCandidates;
|
|
443
526
|
/** Module-scope names bound to runtime Type objects (local and imported); see LoweringHints.runtimeTypeObjectNames. */
|
|
444
527
|
private readonly runtimeTypeObjectNames;
|
|
445
528
|
private staticFieldInitialization;
|
|
@@ -474,11 +557,29 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
474
557
|
* answer applies.
|
|
475
558
|
*/
|
|
476
559
|
private guidanceForGlobal;
|
|
560
|
+
/**
|
|
561
|
+
* D90 (coherence): the one report an unresolved name earns, wherever it was
|
|
562
|
+
* written. A reserved global names the module that replaced it, a foreign
|
|
563
|
+
* builtin with no successor stops at the bare message rather than guessing,
|
|
564
|
+
* and everything else may carry the nearest visible name. Both unresolved-
|
|
565
|
+
* name sites reach this, because `exports = {run: run}` is the same mistake
|
|
566
|
+
* as `const value = exports` and used to earn a strictly worse answer for
|
|
567
|
+
* standing on the left of the `=`.
|
|
568
|
+
*/
|
|
569
|
+
private reportUnresolvedName;
|
|
477
570
|
private nearestVisibleBindingName;
|
|
571
|
+
/** Files a scope's name in the "did you mean" roster and takes it back out when the scope exits. */
|
|
572
|
+
private recordScopedName;
|
|
478
573
|
private readonly modulePath;
|
|
479
574
|
private readonly importBindings;
|
|
480
575
|
private readonly dynamicImports;
|
|
481
576
|
analyze(program: Program): readonly Diagnostic[];
|
|
577
|
+
/**
|
|
578
|
+
* D89: the advisories this analysis raised. `analyze` keeps returning the
|
|
579
|
+
* diagnostics alone, so the caller reads the two channels separately and the
|
|
580
|
+
* cursor arithmetic over `this.diagnostics` stays exact.
|
|
581
|
+
*/
|
|
582
|
+
analyzedAdvisories(): readonly Advisory[];
|
|
482
583
|
private registerExternTypeImports;
|
|
483
584
|
private validateDataTypeDeclarations;
|
|
484
585
|
private validateCoreDeclarationSignatures;
|
|
@@ -616,6 +717,21 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
616
717
|
private registerClassNames;
|
|
617
718
|
private registerClassShapes;
|
|
618
719
|
protected analyzeStatement(statement: Statement): void;
|
|
720
|
+
/**
|
|
721
|
+
* D89 A2: the two-slot `for` over a List, Set, or string binds
|
|
722
|
+
* `value, index`, which matches JavaScript's `forEach((v, i) => …)` and
|
|
723
|
+
* inverts Python's `enumerate`. Python's own spelling is already a loud
|
|
724
|
+
* error, so nothing silent comes from it; the silence happens when a model
|
|
725
|
+
* writes `for i, v in nums`, a hybrid neither language has, and both names
|
|
726
|
+
* quietly hold the other one's value.
|
|
727
|
+
*
|
|
728
|
+
* Both rosters must hit. One name alone proves nothing — `for index, total
|
|
729
|
+
* in scores` may be counting exactly what it says — and a wrong guess here
|
|
730
|
+
* would tell a correct author to break working code. The value slot also
|
|
731
|
+
* accepts the singular of the collection's own name, because `for i, user
|
|
732
|
+
* in users` is the same reflex spelled from the data instead of a letter.
|
|
733
|
+
*/
|
|
734
|
+
private adviseSwappedLoopSlots;
|
|
619
735
|
private checkFloatingPromiseStatement;
|
|
620
736
|
private checkDiscardedExpressionResult;
|
|
621
737
|
private carriesPromise;
|
|
@@ -704,23 +820,44 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
704
820
|
* result has and gets the same solution.
|
|
705
821
|
*/
|
|
706
822
|
private seededIterationSource;
|
|
823
|
+
/**
|
|
824
|
+
* D90 R18: the seed routed to the field its form owns. An optional seed can
|
|
825
|
+
* only have come from the asynchronous pull form — the synchronous form
|
|
826
|
+
* never validates to `T?` — so the shape pre-pass reads the form off the
|
|
827
|
+
* seed the previous convergence pass learned.
|
|
828
|
+
*/
|
|
829
|
+
private seededIterationInfo;
|
|
707
830
|
/**
|
|
708
831
|
* `@iterate:` answers the compiler's question "what does
|
|
709
|
-
* iterating you mean?"
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
832
|
+
* iterating you mean?". It shares `@dispose:`'s compiler-name path, then
|
|
833
|
+
* supplies its own role: it is a contract, not a method, and it produces a
|
|
834
|
+
* value. D90 R18 gives it two forms, told apart by the answer's shape the
|
|
835
|
+
* same way `@dispose:`'s async-ness is read off its own body: the
|
|
836
|
+
* synchronous form answers a collection the language already iterates and
|
|
837
|
+
* the eight plain consumers read it once; the asynchronous pull form
|
|
838
|
+
* answers `T?` — `async for` drives it once per element, it may await, and
|
|
839
|
+
* null is exhaustion.
|
|
713
840
|
*/
|
|
714
841
|
private analyzeClassIterate;
|
|
715
842
|
/**
|
|
716
|
-
* The
|
|
717
|
-
* me is iterating this", and the language
|
|
718
|
-
* List, Set, Map, or Record means
|
|
719
|
-
*
|
|
843
|
+
* The answer space is the four collections plus `T?` (D90 R18): the
|
|
844
|
+
* synchronous form says "iterating me is iterating this", and the language
|
|
845
|
+
* already fixed what iterating a List, Set, Map, or Record means; the
|
|
846
|
+
* asynchronous pull form answers one element per pull, null for exhaustion.
|
|
847
|
+
* Anything else would be a second iteration semantics, which is the thing
|
|
848
|
+
* charter section 19 keeps out.
|
|
720
849
|
*/
|
|
721
850
|
private validatedIterationSource;
|
|
722
851
|
/** The `@iterate:` answer a class inherits, most derived ancestor first. */
|
|
723
852
|
private inheritedIterationSource;
|
|
853
|
+
/** D90 R18: the asynchronous `@iterate:` element a class inherits, most derived ancestor first. */
|
|
854
|
+
private inheritedAsyncIterationSource;
|
|
855
|
+
/**
|
|
856
|
+
* D90 R18: what pulling this value under `async for` means. A class answers
|
|
857
|
+
* through the asynchronous `@iterate:` form — its own, or the one it
|
|
858
|
+
* inherits, mirroring the synchronous contract exactly.
|
|
859
|
+
*/
|
|
860
|
+
private asyncIterationContract;
|
|
724
861
|
/**
|
|
725
862
|
* D68 rule 177: what iterating this value means. A class answers through
|
|
726
863
|
* `@iterate:` — its own, or the one it inherits, because overriding replaces
|
|
@@ -782,6 +919,15 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
782
919
|
*/
|
|
783
920
|
private inferredNullResultAnnotation;
|
|
784
921
|
private reportInferredNullResult;
|
|
922
|
+
/**
|
|
923
|
+
* D89 (message correction): the one report a `self` parameter earns, and the
|
|
924
|
+
* deletion it names. The removed range reaches to the next parameter's start
|
|
925
|
+
* (or back to the previous one's end), so the separating comma and its
|
|
926
|
+
* whitespace come with it without reading the source text — the rewrite is a
|
|
927
|
+
* spelling change with no judgment in it, which is what D38 §48 requires of
|
|
928
|
+
* a registered fix.
|
|
929
|
+
*/
|
|
930
|
+
private reportImplicitSelfParameter;
|
|
785
931
|
protected analyzeFunctionDeclaration(statement: AnalyzableFunctionDeclaration, className: string | null, method?: boolean, declareSelf?: boolean, forceAsynchronous?: boolean, declarationKind?: string): void;
|
|
786
932
|
/**
|
|
787
933
|
* A target-owned declaration may use an ordinary default expression as a
|
|
@@ -814,14 +960,57 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
814
960
|
private containsCoreDuration;
|
|
815
961
|
private inferCoreDurationExpression;
|
|
816
962
|
private inferBinary;
|
|
963
|
+
/**
|
|
964
|
+
* D89 A3: `%` follows JavaScript and keeps the dividend's sign, so `-7 % 3`
|
|
965
|
+
* is `-1` where Python answers `2`. Nothing here reports an error — both
|
|
966
|
+
* languages accept the spelling, they just disagree about the result.
|
|
967
|
+
*
|
|
968
|
+
* Only a literal negative dividend triggers. A variable's sign is not
|
|
969
|
+
* knowable, and advising every `%` whose left side might go negative would
|
|
970
|
+
* be the noise the tier exists to avoid. The shape matched is a unary minus
|
|
971
|
+
* wrapping a numeric literal, because that is what `-7` parses as; there is
|
|
972
|
+
* no negative-valued literal for a value test to find.
|
|
973
|
+
*
|
|
974
|
+
* The admission bar is "Vel accepts the spelling as a different meaning", so
|
|
975
|
+
* every shape whose two answers are the same is silent rather than advised:
|
|
976
|
+
* a remainder of zero (`-6 % 3`) agrees, `% 0` answers NaN here and raises
|
|
977
|
+
* in Python so there is no Python answer to name, and a non-finite dividend
|
|
978
|
+
* answers NaN on both sides. A message that states a disagreement and then
|
|
979
|
+
* prints the same number twice is a new defect, not a weaker advisory.
|
|
980
|
+
*/
|
|
981
|
+
private adviseNegativeLiteralModulo;
|
|
817
982
|
private requireIntersectingEquality;
|
|
818
983
|
private rejectFreshCollectionEquality;
|
|
819
984
|
private freshCollectionOperand;
|
|
820
985
|
private requireMembershipIntersection;
|
|
986
|
+
private rejectFreshCollectionProbe;
|
|
821
987
|
private rejectDisjointEnumTest;
|
|
822
988
|
/** The enum/null arms of a type, or null when any arm falls outside that domain. */
|
|
823
989
|
private pureEnumDomainArms;
|
|
824
990
|
private rejectDisjointEnumValidatorProbe;
|
|
991
|
+
/**
|
|
992
|
+
* D59 rule 141 settled that `toBe` *is* `==` ("toBe 必须用语言自己的 `==`")
|
|
993
|
+
* and rule 141.1 settled that `toContain` *is* `values.has(item)`. The
|
|
994
|
+
* runtime half of both landed; the compile-time half did not travel with
|
|
995
|
+
* them, so `expect([1]).toBe([1])` compiled and failed at run time with
|
|
996
|
+
* both operands rendering byte-identically, while `[1] == [1]` is refused
|
|
997
|
+
* where it is written. This runs the operator's own two gates on the
|
|
998
|
+
* matcher: D42 item 64's intersection requirement, and COL-I3's rejection
|
|
999
|
+
* of a freshly built literal in an identity comparison.
|
|
1000
|
+
*
|
|
1001
|
+
* `toBe` and `toEqual` deliberately part company on the fresh-literal gate.
|
|
1002
|
+
* `toBe` asks the `==` question, where a new object can never be identical
|
|
1003
|
+
* to anything, so the literal proves the answer. `toEqual` asks the
|
|
1004
|
+
* `equals(a, b)` question, where a fresh literal is the normal and correct
|
|
1005
|
+
* spelling of the expected value — rejecting it there would refuse the very
|
|
1006
|
+
* repair the `toBe` message teaches. The intersection gate has no such
|
|
1007
|
+
* split: two types with no values in common never deeply equal either.
|
|
1008
|
+
*
|
|
1009
|
+
* `toHaveLength` and `toMatch` are left alone. Neither takes a comparand:
|
|
1010
|
+
* `toHaveLength` takes a count, and `toMatch` takes a regular-expression
|
|
1011
|
+
* pattern whose relation to the subject is matching, not equality.
|
|
1012
|
+
*/
|
|
1013
|
+
private checkTestMatcherComparand;
|
|
825
1014
|
private enumTargetOfValidatorObject;
|
|
826
1015
|
/** The enum behind a type alias name, or null when the alias does not resolve to an enum. */
|
|
827
1016
|
private aliasedEnumTarget;
|
|
@@ -960,6 +1149,21 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
960
1149
|
private narrowingSubjectExpression;
|
|
961
1150
|
/** The property name when an expression reads a getter rather than a stored field. */
|
|
962
1151
|
private getterAccessProperty;
|
|
1152
|
+
/**
|
|
1153
|
+
* D90 R17: the author's own spelling of a boundary value, for the
|
|
1154
|
+
* diagnostics that teach `Type.parse`. Identifier and member paths render
|
|
1155
|
+
* exactly, a simple call renders as `name(...)`, and anything else answers
|
|
1156
|
+
* null so the caller falls back to the word `value`.
|
|
1157
|
+
*/
|
|
1158
|
+
private boundaryReceiverText;
|
|
1159
|
+
/** A type name suggested from the receiver's last name segment, or 'X' when none reads naturally. */
|
|
1160
|
+
private boundaryTypeNameSuggestion;
|
|
1161
|
+
/**
|
|
1162
|
+
* D90 R17: an undeclared foreign value arrives as unknown, and the way into
|
|
1163
|
+
* the typed world is `Type.parse` at the edge. Every refusal on an unknown
|
|
1164
|
+
* teaches that ritual with the author's own expression spelled into it.
|
|
1165
|
+
*/
|
|
1166
|
+
private boundaryValidationGuidance;
|
|
963
1167
|
private conditionSubjectText;
|
|
964
1168
|
protected requireAssignable(actual: ValueType, expected: ValueType, valueSpan: Span): void;
|
|
965
1169
|
/**
|
|
@@ -1058,10 +1262,32 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
1058
1262
|
* carried whole so the author never sees a half-migrated module.
|
|
1059
1263
|
*/
|
|
1060
1264
|
private reportPermanentNamespaceImports;
|
|
1265
|
+
/**
|
|
1266
|
+
* D50 rule 97.3: a retirement that leaves one surviving spelling did not
|
|
1267
|
+
* happen. `export {stringify} from "velar/json"` is an import spelling with
|
|
1268
|
+
* an export in front of it — the barrel republishes the retired bare name
|
|
1269
|
+
* and every downstream `import {stringify} from "./barrel.vel"` is clean
|
|
1270
|
+
* forever after. No mechanical fix: which reads in which other modules
|
|
1271
|
+
* wanted the name is not a rewrite this module can make.
|
|
1272
|
+
*/
|
|
1273
|
+
private reportPermanentNamespaceReExports;
|
|
1061
1274
|
/** A member name to show in the rule 106 guidance, so the fix is concrete. */
|
|
1062
1275
|
private firstNamespaceMember;
|
|
1063
1276
|
protected typeError(message: string, errorSpan: Span, fix?: DiagnosticFix): void;
|
|
1064
1277
|
protected recoveredTypeError(message: string, errorSpan: Span, fix?: DiagnosticFix): void;
|
|
1278
|
+
/**
|
|
1279
|
+
* D89: raises a roster advisory. It cannot reach `this.diagnostics`, so it
|
|
1280
|
+
* cannot fail a build and cannot shift the diagnostic cursors this analyzer
|
|
1281
|
+
* reads as array lengths.
|
|
1282
|
+
*
|
|
1283
|
+
* One report per code and span. `reanalyzeLoopBackEdge` runs a loop body a
|
|
1284
|
+
* second time whenever the back edge invalidates a fact, and its diagnostic
|
|
1285
|
+
* answer is `deduplicateDiagnostics`, which only ever touches
|
|
1286
|
+
* `this.diagnostics`. Deduplicating where the advisory is raised covers that
|
|
1287
|
+
* pass and every other re-analysis without a second pair of cursors, which
|
|
1288
|
+
* is the whole reason the two channels are separate arrays.
|
|
1289
|
+
*/
|
|
1290
|
+
protected advise(code: string, message: string, adviceSpan: Span, fix?: DiagnosticFix): void;
|
|
1065
1291
|
private analyzeMatchPattern;
|
|
1066
1292
|
private matchLocationNarrowing;
|
|
1067
1293
|
private retargetNarrowings;
|
|
@@ -1100,17 +1326,93 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
1100
1326
|
* constructor's own arguments. Nothing infers it from a later mutation, so a
|
|
1101
1327
|
* binding left with no source is reported at the construction rather than
|
|
1102
1328
|
* kept as `unknown` for a following line to fill in.
|
|
1329
|
+
*
|
|
1330
|
+
* The value written at this position is not always the construction itself.
|
|
1331
|
+
* A ternary arm, a list element or its spread, a record-literal field, a
|
|
1332
|
+
* `??` fallback, a receiver and an argument all become part of the value the
|
|
1333
|
+
* name holds, so each is its own settling position and each reports at its
|
|
1334
|
+
* own `[]`. What stops the walk is the value, not the syntax: it descends
|
|
1335
|
+
* only while `carriesUnsettledCollection` still sees the hole in the type
|
|
1336
|
+
* arriving here, so `print(Set().size)` and `const n = Set().size` stay
|
|
1337
|
+
* legal per rule 208 — neither of those names holds a collection — while a
|
|
1338
|
+
* spread whose `unknown` the merge absorbs (`["x", ...[]]`) leaves nothing
|
|
1339
|
+
* to report. A sibling settles nothing for its neighbour: `[["a"], []]`
|
|
1340
|
+
* merges through `unionOf`, so the union still carries the hole and the
|
|
1341
|
+
* empty `[]` reports on its own.
|
|
1342
|
+
*
|
|
1343
|
+
* Returns whether it reported, so the caller can hand the name `invalidType`
|
|
1344
|
+
* instead of the hole. Rule 209 requires one mistake to be reported once,
|
|
1345
|
+
* and `List<unknown>` reaching a later line is what produces the second,
|
|
1346
|
+
* contradicting report the ruling exists to delete.
|
|
1347
|
+
*/
|
|
1348
|
+
protected requireSettledCollectionElement(initializer: Expression, declared: ValueType, annotated: boolean): boolean;
|
|
1349
|
+
/**
|
|
1350
|
+
* D85 rule 209: where the value at this position came from, when it came
|
|
1351
|
+
* from a hole VEL4039 already reported. The answer is two-part because a
|
|
1352
|
+
* callee can be declared after its caller: `true` is a hole already on
|
|
1353
|
+
* record, and `causes` are the local results that make this position a hole
|
|
1354
|
+
* too if theirs turn out to be one.
|
|
1355
|
+
*
|
|
1356
|
+
* Only a name and a call to a local name are modelled — the two shapes an
|
|
1357
|
+
* author writes between an empty collection and the `return` that publishes
|
|
1358
|
+
* it. Anything else contributes nothing, so an unmodelled position keeps the
|
|
1359
|
+
* report it has today rather than losing one.
|
|
1360
|
+
*/
|
|
1361
|
+
private collectResultHoleSources;
|
|
1362
|
+
/**
|
|
1363
|
+
* D85 rule 209: a name bound to a reported hole carries it, so `const a = []`
|
|
1364
|
+
* followed by `return a` is the same one mistake `return []` is. Only an
|
|
1365
|
+
* unannotated `const`/`let` of a single name carries anything: an annotation
|
|
1366
|
+
* settles the construction, and a destructuring pattern takes the hole apart
|
|
1367
|
+
* rather than passing it on.
|
|
1368
|
+
*/
|
|
1369
|
+
private recordBindingHoleSource;
|
|
1370
|
+
/**
|
|
1371
|
+
* D85 rule 209: delete the convergence report of every function whose result
|
|
1372
|
+
* is invalid only because a hole VEL4039 already explained reached it through
|
|
1373
|
+
* a local call. The set grows until it stops growing, because a chain of
|
|
1374
|
+
* forwarding functions is still one mistake however long it is — and a cycle
|
|
1375
|
+
* with no empty collection anywhere in it never enters the set, so a genuine
|
|
1376
|
+
* convergence failure still reports on both of its halves.
|
|
1103
1377
|
*/
|
|
1104
|
-
|
|
1378
|
+
private resolveDeferredConvergenceReports;
|
|
1379
|
+
private reportUnsettledCollection;
|
|
1105
1380
|
private isFreshUnresolvedCollection;
|
|
1106
1381
|
protected declareBinding(name: string, mutable: boolean, type: ValueType, declarationSpan: Span, internal?: boolean, declaredType?: ValueType, importSource?: string): void;
|
|
1107
1382
|
private recordImportedBindingSource;
|
|
1108
1383
|
private recordImportedBindingOrigin;
|
|
1109
1384
|
private recordInitializationImportRead;
|
|
1385
|
+
/**
|
|
1386
|
+
* D31 item 23: the call edge. Inside a deferred body it is an edge of the
|
|
1387
|
+
* reachability graph; at module top level it is a root, because that call
|
|
1388
|
+
* runs the callee while the module itself evaluates. The callee is held as
|
|
1389
|
+
* a binding, not as a frame — a `def` is hoisted, so `const x = pull()` can
|
|
1390
|
+
* be analyzed before `def pull()` is.
|
|
1391
|
+
*/
|
|
1392
|
+
private recordDeferredCallEdge;
|
|
1393
|
+
/** Files an arrow's deferred frame under the module-local name it was bound to. */
|
|
1394
|
+
private claimArrowDeferredFrame;
|
|
1110
1395
|
/** True while analysis is directly in a declaration body rather than a function frame. */
|
|
1111
1396
|
protected inComponentSetupPosition(): boolean;
|
|
1112
1397
|
protected inModuleInitializationPosition(): boolean;
|
|
1113
|
-
/**
|
|
1398
|
+
/**
|
|
1399
|
+
* Initialization-position reads of imported bindings, for the project
|
|
1400
|
+
* module-cycle check.
|
|
1401
|
+
*
|
|
1402
|
+
* D31 item 23 recorded the indirect shape as a v1 residual: a top-level call
|
|
1403
|
+
* of a module-local function runs that body while the module evaluates, so
|
|
1404
|
+
* an imported binding read inside it is an initialization-position read too
|
|
1405
|
+
* — and following VEL3019's own remediation ("Move this read into a
|
|
1406
|
+
* function") and then calling that function at top level re-created the bare
|
|
1407
|
+
* `ReferenceError` the check exists to delete. The closure below is the
|
|
1408
|
+
* intra-module reachability pass that closes it: one module, one walk over
|
|
1409
|
+
* the call edges already collected, no cross-module analysis.
|
|
1410
|
+
*
|
|
1411
|
+
* An indirect read is reported at the *call*, not at the read. The call is
|
|
1412
|
+
* the line that runs during module evaluation and the line an author can
|
|
1413
|
+
* move; the read inside the body is already in a function, which is what the
|
|
1414
|
+
* remediation asks for.
|
|
1415
|
+
*/
|
|
1114
1416
|
moduleInitializationImportReads(): readonly InitializationImportRead[];
|
|
1115
1417
|
private requireTextConvertible;
|
|
1116
1418
|
private isTextConvertible;
|
|
@@ -1131,6 +1433,47 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
1131
1433
|
private runtimeTypeObjectValue;
|
|
1132
1434
|
private displayExternalClasses;
|
|
1133
1435
|
protected prescanScopeDeclarations(statements: readonly Statement[]): void;
|
|
1436
|
+
/**
|
|
1437
|
+
* D90 R12: "exported" is a property of the declaration a consumer can reach,
|
|
1438
|
+
* not of the `def` keyword. A module-level declaration carries the flag
|
|
1439
|
+
* itself and is judged here and now. A class member carries none — a public
|
|
1440
|
+
* member of a class this module publishes is read by a consumer exactly as
|
|
1441
|
+
* an exported `const` is — but whether the class is published is a question
|
|
1442
|
+
* about the whole module, so the member waits for reportExportPositionAny. A
|
|
1443
|
+
* `private` member is never reachable, and R12's boundary does not move:
|
|
1444
|
+
* module-internal `any` stays legal.
|
|
1445
|
+
*/
|
|
1446
|
+
private recordExportedAny;
|
|
1447
|
+
/**
|
|
1448
|
+
* D90 R12: the class members that turned out to be at an export position.
|
|
1449
|
+
* Reported once the module is analyzed, because the answer is reachability
|
|
1450
|
+
* and reachability is a property of the module, not of the declaration.
|
|
1451
|
+
*/
|
|
1452
|
+
private reportExportPositionAny;
|
|
1453
|
+
/**
|
|
1454
|
+
* D90 R12: which class declarations a consuming module can reach. Exported
|
|
1455
|
+
* classes seed the set; from there it follows every position a consumer can
|
|
1456
|
+
* read a value *out of* — the type of anything else this module exports, the
|
|
1457
|
+
* base a reachable class names, and the public surface of a class already
|
|
1458
|
+
* reachable. `export class Box extends Base:` publishes `Base`'s members,
|
|
1459
|
+
* and `def make() -> Inner` publishes `Inner`'s, whether or not either name
|
|
1460
|
+
* is exported.
|
|
1461
|
+
*
|
|
1462
|
+
* Input positions are deliberately absent, for the same reason
|
|
1463
|
+
* `typeContainsAnyOutput` omits them: a consumer that has to *supply* an
|
|
1464
|
+
* instance obtained it from an output position first, and that position is
|
|
1465
|
+
* what makes the class reachable.
|
|
1466
|
+
*/
|
|
1467
|
+
private exportReachableClasses;
|
|
1468
|
+
/**
|
|
1469
|
+
* D90 R12: the diagnostic has to teach the way out, not only refuse. A
|
|
1470
|
+
* consuming module never writes `unsafe`, so an exported `any` hands it a
|
|
1471
|
+
* value carrying no guarantee at all; the escape is to validate the value
|
|
1472
|
+
* into a declared type in the module that owns the boundary, which is what
|
|
1473
|
+
* `Type.parse` exists for. No new diagnostic code and no unsafe marker: this
|
|
1474
|
+
* is the rule at validateTypeReference finished, not a second rule.
|
|
1475
|
+
*/
|
|
1476
|
+
private reportExportedAny;
|
|
1134
1477
|
private collectPatternNames;
|
|
1135
1478
|
private checkShadowedRead;
|
|
1136
1479
|
private declarePattern;
|
|
@@ -1171,10 +1514,44 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
1171
1514
|
private memberNarrowingRootType;
|
|
1172
1515
|
private runtimeCheckedType;
|
|
1173
1516
|
private matchPatternReflectionMayExecute;
|
|
1517
|
+
/**
|
|
1518
|
+
* A snapshot used to copy every binding of every live scope, which made a
|
|
1519
|
+
* branch cost O(names in the module) and whole-module analysis quadratic in
|
|
1520
|
+
* module size. A binding nothing ever narrows cannot differ between two
|
|
1521
|
+
* moments, so only the bindings flow analysis has actually written are
|
|
1522
|
+
* visited — `flowTouched`, kept per scope depth so an exiting scope drops
|
|
1523
|
+
* its own, and `flowOrigins`, which remembers what each one held before its
|
|
1524
|
+
* first write. `flowOrigins` answers for a binding a *later* write touched
|
|
1525
|
+
* than the snapshot being restored: the snapshot has no entry, and its
|
|
1526
|
+
* pre-write state is exactly the state that snapshot recorded. A narrowing
|
|
1527
|
+
* shadow born after the snapshot stores `null` instead, because a full-scope
|
|
1528
|
+
* snapshot had nothing to restore it to either.
|
|
1529
|
+
*/
|
|
1530
|
+
private flowFactState;
|
|
1531
|
+
/** Called immediately before flow analysis writes a binding, so the recorded state is the pre-write one. */
|
|
1532
|
+
private recordFlowFactOrigin;
|
|
1533
|
+
/** A narrowing shadow created mid-flow: no older snapshot has a state for it. */
|
|
1534
|
+
private trackNarrowingShadow;
|
|
1535
|
+
private trackFlowBinding;
|
|
1536
|
+
/** Every binding whose flow facts may differ from another moment's, outermost scope first. */
|
|
1537
|
+
private touchedFlowBindings;
|
|
1538
|
+
/** The state `snapshot` recorded for `binding`, or null when it did not exist yet. */
|
|
1539
|
+
private flowStateIn;
|
|
1174
1540
|
private snapshotFlowFacts;
|
|
1175
1541
|
private restoreFlowFacts;
|
|
1176
1542
|
private analyzeIsolatedFlow;
|
|
1177
1543
|
private flowInvalidationsSince;
|
|
1544
|
+
/**
|
|
1545
|
+
* A loop's back-edge pass re-runs the whole body, and a nested loop inside
|
|
1546
|
+
* that pass runs its own, so the work doubled with every level of loop
|
|
1547
|
+
* nesting: fourteen levels of `while` in a 91-line file took 2.4 seconds and
|
|
1548
|
+
* seventeen took 35. The passes are budgeted by how many back-edge passes
|
|
1549
|
+
* are already running. Past the budget a loop analyzes its body once and its
|
|
1550
|
+
* exit keeps nothing — `widened` — which is what the loop would answer if
|
|
1551
|
+
* its back edge had falsified every fact, so the degradation only ever
|
|
1552
|
+
* removes a fact, never invents one. Real code does not nest loops four
|
|
1553
|
+
* deep, so nothing reachable by hand reaches the budget.
|
|
1554
|
+
*/
|
|
1178
1555
|
private reanalyzeLoopBackEdge;
|
|
1179
1556
|
private flowInvalidationsAffectFacts;
|
|
1180
1557
|
private deduplicateDiagnostics;
|
|
@@ -1182,7 +1559,18 @@ export declare class Analyzer implements TypeEnvironment {
|
|
|
1182
1559
|
private clearCachedFlowTypesInSpan;
|
|
1183
1560
|
private flowSnapshotAfterInvalidations;
|
|
1184
1561
|
private visibleBindings;
|
|
1562
|
+
/** The binding a name resolved to when `visible` was captured. */
|
|
1563
|
+
private visibleBinding;
|
|
1564
|
+
/**
|
|
1565
|
+
* Only a name a narrowing has written can carry a fact, and `narrowedNames`
|
|
1566
|
+
* is the roster of those per scope — so this walks the narrowings rather
|
|
1567
|
+
* than every name in scope. The member half matches a dotted path against
|
|
1568
|
+
* the binding its root names instead of spreading the whole root set per
|
|
1569
|
+
* path, which is O(one lookup) rather than O(names in the module).
|
|
1570
|
+
*/
|
|
1185
1571
|
private narrowingsForVisibleBindings;
|
|
1572
|
+
/** Whether a member path's root — `<declaration offset>:<name>` — names a binding visible then. */
|
|
1573
|
+
private memberNarrowingRootIsVisible;
|
|
1186
1574
|
private narrowingsInSnapshot;
|
|
1187
1575
|
private commonNarrowings;
|
|
1188
1576
|
/**
|