@velarscript/cli 0.12.1 → 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/README.md +4 -12
- package/dist/browser-process-owner.d.ts +23 -0
- package/dist/browser-process-owner.d.ts.map +1 -1
- package/dist/browser-process-owner.js +46 -2
- package/dist/browser-process-owner.js.map +1 -1
- package/dist/browser-test-runner.d.ts.map +1 -1
- package/dist/browser-test-runner.js +110 -14
- package/dist/browser-test-runner.js.map +1 -1
- package/dist/cli.js +131 -68
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +28 -4
- package/dist/config.js.map +1 -1
- package/dist/dev-server.d.ts +18 -0
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +168 -8
- package/dist/dev-server.js.map +1 -1
- package/dist/extension-metadata.d.ts +6 -0
- package/dist/extension-metadata.d.ts.map +1 -1
- package/dist/extension-metadata.js +70 -4
- package/dist/extension-metadata.js.map +1 -1
- package/dist/format-guard.d.ts +20 -0
- package/dist/format-guard.d.ts.map +1 -0
- package/dist/format-guard.js +13 -0
- package/dist/format-guard.js.map +1 -0
- package/dist/framework-host.d.ts.map +1 -1
- package/dist/framework-host.js +15 -2
- package/dist/framework-host.js.map +1 -1
- package/dist/language-server-bundle-entry.js +0 -2
- package/dist/language-server-bundle-entry.js.map +1 -1
- package/dist/language-server-tool.d.ts.map +1 -1
- package/dist/language-server-tool.js +0 -2
- package/dist/language-server-tool.js.map +1 -1
- package/dist/language-server.d.ts +1 -1
- package/dist/language-server.d.ts.map +1 -1
- package/dist/language-server.js +87 -293
- package/dist/language-server.js.map +1 -1
- package/dist/local-request-guard.d.ts +18 -0
- package/dist/local-request-guard.d.ts.map +1 -0
- package/dist/local-request-guard.js +75 -0
- package/dist/local-request-guard.js.map +1 -0
- package/dist/mechanical-fixer.d.ts.map +1 -1
- package/dist/mechanical-fixer.js +116 -2
- package/dist/mechanical-fixer.js.map +1 -1
- package/dist/module-assets.d.ts +23 -0
- package/dist/module-assets.d.ts.map +1 -1
- package/dist/module-assets.js +216 -14
- package/dist/module-assets.js.map +1 -1
- package/dist/node-application.d.ts +7 -2
- package/dist/node-application.d.ts.map +1 -1
- package/dist/node-application.js +44 -14
- package/dist/node-application.js.map +1 -1
- package/dist/node-runtime-dependencies.d.ts +2 -0
- package/dist/node-runtime-dependencies.d.ts.map +1 -0
- package/dist/node-runtime-dependencies.js +24 -0
- package/dist/node-runtime-dependencies.js.map +1 -0
- package/dist/npm.d.ts +29 -0
- package/dist/npm.d.ts.map +1 -1
- package/dist/npm.js +39 -2
- package/dist/npm.js.map +1 -1
- package/dist/ownership-graph.d.ts.map +1 -1
- package/dist/ownership-graph.js +155 -38
- package/dist/ownership-graph.js.map +1 -1
- package/dist/package-manager.d.ts.map +1 -1
- package/dist/package-manager.js +4 -1
- package/dist/package-manager.js.map +1 -1
- package/dist/preview-server.d.ts.map +1 -1
- package/dist/preview-server.js +12 -4
- package/dist/preview-server.js.map +1 -1
- package/dist/production-build.d.ts.map +1 -1
- package/dist/production-build.js +24 -6
- package/dist/production-build.js.map +1 -1
- package/dist/production-verifier.js +3 -0
- package/dist/production-verifier.js.map +1 -1
- package/dist/project-check.d.ts +14 -1
- package/dist/project-check.d.ts.map +1 -1
- package/dist/project-check.js +17 -4
- package/dist/project-check.js.map +1 -1
- package/dist/project-format.d.ts +9 -0
- package/dist/project-format.d.ts.map +1 -1
- package/dist/project-format.js +13 -0
- package/dist/project-format.js.map +1 -1
- package/dist/project-semantic.d.ts.map +1 -1
- package/dist/project-semantic.js +15 -4
- package/dist/project-semantic.js.map +1 -1
- package/dist/project.d.ts +25 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +341 -42
- package/dist/project.js.map +1 -1
- package/dist/reproduction.d.ts +18 -0
- package/dist/reproduction.d.ts.map +1 -1
- package/dist/reproduction.js +47 -6
- package/dist/reproduction.js.map +1 -1
- package/dist/stable-order.d.ts +17 -0
- package/dist/stable-order.d.ts.map +1 -0
- package/dist/stable-order.js +19 -0
- package/dist/stable-order.js.map +1 -0
- package/dist/standard-modules.d.ts +2 -2
- package/dist/standard-modules.d.ts.map +1 -1
- package/dist/standard-modules.js +2 -2
- package/dist/standard-modules.js.map +1 -1
- package/dist/static-deployment.d.ts.map +1 -1
- package/dist/static-deployment.js +27 -0
- package/dist/static-deployment.js.map +1 -1
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +196 -100
- package/dist/test-runner.js.map +1 -1
- package/dist/test-worker.d.ts +64 -0
- package/dist/test-worker.d.ts.map +1 -0
- package/dist/test-worker.js +161 -0
- package/dist/test-worker.js.map +1 -0
- package/dist/typescript-declarations.d.ts +1 -1
- package/dist/typescript-declarations.d.ts.map +1 -1
- package/dist/typescript-declarations.js +233 -21
- package/dist/typescript-declarations.js.map +1 -1
- package/dist/unowned-errors.d.ts +15 -2
- package/dist/unowned-errors.d.ts.map +1 -1
- package/dist/unowned-errors.js +13 -2
- package/dist/unowned-errors.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/workspace-index.d.ts.map +1 -1
- package/dist/workspace-index.js +42 -17
- package/dist/workspace-index.js.map +1 -1
- package/package.json +7 -8
- package/skill/ai-skill-node.md +74 -9
- package/skill/ai-skill-web.md +51 -1
- package/skill/ai-skill.md +36 -13
- package/dist/official-script-language-service.d.ts +0 -2
- package/dist/official-script-language-service.d.ts.map +0 -1
- package/dist/official-script-language-service.js +0 -10
- package/dist/official-script-language-service.js.map +0 -1
- package/dist/official-tool-assets.d.ts +0 -3
- package/dist/official-tool-assets.d.ts.map +0 -1
- package/dist/official-tool-assets.js +0 -60
- package/dist/official-tool-assets.js.map +0 -1
- package/dist/script-language-service.d.ts +0 -82
- package/dist/script-language-service.d.ts.map +0 -1
- package/dist/script-language-service.js +0 -18
- package/dist/script-language-service.js.map +0 -1
package/dist/project.js
CHANGED
|
@@ -10,6 +10,8 @@ import { MAX_VELAR_PROJECT_MODULES, readVelarSourceFile, validateVelarSourceText
|
|
|
10
10
|
import { readBoundedText } from "./bounded-text.js";
|
|
11
11
|
import { hostErrorMessage, isHostErrorCode } from "./host-error.js";
|
|
12
12
|
import { canonicalizePotentialPath } from "./canonical-path.js";
|
|
13
|
+
import { byCodeUnit } from "./stable-order.js";
|
|
14
|
+
import { VELAR_VERSION } from "./version.js";
|
|
13
15
|
const MAX_PROJECT_RESOURCES = 1024;
|
|
14
16
|
const MAX_JSON_RESOURCE_BYTES = 4 * 1024 * 1024;
|
|
15
17
|
function missingExportMessage(source, name) {
|
|
@@ -103,8 +105,11 @@ export async function compileProjectEntries(entries, primaryEntry, overrides = n
|
|
|
103
105
|
scheduled.add(module.inputPath);
|
|
104
106
|
pending.push(module);
|
|
105
107
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
// An index cursor, not `shift()`: the queue is bounded by
|
|
109
|
+
// MAX_VELAR_PROJECT_MODULES, and shifting each of those entries off the
|
|
110
|
+
// front costs O(n) apiece, making the dependency walk itself quadratic.
|
|
111
|
+
for (let cursor = 0; cursor < pending.length; cursor += 1) {
|
|
112
|
+
const pendingModule = pending[cursor];
|
|
108
113
|
const inputPath = pendingModule.inputPath;
|
|
109
114
|
if (visited.has(inputPath))
|
|
110
115
|
continue;
|
|
@@ -385,8 +390,10 @@ export async function compileProjectEntries(entries, primaryEntry, overrides = n
|
|
|
385
390
|
}
|
|
386
391
|
}
|
|
387
392
|
const modules = [];
|
|
388
|
-
const affected = previous ? affectedModules(loaded, velarImports, resourceImports, previous, changedPaths) : new Set(loaded.keys());
|
|
389
393
|
const previousModules = new Map(previous?.modules.map((module) => [module.inputPath, module]));
|
|
394
|
+
const affected = previous
|
|
395
|
+
? affectedModules(loaded, velarImports, resourceImports, previous, previousModules, changedPaths)
|
|
396
|
+
: new Set(loaded.keys());
|
|
390
397
|
for (const [dependency, importers] of previous?.externalTypeDependencies ?? []) {
|
|
391
398
|
for (const importer of importers) {
|
|
392
399
|
if (!loaded.has(importer) || affected.has(importer))
|
|
@@ -463,7 +470,13 @@ export async function compileProjectEntries(entries, primaryEntry, overrides = n
|
|
|
463
470
|
modules.push(...group.map((module) => passResults.get(module.inputPath)));
|
|
464
471
|
}
|
|
465
472
|
appendInitializationCycleDiagnostics(modules, loaded, velarImports, entryPath, resolutionDiagnostics);
|
|
466
|
-
|
|
473
|
+
// D90 R3(a): module order decides the concatenated stylesheet's bytes, its
|
|
474
|
+
// content hash, and `buildId`. `localeCompare` follows the collation the
|
|
475
|
+
// process environment selects, so it made those outputs — and the cascade
|
|
476
|
+
// winner between two equal-specificity rules — depend on the build
|
|
477
|
+
// machine's `LC_ALL`. Order by code unit over the POSIX-normalized
|
|
478
|
+
// relative path instead.
|
|
479
|
+
modules.sort((left, right) => byCodeUnit(left.relativePath, right.relativePath));
|
|
467
480
|
if (framework?.host.validateProject) {
|
|
468
481
|
try {
|
|
469
482
|
const messages = framework.host.validateProject({
|
|
@@ -622,10 +635,10 @@ function standardModuleListing(source, interfaces) {
|
|
|
622
635
|
}
|
|
623
636
|
function migratedStandardPackageDiagnostic(source) {
|
|
624
637
|
if (source === "velar/javascript") {
|
|
625
|
-
return "Standard module 'velar/javascript'
|
|
638
|
+
return "Standard module 'velar/javascript' is not part of VelarScript; JavaScript and TypeScript tooling belongs to the consuming project";
|
|
626
639
|
}
|
|
627
640
|
if (source === "velar/text-buffer") {
|
|
628
|
-
return "Standard module 'velar/text-buffer'
|
|
641
|
+
return "Standard module 'velar/text-buffer' is not part of VelarScript; applications must own or install their text-buffer implementation";
|
|
629
642
|
}
|
|
630
643
|
return null;
|
|
631
644
|
}
|
|
@@ -667,7 +680,7 @@ function importedReactiveAssignmentDiagnostics(result, reactiveImports) {
|
|
|
667
680
|
? { ...result, diagnostics }
|
|
668
681
|
: result;
|
|
669
682
|
}
|
|
670
|
-
function affectedModules(loaded, velarImports, resourceImports, previous, changedPaths) {
|
|
683
|
+
function affectedModules(loaded, velarImports, resourceImports, previous, previousModules, changedPaths) {
|
|
671
684
|
const affected = new Set([...changedPaths].map((path) => resolve(path)));
|
|
672
685
|
const reverse = new Map();
|
|
673
686
|
const dependencies = (path, values, imports) => {
|
|
@@ -709,25 +722,30 @@ function affectedModules(loaded, velarImports, resourceImports, previous, change
|
|
|
709
722
|
dependents.add(importer);
|
|
710
723
|
reverse.set(dependency, dependents);
|
|
711
724
|
}
|
|
725
|
+
// An index cursor, not `shift()`: the array shift is O(n) per element, so
|
|
726
|
+
// the closure walk was quadratic in the number of affected modules.
|
|
712
727
|
const pending = [...affected];
|
|
713
|
-
|
|
714
|
-
const
|
|
715
|
-
for (const dependent of reverse.get(path) ?? []) {
|
|
728
|
+
for (let cursor = 0; cursor < pending.length; cursor += 1) {
|
|
729
|
+
for (const dependent of reverse.get(pending[cursor]) ?? []) {
|
|
716
730
|
if (affected.has(dependent))
|
|
717
731
|
continue;
|
|
718
732
|
affected.add(dependent);
|
|
719
733
|
pending.push(dependent);
|
|
720
734
|
}
|
|
721
735
|
}
|
|
736
|
+
// A module the previous result never held is affected by definition. Asking
|
|
737
|
+
// that of the previous module *list* was a linear scan per loaded module —
|
|
738
|
+
// O(M²) string comparisons on every keystroke at the 4096-module cap — for
|
|
739
|
+
// a question the caller's map already answers in constant time.
|
|
722
740
|
for (const module of loaded.keys())
|
|
723
|
-
if (!
|
|
741
|
+
if (!previousModules.has(module))
|
|
724
742
|
affected.add(module);
|
|
725
743
|
return affected;
|
|
726
744
|
}
|
|
727
745
|
function dependencyFirstCompilationGroups(loaded, velarImports, compilerExtensions) {
|
|
728
746
|
return stronglyConnectedPaths(loaded.keys(), (path) => moduleDependencies(loaded.get(path), loaded, velarImports, compilerExtensions)).map((group) => group
|
|
729
747
|
.map((path) => loaded.get(path))
|
|
730
|
-
.sort((left, right) => left.inputPath
|
|
748
|
+
.sort((left, right) => byCodeUnit(left.inputPath, right.inputPath)));
|
|
731
749
|
}
|
|
732
750
|
/** Iterative Tarjan: the public 4096-module bound must not depend on host stack depth. */
|
|
733
751
|
function stronglyConnectedPaths(paths, dependencies) {
|
|
@@ -915,7 +933,9 @@ function appendInitializationCycleDiagnostics(modules, loaded, velarImports, ent
|
|
|
915
933
|
const additions = [];
|
|
916
934
|
if (cyclic && (componentSizes.get(componentOf.get(path) ?? -1) ?? 0) > 1) {
|
|
917
935
|
for (const read of compiled.initializationImportReads) {
|
|
918
|
-
const
|
|
936
|
+
const imported = resolveDependency(path, read.source);
|
|
937
|
+
const origin = originModule(imported, read.imported, loaded, resolveDependency);
|
|
938
|
+
const target = origin.module;
|
|
919
939
|
if (target === null || target === path)
|
|
920
940
|
continue;
|
|
921
941
|
if (componentOf.get(target) !== componentOf.get(path))
|
|
@@ -924,13 +944,21 @@ function appendInitializationCycleDiagnostics(modules, loaded, velarImports, ent
|
|
|
924
944
|
// initializes at link time, so a cycle member may call one before the
|
|
925
945
|
// defining module evaluates. Every other export shape is in its
|
|
926
946
|
// temporal dead zone until then.
|
|
927
|
-
|
|
947
|
+
//
|
|
948
|
+
// The exemption is a fact about the *origin* module's own export, so
|
|
949
|
+
// it must be asked with the name that module declares. An aliasing
|
|
950
|
+
// barrel (`export {value as helper}`) renames on the way through, and
|
|
951
|
+
// asking with the import-site alias answered about an unrelated
|
|
952
|
+
// export of the same name: it suppressed a real cycle read whenever
|
|
953
|
+
// the origin happened to have a `def` under the alias, and reported a
|
|
954
|
+
// correct program whenever the origin's `def` was renamed.
|
|
955
|
+
if (origin.name !== null && loaded.get(target)?.inspection.moduleInterface.hoistedExports?.has(origin.name))
|
|
928
956
|
continue;
|
|
929
957
|
const modulePosition = order.get(path);
|
|
930
958
|
const targetPosition = order.get(target);
|
|
931
959
|
if (modulePosition === undefined || targetPosition === undefined || targetPosition < modulePosition)
|
|
932
960
|
continue;
|
|
933
|
-
additions.push(diagnostic(INITIALIZATION_CYCLE_DIAGNOSTIC, `Move this read into a function, or extract the shared value into a third module;
|
|
961
|
+
additions.push(diagnostic(INITIALIZATION_CYCLE_DIAGNOSTIC, `Move this read into a function, or extract the shared value into a third module; ${uninitializedModuleName(read.source, imported, target, loaded)} has not initialized when this line runs`, read.span));
|
|
934
962
|
}
|
|
935
963
|
}
|
|
936
964
|
// MOD-I5: resolution failures overlay the same way, on the import
|
|
@@ -963,7 +991,7 @@ function appendInitializationCycleDiagnostics(modules, loaded, velarImports, ent
|
|
|
963
991
|
...compiled,
|
|
964
992
|
// The compile() contract keeps diagnostics ordered by span.
|
|
965
993
|
diagnostics: [...compiled.diagnostics, ...additions]
|
|
966
|
-
.sort((left, right) => left.span.start - right.span.start || left.code
|
|
994
|
+
.sort((left, right) => left.span.start - right.span.start || byCodeUnit(left.code, right.code)),
|
|
967
995
|
// The zero-diagnostics gate for code generation holds after the
|
|
968
996
|
// project-level check as well.
|
|
969
997
|
code: null,
|
|
@@ -978,9 +1006,11 @@ function appendInitializationCycleDiagnostics(modules, loaded, velarImports, ent
|
|
|
978
1006
|
}
|
|
979
1007
|
/**
|
|
980
1008
|
* The module that declares an imported name, following `export {name} from
|
|
981
|
-
* "source"` barrels
|
|
982
|
-
*
|
|
983
|
-
*
|
|
1009
|
+
* "source"` barrels, together with the name that module declares it under.
|
|
1010
|
+
* Judging a cycle read by the module the import names would let a barrel hide
|
|
1011
|
+
* the defining module, whose binding is the one that is actually
|
|
1012
|
+
* uninitialized at run time; judging it by the import-site alias would ask
|
|
1013
|
+
* the defining module about a name it may not use for this export.
|
|
984
1014
|
*/
|
|
985
1015
|
function originModule(target, imported, loaded, resolveDependency) {
|
|
986
1016
|
let current = target;
|
|
@@ -990,33 +1020,44 @@ function originModule(target, imported, loaded, resolveDependency) {
|
|
|
990
1020
|
seen.add(`${current}\0${name}`);
|
|
991
1021
|
const reExport = loaded.get(current)?.inspection.moduleInterface.reExports.get(name);
|
|
992
1022
|
if (reExport === undefined)
|
|
993
|
-
return current;
|
|
1023
|
+
return { module: current, name };
|
|
994
1024
|
const next = resolveDependency(current, reExport.source);
|
|
995
1025
|
if (next === null)
|
|
996
|
-
return current;
|
|
1026
|
+
return { module: current, name };
|
|
997
1027
|
current = next;
|
|
998
1028
|
name = reExport.imported;
|
|
999
1029
|
}
|
|
1000
|
-
return current;
|
|
1030
|
+
return { module: current, name };
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* The module the author must open. Through a re-export barrel the specifier
|
|
1034
|
+
* written at the import site names a module that has fully initialized, so
|
|
1035
|
+
* naming it alone states something false; name the origin and keep the
|
|
1036
|
+
* specifier as the route to it.
|
|
1037
|
+
*/
|
|
1038
|
+
function uninitializedModuleName(source, imported, origin, loaded) {
|
|
1039
|
+
if (imported === origin)
|
|
1040
|
+
return `'${source}'`;
|
|
1041
|
+
return `'${loaded.get(origin)?.relativePath ?? origin}' (re-exported by '${source}')`;
|
|
1001
1042
|
}
|
|
1002
1043
|
export function moduleInterfaceIdentity(interface_, extensions = []) {
|
|
1003
1044
|
const node = (kind, parts = []) => (`${kind.length}:${kind}${parts.map((part) => `${part.length}:${part}`).join("")}`);
|
|
1004
1045
|
const typeMap = (values) => node("type-map", [...values]
|
|
1005
|
-
.sort(([left], [right]) => left
|
|
1046
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1006
1047
|
.map(([name, type]) => node("type-entry", [name, analysisTypeIdentity(type)])));
|
|
1007
1048
|
const names = (values) => node("names", [...values].sort());
|
|
1008
1049
|
const types = (values) => node("types", values.map(analysisTypeIdentity));
|
|
1009
1050
|
const namedTypes = node("named-types", [...interface_.namedTypes]
|
|
1010
|
-
.sort(([left], [right]) => left
|
|
1051
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1011
1052
|
.map(([name, fields]) => node("named-type", [name, typeMap(fields)])));
|
|
1012
1053
|
const namedTypeReadonlyFields = node("named-type-readonly-fields", [...(interface_.namedTypeReadonlyFields ?? new Map())]
|
|
1013
|
-
.sort(([left], [right]) => left
|
|
1054
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1014
1055
|
.map(([name, fields]) => node("named-type-readonly", [name, names(fields)])));
|
|
1015
1056
|
const namedTypeIdentities = node("named-type-identities", [...interface_.namedTypeIdentities]
|
|
1016
|
-
.sort(([left], [right]) => left
|
|
1057
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1017
1058
|
.map(([name, identity]) => node("named-type-identity", [name, identity])));
|
|
1018
1059
|
const namedTypeBases = node("named-type-bases", [...(interface_.namedTypeBases ?? new Map())]
|
|
1019
|
-
.sort(([left], [right]) => left
|
|
1060
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1020
1061
|
.map(([name, base]) => node("named-type-base", [name, analysisTypeIdentity(base)])));
|
|
1021
1062
|
// D55 rule 120, and batch M's lesson one layer out: a dependent compiled
|
|
1022
1063
|
// against the parameter list, the bounds, *and* the template's field types.
|
|
@@ -1024,7 +1065,7 @@ export function moduleInterfaceIdentity(interface_, extensions = []) {
|
|
|
1024
1065
|
// bound that does not enter this hash is a constraint that silently
|
|
1025
1066
|
// disappears from every module already built against it.
|
|
1026
1067
|
const genericTypes = node("generic-types", [...(interface_.genericTypes ?? new Map())]
|
|
1027
|
-
.sort(([left], [right]) => left
|
|
1068
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1028
1069
|
.map(([name, info]) => node("generic-type", [
|
|
1029
1070
|
name,
|
|
1030
1071
|
info.identity,
|
|
@@ -1034,10 +1075,10 @@ export function moduleInterfaceIdentity(interface_, extensions = []) {
|
|
|
1034
1075
|
names(info.readonlyFields ?? new Set()),
|
|
1035
1076
|
])));
|
|
1036
1077
|
const enums = node("enums", [...interface_.enums]
|
|
1037
|
-
.sort(([left], [right]) => left
|
|
1078
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1038
1079
|
.map(([name, info]) => node("enum", [name, info.identity, names(info.members)])));
|
|
1039
1080
|
const classes = node("classes", [...interface_.classes]
|
|
1040
|
-
.sort(([left], [right]) => left
|
|
1081
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1041
1082
|
.map(([name, info]) => node("class", [
|
|
1042
1083
|
name,
|
|
1043
1084
|
info.identity ?? "",
|
|
@@ -1075,14 +1116,14 @@ export function moduleInterfaceIdentity(interface_, extensions = []) {
|
|
|
1075
1116
|
return `${value.length}:${value}`;
|
|
1076
1117
|
};
|
|
1077
1118
|
const extensionExports = node("extension-exports", [...interface_.extensionExports]
|
|
1078
|
-
.sort(([left], [right]) => left
|
|
1119
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1079
1120
|
.map(([extensionId, values]) => {
|
|
1080
1121
|
const identify = extensionOwners.get(extensionId)?.inspection?.interfaceExportIdentity;
|
|
1081
1122
|
if (!identify) {
|
|
1082
1123
|
throw new Error(`Compiler extension '${extensionId}' exports cross-module interface data without an interfaceExportIdentity contract`);
|
|
1083
1124
|
}
|
|
1084
1125
|
const entries = [...values]
|
|
1085
|
-
.sort(([left], [right]) => left
|
|
1126
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1086
1127
|
.map(([name, value]) => {
|
|
1087
1128
|
const identity = identify(name, value);
|
|
1088
1129
|
if (typeof identity !== "string" || identity.length > 1024 * 1024) {
|
|
@@ -1104,10 +1145,10 @@ export function moduleInterfaceIdentity(interface_, extensions = []) {
|
|
|
1104
1145
|
enums,
|
|
1105
1146
|
classes,
|
|
1106
1147
|
node("reactive", [...interface_.reactiveExports]
|
|
1107
|
-
.sort(([left], [right]) => left
|
|
1148
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1108
1149
|
.map(([name, kind]) => node("reactive-entry", [name, kind]))),
|
|
1109
1150
|
node("re-exports", [...interface_.reExports]
|
|
1110
|
-
.sort(([left], [right]) => left
|
|
1151
|
+
.sort(([left], [right]) => byCodeUnit(left, right))
|
|
1111
1152
|
.map(([name, target]) => node("re-export", [name, target.source, target.imported]))),
|
|
1112
1153
|
node("tests", interface_.tests.map((item) => `${item.name}\u0000${item.title}`).sort()),
|
|
1113
1154
|
extensionExports,
|
|
@@ -1155,6 +1196,7 @@ async function createAnalysisContext(module, loaded, velarImports, failures, not
|
|
|
1155
1196
|
readonlyFields: new Set(interface_.exports.keys()),
|
|
1156
1197
|
});
|
|
1157
1198
|
importHiddenTypeMetadata(interface_, namedTypes, namedTypeReadonlyFields, namedTypeBases, genericTypes, enums, classes);
|
|
1199
|
+
importReachableStandardTypeMetadata(interface_, compilerExtensions, namedTypes, namedTypeReadonlyFields, namedTypeBases, genericTypes, enums, classes);
|
|
1158
1200
|
continue;
|
|
1159
1201
|
}
|
|
1160
1202
|
if (dependency.reExport) {
|
|
@@ -1229,6 +1271,7 @@ async function createAnalysisContext(module, loaded, velarImports, failures, not
|
|
|
1229
1271
|
const standard = standardModuleInterface(dependency.source, compilerExtensions);
|
|
1230
1272
|
if (standard) {
|
|
1231
1273
|
importInterface(module, dependency, standard, imports, reactiveImports, namedTypes, namedTypeReadonlyFields, namedTypeIdentities, namedTypeBases, genericTypes, typeAliases, enums, classes, extensionImports, failures);
|
|
1274
|
+
importReachableStandardTypeMetadata(standard, compilerExtensions, namedTypes, namedTypeReadonlyFields, namedTypeBases, genericTypes, enums, classes);
|
|
1232
1275
|
continue;
|
|
1233
1276
|
}
|
|
1234
1277
|
const targetPath = dependency.source.startsWith(".") && extname(dependency.source) === ".vel"
|
|
@@ -1239,7 +1282,11 @@ async function createAnalysisContext(module, loaded, velarImports, failures, not
|
|
|
1239
1282
|
const target = loaded.get(targetPath);
|
|
1240
1283
|
if (!target)
|
|
1241
1284
|
continue;
|
|
1242
|
-
|
|
1285
|
+
const targetInterface = resolvedModuleInterface(target, loaded, velarImports, interfaceCache, compiledInterfaces, compilerExtensions);
|
|
1286
|
+
importInterface(module, dependency, targetInterface, imports, reactiveImports, namedTypes, namedTypeReadonlyFields, namedTypeIdentities, namedTypeBases, genericTypes, typeAliases, enums, classes, extensionImports, failures);
|
|
1287
|
+
// The same sink one step sideways: a project module can re-export a
|
|
1288
|
+
// signature returning a standard type it never declares either.
|
|
1289
|
+
importReachableStandardTypeMetadata(targetInterface, compilerExtensions, namedTypes, namedTypeReadonlyFields, namedTypeBases, genericTypes, enums, classes);
|
|
1243
1290
|
}
|
|
1244
1291
|
return {
|
|
1245
1292
|
imports,
|
|
@@ -1464,7 +1511,9 @@ async function velarPackageAtRoot(name, root) {
|
|
|
1464
1511
|
if (extname(entryPath) !== ".vel")
|
|
1465
1512
|
throw new Error("'velar.entry' must point to a .vel source file");
|
|
1466
1513
|
const targets = packageTargets(manifest.velar?.targets);
|
|
1467
|
-
const
|
|
1514
|
+
const requires = packageRequiresFields(manifest.velar?.requires);
|
|
1515
|
+
const requiredCapabilities = packageRequiredCapabilities(requires);
|
|
1516
|
+
const requiredLanguage = packageRequiredLanguage(requires);
|
|
1468
1517
|
return {
|
|
1469
1518
|
name,
|
|
1470
1519
|
root,
|
|
@@ -1472,6 +1521,7 @@ async function velarPackageAtRoot(name, root) {
|
|
|
1472
1521
|
resources: packageResources(name, root, manifest.velar.resources, manifest.exports),
|
|
1473
1522
|
targets,
|
|
1474
1523
|
requiredCapabilities,
|
|
1524
|
+
requiredLanguage,
|
|
1475
1525
|
};
|
|
1476
1526
|
}
|
|
1477
1527
|
const velarPackageTargets = new Set(["core", "node", "web", "desktop"]);
|
|
@@ -1490,14 +1540,29 @@ function packageTargets(value) {
|
|
|
1490
1540
|
}
|
|
1491
1541
|
return targets;
|
|
1492
1542
|
}
|
|
1493
|
-
|
|
1543
|
+
/**
|
|
1544
|
+
* D90 R13 asks the 'velar' section for an optional language generation. It is
|
|
1545
|
+
* spelled 'velar.requires.language' because 'velar.requires' is already the
|
|
1546
|
+
* package's "what I need from the toolchain" block: the language generation is
|
|
1547
|
+
* one more thing it needs, and it belongs next to 'capabilities' rather than
|
|
1548
|
+
* beside 'entry' and 'targets', which describe what the package *is*.
|
|
1549
|
+
*
|
|
1550
|
+
* The section is validated once, here, so that the readers below take an object
|
|
1551
|
+
* this function has already proved rather than an `unknown` each of them would
|
|
1552
|
+
* have to re-check.
|
|
1553
|
+
*/
|
|
1554
|
+
function packageRequiresFields(value) {
|
|
1494
1555
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
1495
1556
|
throw new Error("'velar.requires' must be an object");
|
|
1496
1557
|
}
|
|
1497
1558
|
const fields = value;
|
|
1498
|
-
const unknown = Object.keys(fields).filter((field) => field !== "capabilities");
|
|
1499
|
-
if (unknown.length > 0)
|
|
1500
|
-
throw new Error(`'velar.requires' has unknown field '${unknown[0]}'`);
|
|
1559
|
+
const unknown = Object.keys(fields).filter((field) => field !== "capabilities" && field !== "language");
|
|
1560
|
+
if (unknown.length > 0) {
|
|
1561
|
+
throw new Error(`'velar.requires' has unknown field '${unknown[0]}'; the supported fields are 'capabilities' and 'language'`);
|
|
1562
|
+
}
|
|
1563
|
+
return fields;
|
|
1564
|
+
}
|
|
1565
|
+
function packageRequiredCapabilities(fields) {
|
|
1501
1566
|
const capabilities = fields.capabilities;
|
|
1502
1567
|
if (!Array.isArray(capabilities) || capabilities.length > 16) {
|
|
1503
1568
|
throw new Error("'velar.requires.capabilities' must be a list with at most 16 entries");
|
|
@@ -1513,7 +1578,103 @@ function packageRequiredCapabilities(value) {
|
|
|
1513
1578
|
}
|
|
1514
1579
|
return required;
|
|
1515
1580
|
}
|
|
1581
|
+
/**
|
|
1582
|
+
* D90 R13: the language generation this toolchain implements is VELAR_VERSION
|
|
1583
|
+
* without its patch component — a patch release never moves the language.
|
|
1584
|
+
*/
|
|
1585
|
+
const TOOLCHAIN_LANGUAGE_GENERATION = VELAR_VERSION.split(".").slice(0, 2).join(".");
|
|
1586
|
+
const languageGenerationPattern = /^(0|[1-9][0-9]{0,3})\.(0|[1-9][0-9]{0,3})$/u;
|
|
1587
|
+
function parseLanguageGeneration(text) {
|
|
1588
|
+
const match = languageGenerationPattern.exec(text);
|
|
1589
|
+
if (match === null)
|
|
1590
|
+
return null;
|
|
1591
|
+
return { major: Number(match[1]), minor: Number(match[2]) };
|
|
1592
|
+
}
|
|
1593
|
+
function compareLanguageGenerations(left, right) {
|
|
1594
|
+
return left.major !== right.major ? left.major - right.major : left.minor - right.minor;
|
|
1595
|
+
}
|
|
1596
|
+
/**
|
|
1597
|
+
* D90 R13: reads the optional 'velar.requires.language' range. The grammar is
|
|
1598
|
+
* language-owned and deliberately small — one or two whitespace-separated
|
|
1599
|
+
* clauses over `<major>.<minor>`, because a package declares the *generation*
|
|
1600
|
+
* it was written against and a patch component would promise something the
|
|
1601
|
+
* language does not track.
|
|
1602
|
+
*/
|
|
1603
|
+
function packageRequiredLanguage(fields) {
|
|
1604
|
+
const declared = fields.language;
|
|
1605
|
+
if (declared === undefined)
|
|
1606
|
+
return null;
|
|
1607
|
+
const malformed = new Error("'velar.requires.language' must be a language generation such as '0.12' or a range such as '>=0.11 <0.14'");
|
|
1608
|
+
if (typeof declared !== "string")
|
|
1609
|
+
throw malformed;
|
|
1610
|
+
// The clauses carry the meaning; the whitespace between them does not. A
|
|
1611
|
+
// manifest is hand-edited JSON, and an invisible trailing space is not a
|
|
1612
|
+
// reason to tell an author that '0.12 ' is not a generation.
|
|
1613
|
+
const text = declared.trim().split(/\s+/u).join(" ");
|
|
1614
|
+
const clauses = text.split(" ");
|
|
1615
|
+
if (clauses.length > 2)
|
|
1616
|
+
throw malformed;
|
|
1617
|
+
let lower = null;
|
|
1618
|
+
let upper = null;
|
|
1619
|
+
for (const clause of clauses) {
|
|
1620
|
+
const operator = /^(>=|<=|>|<)/u.exec(clause)?.[0] ?? "";
|
|
1621
|
+
const generation = parseLanguageGeneration(clause.slice(operator.length));
|
|
1622
|
+
if (generation === null)
|
|
1623
|
+
throw malformed;
|
|
1624
|
+
if (operator === ">=" || operator === ">") {
|
|
1625
|
+
if (lower !== null)
|
|
1626
|
+
throw malformed;
|
|
1627
|
+
lower = { generation, inclusive: operator === ">=" };
|
|
1628
|
+
}
|
|
1629
|
+
else if (operator === "<=" || operator === "<") {
|
|
1630
|
+
if (upper !== null)
|
|
1631
|
+
throw malformed;
|
|
1632
|
+
upper = { generation, inclusive: operator === "<=" };
|
|
1633
|
+
}
|
|
1634
|
+
else {
|
|
1635
|
+
// A bare generation is exactly that generation — it is both bounds at
|
|
1636
|
+
// once, so it never combines with another clause.
|
|
1637
|
+
if (clauses.length !== 1)
|
|
1638
|
+
throw malformed;
|
|
1639
|
+
lower = { generation, inclusive: true };
|
|
1640
|
+
upper = { generation, inclusive: true };
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
if (lower !== null && upper !== null) {
|
|
1644
|
+
// A range that admits no generation at all is a typo, not a requirement.
|
|
1645
|
+
const order = compareLanguageGenerations(lower.generation, upper.generation);
|
|
1646
|
+
if (order > 0 || (order === 0 && !(lower.inclusive && upper.inclusive)))
|
|
1647
|
+
throw malformed;
|
|
1648
|
+
}
|
|
1649
|
+
return { text, lower, upper };
|
|
1650
|
+
}
|
|
1651
|
+
function languageRangeAdmits(range, generation) {
|
|
1652
|
+
if (range.lower !== null) {
|
|
1653
|
+
const order = compareLanguageGenerations(generation, range.lower.generation);
|
|
1654
|
+
if (order < 0 || (order === 0 && !range.lower.inclusive))
|
|
1655
|
+
return false;
|
|
1656
|
+
}
|
|
1657
|
+
if (range.upper !== null) {
|
|
1658
|
+
const order = compareLanguageGenerations(generation, range.upper.generation);
|
|
1659
|
+
if (order > 0 || (order === 0 && !range.upper.inclusive))
|
|
1660
|
+
return false;
|
|
1661
|
+
}
|
|
1662
|
+
return true;
|
|
1663
|
+
}
|
|
1516
1664
|
function assertVelarPackageCompatibility(package_, target, capabilities) {
|
|
1665
|
+
// D90 R13: the generation comes first. A package written for another
|
|
1666
|
+
// generation of the language is not a package whose target list and
|
|
1667
|
+
// capability list can be trusted, and "it belongs to the previous language"
|
|
1668
|
+
// is the more useful thing for its author to hear.
|
|
1669
|
+
const declaredLanguage = package_.requiredLanguage;
|
|
1670
|
+
if (declaredLanguage !== null) {
|
|
1671
|
+
const current = parseLanguageGeneration(TOOLCHAIN_LANGUAGE_GENERATION);
|
|
1672
|
+
if (current === null)
|
|
1673
|
+
throw new Error(`VelarScript toolchain version '${VELAR_VERSION}' is not a language generation`);
|
|
1674
|
+
if (!languageRangeAdmits(declaredLanguage, current)) {
|
|
1675
|
+
throw new Error(`package '${package_.name}' requires VelarScript language ${declaredLanguage.text}; this toolchain implements ${TOOLCHAIN_LANGUAGE_GENERATION}; install a release of '${package_.name}' published for ${TOOLCHAIN_LANGUAGE_GENERATION}, or run the toolchain the package asks for — its sources are not wrong, they belong to another generation of the language`);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1517
1678
|
if (!package_.targets.includes(target)) {
|
|
1518
1679
|
throw new Error(`package '${package_.name}' does not support the '${target}' target; supported targets: ${package_.targets.join(", ")}`);
|
|
1519
1680
|
}
|
|
@@ -1541,8 +1702,9 @@ function packageResources(name, root, value, exports) {
|
|
|
1541
1702
|
}
|
|
1542
1703
|
const fields = declaration;
|
|
1543
1704
|
const unknown = Object.keys(fields).filter((field) => field !== "path" && field !== "type");
|
|
1544
|
-
if (unknown.length > 0)
|
|
1545
|
-
throw new Error(`'velar.resources.${subpath}' has unknown field '${unknown[0]}'`);
|
|
1705
|
+
if (unknown.length > 0) {
|
|
1706
|
+
throw new Error(`'velar.resources.${subpath}' has unknown field '${unknown[0]}'; the supported fields are 'path' and 'type'`);
|
|
1707
|
+
}
|
|
1546
1708
|
if (fields.type !== "json")
|
|
1547
1709
|
throw new Error(`'velar.resources.${subpath}.type' must be 'json'`);
|
|
1548
1710
|
if (typeof fields.path !== "string" || fields.path === "" || isAbsolute(fields.path)
|
|
@@ -1724,6 +1886,143 @@ function importHiddenTypeMetadata(interface_, namedTypes, namedTypeReadonlyField
|
|
|
1724
1886
|
classes.set(info.identity, info);
|
|
1725
1887
|
}
|
|
1726
1888
|
}
|
|
1889
|
+
/** The type identities a value type mentions, at any depth. */
|
|
1890
|
+
function collectTypeIdentities(type, into) {
|
|
1891
|
+
switch (type.kind) {
|
|
1892
|
+
case "named":
|
|
1893
|
+
if (type.identity)
|
|
1894
|
+
into.add(type.identity);
|
|
1895
|
+
if (type.application) {
|
|
1896
|
+
into.add(type.application.declaration);
|
|
1897
|
+
for (const argument of type.application.arguments)
|
|
1898
|
+
collectTypeIdentities(argument, into);
|
|
1899
|
+
}
|
|
1900
|
+
return;
|
|
1901
|
+
case "class":
|
|
1902
|
+
case "classConstructor":
|
|
1903
|
+
case "enum":
|
|
1904
|
+
case "enumMember":
|
|
1905
|
+
case "enumObject":
|
|
1906
|
+
if (type.identity)
|
|
1907
|
+
into.add(type.identity);
|
|
1908
|
+
return;
|
|
1909
|
+
case "typeObject":
|
|
1910
|
+
if (type.value)
|
|
1911
|
+
collectTypeIdentities(type.value, into);
|
|
1912
|
+
return;
|
|
1913
|
+
case "optional":
|
|
1914
|
+
collectTypeIdentities(type.inner, into);
|
|
1915
|
+
return;
|
|
1916
|
+
case "list":
|
|
1917
|
+
case "set":
|
|
1918
|
+
collectTypeIdentities(type.element, into);
|
|
1919
|
+
return;
|
|
1920
|
+
case "map":
|
|
1921
|
+
collectTypeIdentities(type.key, into);
|
|
1922
|
+
collectTypeIdentities(type.value, into);
|
|
1923
|
+
return;
|
|
1924
|
+
case "record":
|
|
1925
|
+
case "promise":
|
|
1926
|
+
case "runtimeType":
|
|
1927
|
+
collectTypeIdentities(type.value, into);
|
|
1928
|
+
return;
|
|
1929
|
+
case "object":
|
|
1930
|
+
for (const field of type.fields.values())
|
|
1931
|
+
collectTypeIdentities(field, into);
|
|
1932
|
+
return;
|
|
1933
|
+
case "function":
|
|
1934
|
+
case "action":
|
|
1935
|
+
case "intrinsic":
|
|
1936
|
+
for (const parameter of type.parameters)
|
|
1937
|
+
collectTypeIdentities(parameter, into);
|
|
1938
|
+
if (type.rest)
|
|
1939
|
+
collectTypeIdentities(type.rest, into);
|
|
1940
|
+
collectTypeIdentities(type.result, into);
|
|
1941
|
+
return;
|
|
1942
|
+
case "extension":
|
|
1943
|
+
for (const property of type.properties.values())
|
|
1944
|
+
collectTypeIdentities(property, into);
|
|
1945
|
+
for (const argument of type.arguments)
|
|
1946
|
+
collectTypeIdentities(argument, into);
|
|
1947
|
+
return;
|
|
1948
|
+
case "union":
|
|
1949
|
+
for (const member of type.members)
|
|
1950
|
+
collectTypeIdentities(member, into);
|
|
1951
|
+
return;
|
|
1952
|
+
default:
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
const standardTypeOwnerIndexes = new WeakMap();
|
|
1956
|
+
/** Which standard module declares each standard type identity. */
|
|
1957
|
+
function standardTypeOwners(extensions) {
|
|
1958
|
+
const cached = standardTypeOwnerIndexes.get(extensions);
|
|
1959
|
+
if (cached)
|
|
1960
|
+
return cached;
|
|
1961
|
+
const owners = new Map();
|
|
1962
|
+
for (const interface_ of standardModuleInterfaces(extensions).values()) {
|
|
1963
|
+
for (const identity of interface_.namedTypeIdentities.values())
|
|
1964
|
+
if (!owners.has(identity))
|
|
1965
|
+
owners.set(identity, interface_);
|
|
1966
|
+
for (const info of interface_.genericTypes?.values() ?? [])
|
|
1967
|
+
if (!owners.has(info.identity))
|
|
1968
|
+
owners.set(info.identity, interface_);
|
|
1969
|
+
for (const info of interface_.enums.values())
|
|
1970
|
+
if (!owners.has(info.identity))
|
|
1971
|
+
owners.set(info.identity, interface_);
|
|
1972
|
+
for (const info of interface_.classes.values())
|
|
1973
|
+
if (info.identity && !owners.has(info.identity))
|
|
1974
|
+
owners.set(info.identity, interface_);
|
|
1975
|
+
}
|
|
1976
|
+
standardTypeOwnerIndexes.set(extensions, owners);
|
|
1977
|
+
return owners;
|
|
1978
|
+
}
|
|
1979
|
+
/**
|
|
1980
|
+
* A standard module's signatures routinely hand back a type another standard
|
|
1981
|
+
* module declares — `velar/fs`'s `readBytes` returns a `Bytes` owned by
|
|
1982
|
+
* `velar/binary`, `velar/serve`'s `Request.cancellation` is a `Cancellation`
|
|
1983
|
+
* owned by `velar/task`. The field table for such a type travels with its
|
|
1984
|
+
* declaring module, so importing only the module the author wrote left the
|
|
1985
|
+
* analyzer holding a named type it knew no members of, and it reported the
|
|
1986
|
+
* false fact that the type has no such field; adding an otherwise unused
|
|
1987
|
+
* import of the declaring module was the only way to make correct code
|
|
1988
|
+
* compile. Import the hidden metadata of every standard module reachable
|
|
1989
|
+
* through the imported module's own declared signatures instead.
|
|
1990
|
+
*
|
|
1991
|
+
* Only identity-keyed metadata travels, so nothing is bound to a local name
|
|
1992
|
+
* the author did not write — `Bytes` gains its members, and stays unspellable
|
|
1993
|
+
* until `velar/binary` is imported for real.
|
|
1994
|
+
*/
|
|
1995
|
+
function importReachableStandardTypeMetadata(interface_, extensions, namedTypes, namedTypeReadonlyFields, namedTypeBases, genericTypes, enums, classes) {
|
|
1996
|
+
const owners = standardTypeOwners(extensions);
|
|
1997
|
+
if (owners.size === 0)
|
|
1998
|
+
return;
|
|
1999
|
+
const reached = new Set();
|
|
2000
|
+
const seed = (source) => {
|
|
2001
|
+
for (const type of source.exports.values())
|
|
2002
|
+
collectTypeIdentities(type, reached);
|
|
2003
|
+
for (const fields of source.namedTypes.values())
|
|
2004
|
+
for (const type of fields.values())
|
|
2005
|
+
collectTypeIdentities(type, reached);
|
|
2006
|
+
for (const base of source.namedTypeBases?.values() ?? [])
|
|
2007
|
+
collectTypeIdentities(base, reached);
|
|
2008
|
+
for (const info of source.genericTypes?.values() ?? [])
|
|
2009
|
+
for (const type of info.fields.values())
|
|
2010
|
+
collectTypeIdentities(type, reached);
|
|
2011
|
+
};
|
|
2012
|
+
seed(interface_);
|
|
2013
|
+
const visited = new Set([interface_]);
|
|
2014
|
+
// Transitive: a reachable type's own fields may name a third module's type.
|
|
2015
|
+
// A Set iterator visits entries added while it runs, and each owner is
|
|
2016
|
+
// seeded at most once, so this terminates at the number of standard modules.
|
|
2017
|
+
for (const identity of reached) {
|
|
2018
|
+
const owner = owners.get(identity);
|
|
2019
|
+
if (!owner || visited.has(owner))
|
|
2020
|
+
continue;
|
|
2021
|
+
visited.add(owner);
|
|
2022
|
+
importHiddenTypeMetadata(owner, namedTypes, namedTypeReadonlyFields, namedTypeBases, genericTypes, enums, classes);
|
|
2023
|
+
seed(owner);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
1727
2026
|
function importInterface(module, dependency, interface_, imports, reactiveImports, namedTypes, namedTypeReadonlyFields, namedTypeIdentities, namedTypeBases, genericTypes, typeAliases, enums, classes, extensionImports, failures) {
|
|
1728
2027
|
const aliases = new Map(dependency.specifiers
|
|
1729
2028
|
.filter((specifier) => !specifier.namespace && specifier.imported !== "default")
|