@telorun/analyzer 0.70.0 → 0.71.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/analysis-registry.d.ts.map +1 -1
- package/dist/analysis-registry.js +4 -5
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +50 -8
- package/dist/call-graph.d.ts.map +1 -1
- package/dist/call-graph.js +10 -4
- package/dist/cel-scope-query.d.ts +14 -0
- package/dist/cel-scope-query.d.ts.map +1 -1
- package/dist/cel-scope-query.js +36 -6
- package/dist/definition-registry.d.ts.map +1 -1
- package/dist/definition-registry.js +3 -4
- package/dist/flatten-for-analyzer.d.ts +2 -2
- package/dist/flatten-for-analyzer.d.ts.map +1 -1
- package/dist/flatten-for-analyzer.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/manifest-visitor.d.ts.map +1 -1
- package/dist/manifest-visitor.js +11 -3
- package/dist/module-alias-scope.d.ts +65 -0
- package/dist/module-alias-scope.d.ts.map +1 -0
- package/dist/module-alias-scope.js +25 -0
- package/dist/{zone-module-documents.d.ts → module-documents.d.ts} +11 -7
- package/dist/module-documents.d.ts.map +1 -0
- package/dist/ref-sentinel-target.d.ts +38 -0
- package/dist/ref-sentinel-target.d.ts.map +1 -0
- package/dist/ref-sentinel-target.js +13 -0
- package/dist/resolve-schema-type-refs.d.ts.map +1 -1
- package/dist/resolve-schema-type-refs.js +2 -1
- package/dist/resolve-throws-union.d.ts +18 -1
- package/dist/resolve-throws-union.d.ts.map +1 -1
- package/dist/resolve-throws-union.js +93 -9
- package/dist/resolve-zone-requirements.d.ts +3 -3
- package/dist/resolve-zone-requirements.d.ts.map +1 -1
- package/dist/resolve-zone-requirements.js +12 -12
- package/dist/telo-version.d.ts +1 -1
- package/dist/telo-version.js +1 -1
- package/dist/template-body.d.ts.map +1 -1
- package/dist/template-body.js +2 -4
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/validate-invocation-contract.d.ts +5 -0
- package/dist/validate-invocation-contract.d.ts.map +1 -1
- package/dist/validate-invocation-contract.js +114 -3
- package/dist/validate-logging.d.ts.map +1 -1
- package/dist/validate-logging.js +2 -2
- package/dist/validate-references.d.ts +16 -5
- package/dist/validate-references.d.ts.map +1 -1
- package/dist/validate-references.js +30 -12
- package/dist/validate-resource-inputs.d.ts +1 -26
- package/dist/validate-resource-inputs.d.ts.map +1 -1
- package/dist/validate-resource-inputs.js +12 -2
- package/dist/validate-schema-type-refs.d.ts.map +1 -1
- package/dist/validate-schema-type-refs.js +2 -1
- package/dist/validate-throws-coverage.d.ts +5 -1
- package/dist/validate-throws-coverage.d.ts.map +1 -1
- package/dist/validate-throws-coverage.js +6 -2
- package/package.json +2 -2
- package/src/analysis-registry.ts +4 -5
- package/src/analyzer.ts +61 -10
- package/src/call-graph.ts +9 -3
- package/src/cel-scope-query.ts +45 -8
- package/src/definition-registry.ts +3 -6
- package/src/flatten-for-analyzer.ts +3 -3
- package/src/index.ts +2 -2
- package/src/manifest-visitor.ts +11 -3
- package/src/module-alias-scope.ts +94 -0
- package/src/{zone-module-documents.ts → module-documents.ts} +10 -6
- package/src/ref-sentinel-target.ts +46 -0
- package/src/resolve-schema-type-refs.ts +2 -1
- package/src/resolve-throws-union.ts +123 -8
- package/src/resolve-zone-requirements.ts +14 -14
- package/src/telo-version.ts +1 -1
- package/src/template-body.ts +2 -5
- package/src/types.ts +3 -3
- package/src/validate-invocation-contract.ts +128 -2
- package/src/validate-logging.ts +2 -3
- package/src/validate-references.ts +41 -11
- package/src/validate-resource-inputs.ts +26 -3
- package/src/validate-schema-type-refs.ts +2 -1
- package/src/validate-throws-coverage.ts +12 -1
- package/dist/zone-module-documents.d.ts.map +0 -1
- /package/dist/{zone-module-documents.js → module-documents.js} +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { AliasResolver, type ModuleScopes } from "./alias-resolver.js";
|
|
2
|
+
/**
|
|
3
|
+
* WHICH ALIAS TABLE A MANIFEST'S OWN NAMES ARE WRITTEN IN.
|
|
4
|
+
*
|
|
5
|
+
* An application analysis is flattened, so an imported library's definitions and
|
|
6
|
+
* exported instances are checked in the CONSUMER's pass. But every alias-qualified
|
|
7
|
+
* name on such a manifest — its `kind:`, its `extends:`, an `x-telo-schema-from`
|
|
8
|
+
* anchor — was written against the alias map of the module that DECLARED it. A
|
|
9
|
+
* library writes `kind: Http.Api` through an import the consumer has no reason to
|
|
10
|
+
* have, so resolving it through the entry's table finds nothing, and everything
|
|
11
|
+
* derived from the definition silently goes missing: the field map (Phase-5
|
|
12
|
+
* injection blind to a forwarded resource's ref slots) and the `x-telo-context`
|
|
13
|
+
* regions (`request` / `result` reported as unknown identifiers on a file the
|
|
14
|
+
* consumer cannot edit).
|
|
15
|
+
*
|
|
16
|
+
* **There are TWO fallbacks, not one, and this file is where they are told
|
|
17
|
+
* apart** — that is the whole reason they live together. They agree on every
|
|
18
|
+
* module that has a table, and differ on a non-root module that has none:
|
|
19
|
+
*
|
|
20
|
+
* - {@link moduleAliasScope} falls back to the GLOBAL table. For a question
|
|
21
|
+
* asked about an arbitrary manifest, where a missing entry means "this is the
|
|
22
|
+
* entry's own", which is what the global table answers correctly.
|
|
23
|
+
* - {@link declaringModuleScope} falls back to an EMPTY table for a non-root
|
|
24
|
+
* module. For canonicalizing what a library DECLARED, where resolving its
|
|
25
|
+
* `Http.Api` through the consumer's imports would silently bind a library's
|
|
26
|
+
* kind to whatever the app happens to import under that alias — a wrong
|
|
27
|
+
* answer, which is worse than none.
|
|
28
|
+
*
|
|
29
|
+
* Both rest on one invariant neither states inline: **a root module is never a
|
|
30
|
+
* key in `aliasesByModule`** — a root's imports are registered into the global
|
|
31
|
+
* table instead (see the `rootModules` guards in `analyze()`) — so for a
|
|
32
|
+
* consumer-owned manifest the two rules coincide and neither fallback is a
|
|
33
|
+
* degradation.
|
|
34
|
+
*
|
|
35
|
+
* Every READ of the rule goes through one of these two. What legitimately does
|
|
36
|
+
* not, and why, so the next reader does not have to re-derive it: the three
|
|
37
|
+
* sites in `analyze()` that POPULATE `aliasesByModule` (a write, not a lookup),
|
|
38
|
+
* and `resolve-ref-sentinels`, whose module is known non-root by construction and
|
|
39
|
+
* whose fallback is the raw kind rather than another table — a different rule
|
|
40
|
+
* that happens to read the same map.
|
|
41
|
+
*/
|
|
42
|
+
export declare function moduleAliasScope<A extends KindResolver, M extends KindResolver>(metadata: {
|
|
43
|
+
module?: unknown;
|
|
44
|
+
} | undefined, aliases: A, aliasesByModule: ReadonlyMap<string, M> | undefined): A | M;
|
|
45
|
+
export declare function moduleAliasScope<A extends KindResolver, M extends KindResolver>(metadata: {
|
|
46
|
+
module?: unknown;
|
|
47
|
+
} | undefined, aliases: A | undefined, aliasesByModule: ReadonlyMap<string, M> | undefined): A | M | undefined;
|
|
48
|
+
/** All this rule needs of a resolver, and deliberately all it asks for:
|
|
49
|
+
* `ModuleScopes` already types its map this way so a caller can hand over a
|
|
50
|
+
* lighter table, and requiring the full `AliasResolver` here would have made
|
|
51
|
+
* the one site that does (a template body) reach for a cast. */
|
|
52
|
+
interface KindResolver {
|
|
53
|
+
resolveKind(kind: string): string | undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The scope a DECLARING module's own alias-form names are canonicalized in — the
|
|
57
|
+
* root-aware half of the rule above, and the one that must never fall through to
|
|
58
|
+
* the consumer's table. See this file's header for why the two differ.
|
|
59
|
+
*/
|
|
60
|
+
export declare function declaringModuleScope(ownModule: string | undefined, aliases: AliasResolver, scopes: {
|
|
61
|
+
aliasesByModule: Map<string, AliasResolver>;
|
|
62
|
+
rootModules: Set<string>;
|
|
63
|
+
}): AliasResolver;
|
|
64
|
+
export type { ModuleScopes };
|
|
65
|
+
//# sourceMappingURL=module-alias-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-alias-scope.d.ts","sourceRoot":"","sources":["../src/module-alias-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA0B,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE/F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,YAAY,EAC7E,QAAQ,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EAC1C,OAAO,EAAE,CAAC,EACV,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GAClD,CAAC,GAAG,CAAC,CAAC;AACT,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,YAAY,EAC7E,QAAQ,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EAC1C,OAAO,EAAE,CAAC,GAAG,SAAS,EACtB,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GAClD,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;AAWrB;;;iEAGiE;AACjE,UAAU,YAAY;IACpB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC/C;AAQD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE;IAAE,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,GAChF,aAAa,CAMf;AAED,YAAY,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AliasResolver, scopeResolverForModule } from "./alias-resolver.js";
|
|
2
|
+
export function moduleAliasScope(metadata, aliases, aliasesByModule) {
|
|
3
|
+
const declaringModule = metadata?.module;
|
|
4
|
+
if (typeof declaringModule !== "string")
|
|
5
|
+
return aliases;
|
|
6
|
+
return aliasesByModule?.get(declaringModule) ?? aliases;
|
|
7
|
+
}
|
|
8
|
+
/** An empty table, shared: a non-root module with no aliases of its own resolves
|
|
9
|
+
* nothing rather than resolving through the consumer's. One instance because it
|
|
10
|
+
* is immutable in use and allocating one per call put a resolver on a per-schema
|
|
11
|
+
* loop. */
|
|
12
|
+
const NO_ALIASES = new AliasResolver();
|
|
13
|
+
/**
|
|
14
|
+
* The scope a DECLARING module's own alias-form names are canonicalized in — the
|
|
15
|
+
* root-aware half of the rule above, and the one that must never fall through to
|
|
16
|
+
* the consumer's table. See this file's header for why the two differ.
|
|
17
|
+
*/
|
|
18
|
+
export function declaringModuleScope(ownModule, aliases, scopes) {
|
|
19
|
+
const own = scopeResolverForModule(ownModule, scopes.rootModules, scopes.aliasesByModule);
|
|
20
|
+
if (own)
|
|
21
|
+
return own;
|
|
22
|
+
// Root (or unknown-and-therefore-treated-as-root): the global table IS its
|
|
23
|
+
// import map. A non-root module with no table of its own resolves nothing.
|
|
24
|
+
return ownModule && !scopes.rootModules.has(ownModule) ? NO_ALIASES : aliases;
|
|
25
|
+
}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import type { ResourceManifest } from "@telorun/sdk";
|
|
2
2
|
/**
|
|
3
|
-
* One imported library's FULL document set
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* One imported library's FULL document set — what the flattened analysis view
|
|
4
|
+
* no longer holds, since it forwards only each library's export surface and
|
|
5
|
+
* never its internal dispatch chain.
|
|
6
|
+
*
|
|
7
|
+
* Named for what it CARRIES rather than for who asked first: the zone stage's
|
|
8
|
+
* per-library export derivation was the original consumer, and the throws walk
|
|
9
|
+
* is the second — a third should not have to import "zone" to ask about
|
|
10
|
+
* something else again.
|
|
7
11
|
*
|
|
8
12
|
* Plain data in a module of its own, deliberately. It is produced by the
|
|
9
|
-
* loading side (`
|
|
13
|
+
* loading side (`collectModuleDocuments`), named in `AnalysisOptions`, and
|
|
10
14
|
* consumed by the projection; putting it in any of the three would make the
|
|
11
15
|
* other two import that one, and `types.ts` ↔ the projection is a genuine
|
|
12
16
|
* cycle. A leaf module with no imports of its own breaks it without an inline
|
|
13
17
|
* `import(...)` type expression standing in for the dependency nobody wanted.
|
|
14
18
|
*/
|
|
15
|
-
export interface
|
|
19
|
+
export interface ModuleDocuments {
|
|
16
20
|
/** The library's module name (its `Telo.Library` doc's `metadata.name`). */
|
|
17
21
|
module: string;
|
|
18
22
|
/** Stable source identity of the library's owner file — the cache key. */
|
|
@@ -24,4 +28,4 @@ export interface ZoneModuleDocuments {
|
|
|
24
28
|
/** The library's declared `exports.resources` entries (bare names). */
|
|
25
29
|
exportedNames: readonly string[];
|
|
26
30
|
}
|
|
27
|
-
//# sourceMappingURL=
|
|
31
|
+
//# sourceMappingURL=module-documents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-documents.d.ts","sourceRoot":"","sources":["../src/module-documents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a `!ref` names, parsed once.
|
|
3
|
+
*
|
|
4
|
+
* THE single reader of the tag's grammar, on the `ref-slot.ts` / `zone-slot.ts`
|
|
5
|
+
* precedent. Three passes had grown their own parse of the same scalar and they
|
|
6
|
+
* disagreed: one took the source verbatim, one split on the first dot and
|
|
7
|
+
* dropped every alias but `Self`, one split on the LAST dot and dropped the
|
|
8
|
+
* alias entirely — so the same `!ref Alias.name` named three different things
|
|
9
|
+
* depending on which pass was asking, and the loosest of the three resolved a
|
|
10
|
+
* bare name against whatever manifest happened to share it.
|
|
11
|
+
*
|
|
12
|
+
* The grammar itself is one line and is not in dispute: `!ref <name>` or
|
|
13
|
+
* `!ref <Alias>.<name>`, split on the FIRST dot, because that is what
|
|
14
|
+
* `resolveRefSentinels` does and a name may not contain one
|
|
15
|
+
* (`INVALID_NAME` rejects it at every declaration site).
|
|
16
|
+
*
|
|
17
|
+
* What this deliberately does NOT do is decide what to look up. A reduction is
|
|
18
|
+
* the caller's, and the three genuinely differ: an edge in the call graph points
|
|
19
|
+
* at a cross-module target and tolerates not resolving it; a zone correlation
|
|
20
|
+
* refuses to bind anything it cannot resolve exactly; a throws walk resolves in
|
|
21
|
+
* the DECLARING library first. Each states its own, over one parse.
|
|
22
|
+
*
|
|
23
|
+
* Browser-safe.
|
|
24
|
+
*/
|
|
25
|
+
export interface RefSentinelTarget {
|
|
26
|
+
/** The scalar as written, for a caller that wants the author's spelling. */
|
|
27
|
+
source: string;
|
|
28
|
+
/** The prefix before the first dot, `Self` included and not normalized away —
|
|
29
|
+
* a caller that treats `Self` as "no alias" says so itself. */
|
|
30
|
+
alias?: string;
|
|
31
|
+
/** The segment after the first dot, or the whole scalar when there is none. */
|
|
32
|
+
name: string;
|
|
33
|
+
}
|
|
34
|
+
/** Parse a `!ref` sentinel. Returns `undefined` for anything that is not one —
|
|
35
|
+
* including the `{kind, name}` object `resolveRefSentinels` rewrites it into,
|
|
36
|
+
* which is a different shape with a different reader. */
|
|
37
|
+
export declare function refSentinelTarget(value: unknown): RefSentinelTarget | undefined;
|
|
38
|
+
//# sourceMappingURL=ref-sentinel-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ref-sentinel-target.d.ts","sourceRoot":"","sources":["../src/ref-sentinel-target.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf;oEACgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;0DAE0D;AAC1D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAM/E"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isRefSentinel } from "@telorun/templating";
|
|
2
|
+
/** Parse a `!ref` sentinel. Returns `undefined` for anything that is not one —
|
|
3
|
+
* including the `{kind, name}` object `resolveRefSentinels` rewrites it into,
|
|
4
|
+
* which is a different shape with a different reader. */
|
|
5
|
+
export function refSentinelTarget(value) {
|
|
6
|
+
if (!isRefSentinel(value))
|
|
7
|
+
return undefined;
|
|
8
|
+
const source = value.source;
|
|
9
|
+
const dot = source.indexOf(".");
|
|
10
|
+
if (dot <= 0)
|
|
11
|
+
return { source, name: source };
|
|
12
|
+
return { source, alias: source.slice(0, dot), name: source.slice(dot + 1) };
|
|
13
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-schema-type-refs.d.ts","sourceRoot":"","sources":["../src/resolve-schema-type-refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-schema-type-refs.d.ts","sourceRoot":"","sources":["../src/resolve-schema-type-refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,IAAI,CA6DN"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { canonicalTypeSchemaId, parseTeloTypeRef } from "@telorun/sdk";
|
|
2
|
+
import { moduleAliasScope } from "./module-alias-scope.js";
|
|
2
3
|
/** Schema-bearing fields on a Telo.Definition / Telo.Type resource. */
|
|
3
4
|
const SCHEMA_FIELDS = ["schema", "inputType", "outputType"];
|
|
4
5
|
/**
|
|
@@ -88,7 +89,7 @@ export function resolveSchemaTypeRefs(resources, aliases, aliasesByModule) {
|
|
|
88
89
|
};
|
|
89
90
|
for (const r of resources) {
|
|
90
91
|
const ownModule = r.metadata?.module;
|
|
91
|
-
const resolver = (
|
|
92
|
+
const resolver = moduleAliasScope(r.metadata, aliases, aliasesByModule);
|
|
92
93
|
const resolveAuthority = (authority) => authority === "Self" ? ownModule : resolver?.moduleForAlias(authority);
|
|
93
94
|
for (const field of SCHEMA_FIELDS) {
|
|
94
95
|
walk(r[field], resolveAuthority, ownModule, true);
|
|
@@ -34,10 +34,27 @@ export interface ResolveCtx {
|
|
|
34
34
|
aliasesByModule: Map<string, AliasResolver>;
|
|
35
35
|
/** The consumer/root module names; resources owned by these resolve against `aliases`. */
|
|
36
36
|
rootModules: Set<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Every imported library's FULL manifest list, keyed by module name.
|
|
39
|
+
*
|
|
40
|
+
* A consumer's flat set holds a library's EXPORTED instances and nothing else,
|
|
41
|
+
* so the siblings an exported entry point invokes are not in it. Without this
|
|
42
|
+
* the walk stops at the first such hop, and the difference is not academic: a
|
|
43
|
+
* library whose entry point raises its own code through an internal guard
|
|
44
|
+
* presented an empty union to its consumer, which then had its `catches:`
|
|
45
|
+
* rejected for the very code the entry point documents.
|
|
46
|
+
*
|
|
47
|
+
* Consulted only as a FALLBACK, after the flat set — the flat set is what the
|
|
48
|
+
* consumer's own resources resolve against, and a library-internal name must
|
|
49
|
+
* never shadow one of them.
|
|
50
|
+
*/
|
|
51
|
+
moduleManifests: Map<string, ResourceManifest[]>;
|
|
52
|
+
/** Keyed `<module>\0<name>`: resource names are module-scoped, so two
|
|
53
|
+
* libraries each declaring a `query` are two different unions. */
|
|
37
54
|
memo: Map<string, ThrowsUnion>;
|
|
38
55
|
inProgress: Set<string>;
|
|
39
56
|
}
|
|
40
|
-
export declare function createResolveCtx(allManifests: ResourceManifest[], defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule?: Map<string, AliasResolver>, rootModules?: Set<string>): ResolveCtx;
|
|
57
|
+
export declare function createResolveCtx(allManifests: ResourceManifest[], defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule?: Map<string, AliasResolver>, rootModules?: Set<string>, moduleManifests?: Map<string, ResourceManifest[]>): ResolveCtx;
|
|
41
58
|
/** Resolve the effective throw union for a named manifest. The result combines
|
|
42
59
|
* explicit `throws.codes`, `throws.inherit: true` dataflow (step-context
|
|
43
60
|
* traversal with try/catch subtraction), and unbounded markers for
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED;;gFAEgF;AAChF,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC;;;8EAG0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB;;;;gDAI4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB;;;wFAGoF;IACpF,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,0FAA0F;IAC1F,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB;;;;;;;;;;;;;OAaG;IACH,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACjD;uEACmE;IACnE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,gBAAgB,EAAE,EAChC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,aAAa,EACtB,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,EACvD,WAAW,GAAE,GAAG,CAAC,MAAM,CAAa,EACpC,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAa,GAC3D,UAAU,CAWZ;AA2HD;;;;8CAI8C;AAC9C,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,UAAU,GACd,WAAW,CAiDb"}
|
|
@@ -1,21 +1,91 @@
|
|
|
1
1
|
import { isTaggedSentinel } from "@telorun/templating";
|
|
2
2
|
import { scopeResolverForModule } from "./alias-resolver.js";
|
|
3
|
+
import { resolveScopedName } from "./call-graph.js";
|
|
4
|
+
import { refSentinelTarget } from "./ref-sentinel-target.js";
|
|
3
5
|
import { readStepSlot } from "./step-slot.js";
|
|
4
6
|
/** Code a non-`InvokeError` failure surfaces as inside a `catch` block. Mirrors
|
|
5
7
|
* `PLAIN_ERROR_CODE` in `@telorun/run`'s `toSequenceError`: any invoke can throw
|
|
6
8
|
* a plain error, which the catch sees as `error.code === "INTERNAL_ERROR"`. */
|
|
7
9
|
export const PLAIN_ERROR_CODE = "INTERNAL_ERROR";
|
|
8
|
-
export function createResolveCtx(allManifests, defs, aliases, aliasesByModule = new Map(), rootModules = new Set()) {
|
|
10
|
+
export function createResolveCtx(allManifests, defs, aliases, aliasesByModule = new Map(), rootModules = new Set(), moduleManifests = new Map()) {
|
|
9
11
|
return {
|
|
10
12
|
allManifests,
|
|
11
13
|
defs,
|
|
12
14
|
aliases,
|
|
13
15
|
aliasesByModule,
|
|
14
16
|
rootModules,
|
|
17
|
+
moduleManifests,
|
|
15
18
|
memo: new Map(),
|
|
16
19
|
inProgress: new Set(),
|
|
17
20
|
};
|
|
18
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* A dispatch target named by a resolved `{kind, name}` ref.
|
|
24
|
+
*
|
|
25
|
+
* The flat set is the scope such a ref was resolved in, so it is asked first;
|
|
26
|
+
* the owning library's own documents are the fallback for a name the flattened
|
|
27
|
+
* view dropped. `kindMatches` applies to BOTH — one function, one rule, or the
|
|
28
|
+
* next caller inherits whichever half it happened to hit.
|
|
29
|
+
*/
|
|
30
|
+
function findTarget(ctx, name, ownerModule, kindMatches) {
|
|
31
|
+
const flat = ctx.allManifests.find((m) => m.metadata?.name === name && kindMatches(m));
|
|
32
|
+
if (flat)
|
|
33
|
+
return flat;
|
|
34
|
+
if (!ownerModule)
|
|
35
|
+
return undefined;
|
|
36
|
+
return ctx.moduleManifests
|
|
37
|
+
.get(ownerModule)
|
|
38
|
+
?.find((m) => m.metadata?.name === name && kindMatches(m));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The target of a `!ref` that still carries its sentinel — a library-internal
|
|
42
|
+
* reference inside a manifest forwarded into a consumer's flat set, where Phase
|
|
43
|
+
* 2.5 had nothing to resolve it against.
|
|
44
|
+
*
|
|
45
|
+
* **The declaring library is asked FIRST**, and that ordering is the whole rule:
|
|
46
|
+
* a bare name in a library manifest is unambiguously library-internal, so
|
|
47
|
+
* searching the consumer's flat set first let any consumer resource that
|
|
48
|
+
* happened to share the name supply another library's throw union — the same
|
|
49
|
+
* false `{∅}` this branch exists to remove, arrived at from the other side.
|
|
50
|
+
*
|
|
51
|
+
* An ALIAS-qualified source is the cross-module case and is resolved through the
|
|
52
|
+
* declaring module's own alias table, never by dropping the alias and matching
|
|
53
|
+
* the bare name anywhere.
|
|
54
|
+
*
|
|
55
|
+
* Ambiguity resolves to NOTHING rather than to a guess (`resolveScopedName`'s
|
|
56
|
+
* rule), and the caller reads that as unbounded — the safe direction here, since
|
|
57
|
+
* a union that cannot be enumerated must not read as empty.
|
|
58
|
+
*/
|
|
59
|
+
function findSentinelTarget(ctx, target, ownerModule) {
|
|
60
|
+
const named = (pool) => (pool ?? []).filter((m) => m.metadata?.name === target.name);
|
|
61
|
+
if (target.alias !== undefined && target.alias !== "Self") {
|
|
62
|
+
// A forwarded export: its module is whatever the DECLARING module aliases
|
|
63
|
+
// that prefix to, and it keeps its export name in the flat set.
|
|
64
|
+
// A root-owned manifest resolves aliases against the global table, which is
|
|
65
|
+
// what `scopeResolverForModule` returns undefined for — so fall back to it
|
|
66
|
+
// rather than reading a root's own alias as unresolvable.
|
|
67
|
+
const resolver = scopeResolverFor(ctx, ownerModule) ?? ctx.aliases;
|
|
68
|
+
const module = resolver.moduleForAlias(target.alias);
|
|
69
|
+
if (!module)
|
|
70
|
+
return undefined;
|
|
71
|
+
return named(ctx.allManifests).find((m) => declaringModuleOf(m) === module);
|
|
72
|
+
}
|
|
73
|
+
const own = named(ctx.moduleManifests.get(ownerModule ?? ""));
|
|
74
|
+
if (own.length === 1)
|
|
75
|
+
return own[0];
|
|
76
|
+
if (own.length > 1)
|
|
77
|
+
return undefined;
|
|
78
|
+
return resolveScopedName(named(ctx.allManifests), declaringModuleOf, ownerModule);
|
|
79
|
+
}
|
|
80
|
+
const declaringModuleOf = (m) => m.metadata?.module;
|
|
81
|
+
/** Memo key. Module-scoped, because resource names are. */
|
|
82
|
+
function memoKey(manifest) {
|
|
83
|
+
const name = manifest.metadata?.name;
|
|
84
|
+
if (!name)
|
|
85
|
+
return undefined;
|
|
86
|
+
const mod = manifest.metadata?.module ?? "";
|
|
87
|
+
return `${mod}\0${name}`;
|
|
88
|
+
}
|
|
19
89
|
function emptyUnion() {
|
|
20
90
|
return { codes: new Map(), unbounded: false };
|
|
21
91
|
}
|
|
@@ -60,7 +130,7 @@ function codesFromDefinition(definition) {
|
|
|
60
130
|
* unresolvable passthrough call sites. Cycles short-circuit to an empty
|
|
61
131
|
* result so resolution always terminates. */
|
|
62
132
|
export function resolveThrowsUnion(manifest, ctx) {
|
|
63
|
-
const name = manifest
|
|
133
|
+
const name = memoKey(manifest);
|
|
64
134
|
if (name) {
|
|
65
135
|
const cached = ctx.memo.get(name);
|
|
66
136
|
if (cached)
|
|
@@ -223,8 +293,23 @@ function resolveStepInvokeThrows(step, invokeField, enclosingTryCodes, ctx, owne
|
|
|
223
293
|
if (!invokeRef || typeof invokeRef !== "object")
|
|
224
294
|
return emptyUnion();
|
|
225
295
|
const invokedKind = invokeRef.kind;
|
|
226
|
-
|
|
227
|
-
|
|
296
|
+
// A reference that still carries its parse-time sentinel — a library-internal
|
|
297
|
+
// `!ref` inside a manifest forwarded into a consumer's flat set, where Phase
|
|
298
|
+
// 2.5 had nothing to resolve it against. The target is in the declaring
|
|
299
|
+
// library's own documents, so it is looked up there; only a name that is not
|
|
300
|
+
// there either is UNKNOWN, which is unbounded rather than empty. Reading it as
|
|
301
|
+
// empty is what made a library's exported entry point present a `{∅}` union to
|
|
302
|
+
// its consumer and get the consumer's `catches:` rejected for the code the
|
|
303
|
+
// entry point documents.
|
|
304
|
+
if (!invokedKind) {
|
|
305
|
+
const sentinel = refSentinelTarget(invokeRef);
|
|
306
|
+
if (!sentinel)
|
|
307
|
+
return emptyUnion();
|
|
308
|
+
const target = findSentinelTarget(ctx, sentinel, ownerModule);
|
|
309
|
+
if (target)
|
|
310
|
+
return resolveThrowsUnion(target, ctx);
|
|
311
|
+
return { codes: new Map(), unbounded: true };
|
|
312
|
+
}
|
|
228
313
|
// The invoked kind's alias resolves in the OWNER manifest's lexical scope (the
|
|
229
314
|
// composer that declares the step), so a library's step referencing its own
|
|
230
315
|
// import resolves against that library, not the consumer.
|
|
@@ -239,11 +324,10 @@ function resolveStepInvokeThrows(step, invokeField, enclosingTryCodes, ctx, owne
|
|
|
239
324
|
const invokeName = invokeRef.name;
|
|
240
325
|
if (invokeName) {
|
|
241
326
|
const scopedInvokedKind = scopeResolver?.resolveKind(invokedKind);
|
|
242
|
-
const target = ctx
|
|
243
|
-
(m.kind === invokedKind ||
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
(scopedInvokedKind !== undefined && m.kind === scopedInvokedKind)));
|
|
327
|
+
const target = findTarget(ctx, invokeName, ownerModule, (m) => m.kind === invokedKind ||
|
|
328
|
+
ctx.aliases.resolveKind(m.kind) === invokedKind ||
|
|
329
|
+
m.kind === ctx.aliases.resolveKind(invokedKind) ||
|
|
330
|
+
(scopedInvokedKind !== undefined && m.kind === scopedInvokedKind));
|
|
247
331
|
if (target)
|
|
248
332
|
return resolveThrowsUnion(target, ctx);
|
|
249
333
|
}
|
|
@@ -17,7 +17,7 @@ import type { ResourceManifest } from "@telorun/sdk";
|
|
|
17
17
|
import type { AliasResolver } from "./alias-resolver.js";
|
|
18
18
|
import { type CallGraph, type ResourceGraphNode } from "./call-graph.js";
|
|
19
19
|
import type { DefinitionRegistry } from "./definition-registry.js";
|
|
20
|
-
import type {
|
|
20
|
+
import type { ModuleDocuments } from "./module-documents.js";
|
|
21
21
|
import { type AnalysisDiagnostic } from "./types.js";
|
|
22
22
|
/** One open requirement on a library's exported resource — the contract an
|
|
23
23
|
* importer must satisfy. Plain data, so it caches and crosses the
|
|
@@ -92,7 +92,7 @@ export declare function zoneDocumentsSignature(manifests: readonly ResourceManif
|
|
|
92
92
|
* its full documents (which the flattened analysis view no longer holds), run
|
|
93
93
|
* the projection derive-only, and keep what reaches an exported instance.
|
|
94
94
|
*/
|
|
95
|
-
export declare function deriveLibraryExportRequirements(docs:
|
|
95
|
+
export declare function deriveLibraryExportRequirements(docs: ModuleDocuments, defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule: Map<string, AliasResolver>, cache?: ZoneExportCache): ZoneExportRequirements;
|
|
96
96
|
export interface ZoneAnalysisArgs {
|
|
97
97
|
/** The entry analysis set (post inline-normalization + sentinel resolution). */
|
|
98
98
|
manifests: ResourceManifest[];
|
|
@@ -101,7 +101,7 @@ export interface ZoneAnalysisArgs {
|
|
|
101
101
|
aliases: AliasResolver;
|
|
102
102
|
aliasesByModule: Map<string, AliasResolver>;
|
|
103
103
|
rootModules: ReadonlySet<string>;
|
|
104
|
-
moduleDocuments?: readonly
|
|
104
|
+
moduleDocuments?: readonly ModuleDocuments[];
|
|
105
105
|
cache?: ZoneExportCache;
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-zone-requirements.d.ts","sourceRoot":"","sources":["../src/resolve-zone-requirements.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAEL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAMnE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"resolve-zone-requirements.d.ts","sourceRoot":"","sources":["../src/resolve-zone-requirements.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { refSentinelTarget } from "./ref-sentinel-target.js";
|
|
2
2
|
import { buildCallGraph, } from "./call-graph.js";
|
|
3
3
|
import { enclosingOf, propertySchemas, resolveLocalRef, } from "./manifest-navigation.js";
|
|
4
4
|
import { readProvidesZone, readRequiresZone } from "./zone-slot.js";
|
|
5
5
|
import { DiagnosticSeverity } from "./types.js";
|
|
6
|
+
import { moduleAliasScope } from "./module-alias-scope.js";
|
|
6
7
|
const SOURCE = "telo-analyzer";
|
|
7
8
|
/** Resolve a possibly alias-form kind to its definition in the DECLARING
|
|
8
9
|
* module's scope — the same layering `AnalysisRegistry.resolveDefinitionIn`
|
|
9
10
|
* uses. */
|
|
10
11
|
function definitionResolver(defs, aliases, aliasesByModule) {
|
|
11
12
|
return (kind, module) => {
|
|
12
|
-
const scope = (module
|
|
13
|
+
const scope = moduleAliasScope({ module }, aliases, aliasesByModule);
|
|
13
14
|
const canonical = scope.resolveKind(kind);
|
|
14
15
|
return defs.resolve(kind) ?? (canonical ? defs.resolve(canonical) : undefined);
|
|
15
16
|
};
|
|
@@ -67,18 +68,17 @@ function schemaNodeAt(rootSchema, slotPath) {
|
|
|
67
68
|
* under-approximating direction the whole pass leans on. `Self.` is a local
|
|
68
69
|
* name written the long way and does resolve.
|
|
69
70
|
*
|
|
70
|
-
* This
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
71
|
+
* This is this pass's REDUCTION over the shared `refSentinelTarget` parse, not a
|
|
72
|
+
* second reading of the tag: `call-graph`'s answers a different question (what
|
|
73
|
+
* an EDGE points at, cross-module included, for a graph whose consumers tolerate
|
|
74
|
+
* an unresolved target) and states its own reduction the same way.
|
|
74
75
|
*/
|
|
75
76
|
function refName(value) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return source.slice(0, dot) === "Self" ? source.slice(dot + 1) : undefined;
|
|
77
|
+
const sentinel = refSentinelTarget(value);
|
|
78
|
+
if (sentinel) {
|
|
79
|
+
if (sentinel.alias === undefined)
|
|
80
|
+
return sentinel.name;
|
|
81
|
+
return sentinel.alias === "Self" ? sentinel.name : undefined;
|
|
82
82
|
}
|
|
83
83
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
84
84
|
return undefined;
|
package/dist/telo-version.d.ts
CHANGED
package/dist/telo-version.js
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
// its release identity, this is the scale a module's `requires.telo` range is
|
|
6
6
|
// written against, and every kernel in every language reports the same scale.
|
|
7
7
|
/** The surface generation this analyzer implements. */
|
|
8
|
-
export const TELO_SURFACE_VERSION = "0.
|
|
8
|
+
export const TELO_SURFACE_VERSION = "0.87.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-body.d.ts","sourceRoot":"","sources":["../src/template-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"template-body.d.ts","sourceRoot":"","sources":["../src/template-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B;qBACiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC5C;AAED;mDACmD;AACnD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,gBAAgB,EACnB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GAAG,SAAS,EAClC,MAAM,EAAE,YAAY,GAAG,SAAS,GAC/B,YAAY,EAAE,CA0BhB;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAIhE;AAED;;+EAE+E;AAC/E,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EACtD,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,SAAS,CAEf;AAED;;;;6CAI6C;AAC7C,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAQxF"}
|
package/dist/template-body.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { moduleAliasScope } from "./module-alias-scope.js";
|
|
1
2
|
/** The template bodies a manifest declares — empty for anything that is not a
|
|
2
3
|
* `Telo.Definition` with a `resources:` array. */
|
|
3
4
|
export function templateBodies(m, registry, aliases, scopes) {
|
|
@@ -9,10 +10,7 @@ export function templateBodies(m, registry, aliases, scopes) {
|
|
|
9
10
|
// A nested kind is written through the alias scope of the module that DECLARED
|
|
10
11
|
// the definition, never the consumer's — the same rule every other kind
|
|
11
12
|
// resolution in a forwarded manifest follows.
|
|
12
|
-
const
|
|
13
|
-
const scope = (ownModule && scopes && !scopes.rootModules.has(ownModule)
|
|
14
|
-
? scopes.aliasesByModule.get(ownModule)
|
|
15
|
-
: undefined) ?? aliases;
|
|
13
|
+
const scope = moduleAliasScope(m.metadata, aliases, scopes?.aliasesByModule);
|
|
16
14
|
const out = [];
|
|
17
15
|
for (let i = 0; i < bodies.length; i++) {
|
|
18
16
|
const body = bodies[i];
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HostVersions } from "./requires-block.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ModuleDocuments } from "./module-documents.js";
|
|
3
3
|
/** Matches LSP DiagnosticSeverity values exactly.
|
|
4
4
|
* https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticSeverity */
|
|
5
5
|
export declare const DiagnosticSeverity: {
|
|
@@ -130,10 +130,10 @@ export interface AnalysisOptions {
|
|
|
130
130
|
/** Imported libraries' FULL document sets, for the zone stage's per-library
|
|
131
131
|
* export derivation — the flattened analysis view forwards only each
|
|
132
132
|
* library's export surface, never its internal dispatch chain. Collected
|
|
133
|
-
* from a LoadedGraph via `
|
|
133
|
+
* from a LoadedGraph via `collectModuleDocuments`. Omitting it skips
|
|
134
134
|
* the derivation (the under-approximating direction — the runtime check
|
|
135
135
|
* remains the enforcement). */
|
|
136
|
-
moduleDocuments?:
|
|
136
|
+
moduleDocuments?: ModuleDocuments[];
|
|
137
137
|
/** When true, `analyze()` runs the state-mutating setup (module identity /
|
|
138
138
|
* alias / definition registration plus `normalizeInlineResources`) but
|
|
139
139
|
* skips every diagnostic-producing pass — per-resource validation, the
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,11 @@ import { type AnalysisDiagnostic } from "./types.js";
|
|
|
18
18
|
* whose input contract is now `inputType:`.
|
|
19
19
|
* - CONTRACT_TYPE_NOT_FOUND: a contract names a type that is not declared in
|
|
20
20
|
* scope, so every call through it would fail at dispatch.
|
|
21
|
+
* - CONTRACT_NOT_SUBSTITUTABLE: a definition replaces an ancestor's contract
|
|
22
|
+
* with a shape that cannot stand in for it. The one check nothing else makes:
|
|
23
|
+
* contracts resolve to the nearest declaration in BOTH halves, so a child that
|
|
24
|
+
* declares its own is compared against its abstract by neither the analyzer
|
|
25
|
+
* nor dispatch.
|
|
21
26
|
*
|
|
22
27
|
* Deliberately NOT diagnosed: an input that is neither `required:` nor
|
|
23
28
|
* defaulted. It is indistinguishable from a genuinely optional one — `Ai.Text`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-invocation-contract.d.ts","sourceRoot":"","sources":["../src/validate-invocation-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"validate-invocation-contract.d.ts","sourceRoot":"","sources":["../src/validate-invocation-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAanE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,GACtD,kBAAkB,EAAE,CA4CtB"}
|