typesea 0.1.0 → 0.2.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/CHANGELOG.md +67 -6
- package/README.md +98 -17
- package/dist/adapters/index.d.ts +50 -8
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +169 -48
- package/dist/aot/index.d.ts +18 -2
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +93 -14
- package/dist/async/index.d.ts +28 -56
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +94 -37
- package/dist/builders/composite.d.ts +37 -6
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +84 -10
- package/dist/builders/index.d.ts +2 -0
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +2 -0
- package/dist/builders/modifier.d.ts +30 -5
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +38 -5
- package/dist/builders/object/guard.d.ts +18 -22
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +26 -26
- package/dist/builders/object/index.d.ts +2 -0
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +2 -0
- package/dist/builders/object/schema.d.ts +55 -9
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +92 -15
- package/dist/builders/object/types.d.ts +5 -31
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/object/types.js +2 -0
- package/dist/builders/scalar.d.ts +29 -8
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +33 -8
- package/dist/builders/table.d.ts +4 -0
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +4 -0
- package/dist/builders/types.d.ts +14 -4
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +2 -0
- package/dist/compile/check-composite.d.ts +22 -1
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +564 -24
- package/dist/compile/check-scalar.d.ts +78 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +432 -1
- package/dist/compile/check.d.ts +12 -0
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +37 -0
- package/dist/compile/context.d.ts +47 -9
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +51 -8
- package/dist/compile/graph-predicate.d.ts +4 -2
- package/dist/compile/graph-predicate.d.ts.map +1 -1
- package/dist/compile/graph-predicate.js +1907 -171
- package/dist/compile/guard.d.ts +15 -24
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +158 -74
- package/dist/compile/index.d.ts +3 -1
- package/dist/compile/index.d.ts.map +1 -1
- package/dist/compile/index.js +2 -0
- package/dist/compile/issue.d.ts +110 -0
- package/dist/compile/issue.d.ts.map +1 -1
- package/dist/compile/issue.js +184 -1
- package/dist/compile/names.d.ts +12 -2
- package/dist/compile/names.d.ts.map +1 -1
- package/dist/compile/names.js +19 -3
- package/dist/compile/predicate.d.ts +24 -0
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +131 -5
- package/dist/compile/runtime.d.ts +80 -12
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +25 -6
- package/dist/compile/source.d.ts +10 -2
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +361 -26
- package/dist/compile/types.d.ts +20 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/compile/types.js +2 -0
- package/dist/decoder/index.d.ts +32 -46
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +102 -38
- package/dist/evaluate/check-composite.d.ts +59 -0
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +151 -3
- package/dist/evaluate/check-scalar.d.ts +16 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +32 -0
- package/dist/evaluate/check.d.ts +7 -0
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +43 -0
- package/dist/evaluate/index.d.ts +2 -0
- package/dist/evaluate/index.d.ts.map +1 -1
- package/dist/evaluate/index.js +2 -0
- package/dist/evaluate/issue.d.ts +11 -1
- package/dist/evaluate/issue.d.ts.map +1 -1
- package/dist/evaluate/issue.js +15 -1
- package/dist/evaluate/predicate.d.ts +16 -5
- package/dist/evaluate/predicate.d.ts.map +1 -1
- package/dist/evaluate/predicate.js +20 -5
- package/dist/evaluate/shared.d.ts +59 -13
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +66 -8
- package/dist/evaluate/state.d.ts +35 -13
- package/dist/evaluate/state.d.ts.map +1 -1
- package/dist/evaluate/state.js +35 -2
- package/dist/guard/base.d.ts +79 -29
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +91 -29
- package/dist/guard/error.d.ts +10 -5
- package/dist/guard/error.d.ts.map +1 -1
- package/dist/guard/error.js +10 -5
- package/dist/guard/index.d.ts +2 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +2 -0
- package/dist/guard/number.d.ts +26 -11
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +30 -11
- package/dist/guard/props.d.ts +27 -3
- package/dist/guard/props.d.ts.map +1 -1
- package/dist/guard/props.js +27 -3
- package/dist/guard/read.d.ts +62 -9
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +83 -10
- package/dist/guard/registry.d.ts +12 -2
- package/dist/guard/registry.d.ts.map +1 -1
- package/dist/guard/registry.js +15 -3
- package/dist/guard/string.d.ts +33 -13
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +37 -13
- package/dist/guard/types.d.ts +92 -40
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/types.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/index.d.ts +42 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +51 -8
- package/dist/ir/builder.d.ts +16 -126
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +77 -137
- package/dist/ir/freeze.d.ts +4 -0
- package/dist/ir/freeze.d.ts.map +1 -1
- package/dist/ir/freeze.js +59 -0
- package/dist/ir/index.d.ts +3 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +2 -0
- package/dist/ir/regexp.d.ts +2 -0
- package/dist/ir/regexp.d.ts.map +1 -1
- package/dist/ir/regexp.js +2 -0
- package/dist/ir/types.d.ts +90 -55
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +2 -0
- package/dist/ir/validate.d.ts +8 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +477 -61
- package/dist/issue/index.d.ts +41 -9
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +61 -11
- package/dist/json-schema/emit-combinator.d.ts +44 -4
- package/dist/json-schema/emit-combinator.d.ts.map +1 -1
- package/dist/json-schema/emit-combinator.js +44 -4
- package/dist/json-schema/emit-composite.d.ts +10 -0
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +15 -1
- package/dist/json-schema/emit-scalar.d.ts +26 -3
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +70 -9
- package/dist/json-schema/emit-types.d.ts +11 -1
- package/dist/json-schema/emit-types.d.ts.map +1 -1
- package/dist/json-schema/emit-types.js +2 -0
- package/dist/json-schema/emit.d.ts +12 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +12 -1
- package/dist/json-schema/freeze.d.ts +13 -2
- package/dist/json-schema/freeze.d.ts.map +1 -1
- package/dist/json-schema/freeze.js +41 -8
- package/dist/json-schema/index.d.ts +16 -2
- package/dist/json-schema/index.d.ts.map +1 -1
- package/dist/json-schema/index.js +23 -3
- package/dist/json-schema/issue.d.ts +4 -1
- package/dist/json-schema/issue.d.ts.map +1 -1
- package/dist/json-schema/issue.js +4 -1
- package/dist/json-schema/read.d.ts +24 -3
- package/dist/json-schema/read.d.ts.map +1 -1
- package/dist/json-schema/read.js +59 -12
- package/dist/json-schema/types.d.ts +38 -15
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/json-schema/types.js +2 -0
- package/dist/kind/index.d.ts +15 -28
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +15 -10
- package/dist/lower/index.d.ts +6 -1
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +411 -44
- package/dist/message/index.d.ts +46 -10
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +88 -17
- package/dist/optimize/algebraic.d.ts +54 -0
- package/dist/optimize/algebraic.d.ts.map +1 -0
- package/dist/optimize/algebraic.js +314 -0
- package/dist/optimize/compact.d.ts +8 -1
- package/dist/optimize/compact.d.ts.map +1 -1
- package/dist/optimize/compact.js +13 -2
- package/dist/optimize/domain.d.ts +16 -0
- package/dist/optimize/domain.d.ts.map +1 -0
- package/dist/optimize/domain.js +615 -0
- package/dist/optimize/fold-boolean.d.ts +17 -2
- package/dist/optimize/fold-boolean.d.ts.map +1 -1
- package/dist/optimize/fold-boolean.js +59 -14
- package/dist/optimize/fold-common.d.ts +43 -8
- package/dist/optimize/fold-common.d.ts.map +1 -1
- package/dist/optimize/fold-common.js +37 -6
- package/dist/optimize/fold-constraints.d.ts +33 -0
- package/dist/optimize/fold-constraints.d.ts.map +1 -0
- package/dist/optimize/fold-constraints.js +484 -0
- package/dist/optimize/fold-scalar.d.ts +98 -13
- package/dist/optimize/fold-scalar.d.ts.map +1 -1
- package/dist/optimize/fold-scalar.js +98 -13
- package/dist/optimize/fold.d.ts +8 -1
- package/dist/optimize/fold.d.ts.map +1 -1
- package/dist/optimize/fold.js +22 -2
- package/dist/optimize/index.d.ts +9 -1
- package/dist/optimize/index.d.ts.map +1 -1
- package/dist/optimize/index.js +18 -3
- package/dist/optimize/map-node.d.ts +3 -1
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +45 -3
- package/dist/optimize/peephole.d.ts +16 -0
- package/dist/optimize/peephole.d.ts.map +1 -0
- package/dist/optimize/peephole.js +254 -0
- package/dist/optimize/remap.d.ts +2 -0
- package/dist/optimize/remap.d.ts.map +1 -1
- package/dist/optimize/remap.js +2 -0
- package/dist/optimize/rewrite.d.ts +13 -8
- package/dist/optimize/rewrite.d.ts.map +1 -1
- package/dist/optimize/rewrite.js +13 -8
- package/dist/plan/cache.d.ts +9 -3
- package/dist/plan/cache.d.ts.map +1 -1
- package/dist/plan/cache.js +21 -5
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +2 -0
- package/dist/plan/predicate.d.ts +2 -0
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +268 -29
- package/dist/plan/schema-predicate.d.ts +6 -0
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +117 -13
- package/dist/plan/types.d.ts +2 -0
- package/dist/plan/types.d.ts.map +1 -1
- package/dist/plan/types.js +2 -0
- package/dist/result/index.d.ts +19 -5
- package/dist/result/index.d.ts.map +1 -1
- package/dist/result/index.js +10 -2
- package/dist/schema/common.d.ts +69 -6
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +104 -10
- package/dist/schema/freeze.d.ts +4 -0
- package/dist/schema/freeze.d.ts.map +1 -1
- package/dist/schema/freeze.js +18 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/lazy.d.ts +4 -0
- package/dist/schema/lazy.d.ts.map +1 -1
- package/dist/schema/lazy.js +4 -0
- package/dist/schema/literal.d.ts +7 -1
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -1
- package/dist/schema/types.d.ts +20 -96
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +5 -1
- package/dist/schema/undefined.d.ts +17 -0
- package/dist/schema/undefined.d.ts.map +1 -0
- package/dist/schema/undefined.js +72 -0
- package/dist/schema/validate.d.ts +8 -1
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +146 -55
- package/docs/api.md +57 -0
- package/docs/assets/benchmark-headline.svg +163 -0
- package/docs/engine-notes.md +58 -15
- package/docs/index.html +130 -110
- package/package.json +65 -65
package/dist/message/index.js
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { copyIssueArray, freezeIssueArray, isIssueCodeValue, makeIssue } from "../issue/index.js";
|
|
2
2
|
import { err } from "../result/index.js";
|
|
3
3
|
/**
|
|
4
|
-
* @brief
|
|
4
|
+
* @brief Freeze a user catalog after validating its keys and templates.
|
|
5
|
+
* @details Message helpers keep structured issues separate from human-readable formatting
|
|
6
|
+
* until callers request text.
|
|
7
|
+
* @param catalog Partial message catalog supplied by the application.
|
|
8
|
+
* @returns Frozen catalog that can be reused across validations.
|
|
5
9
|
*/
|
|
6
10
|
export function defineMessages(catalog) {
|
|
7
11
|
return Object.freeze(copyCatalog(catalog));
|
|
8
12
|
}
|
|
9
13
|
/**
|
|
10
|
-
* @brief
|
|
14
|
+
* @brief Render one issue into a localized human-readable message.
|
|
15
|
+
* @details The issue is copied before rendering so user callbacks cannot mutate
|
|
16
|
+
* shared diagnostic objects through accidental aliasing.
|
|
17
|
+
* @param issue Issue object to render.
|
|
18
|
+
* @param options Optional locale, catalog, and path formatter.
|
|
19
|
+
* @returns Rendered message text.
|
|
11
20
|
*/
|
|
12
21
|
export function formatIssue(issue, options) {
|
|
13
22
|
const copied = copyIssueArray([issue]);
|
|
@@ -18,7 +27,12 @@ export function formatIssue(issue, options) {
|
|
|
18
27
|
return renderIssue(first, readOptions(options));
|
|
19
28
|
}
|
|
20
29
|
/**
|
|
21
|
-
* @brief
|
|
30
|
+
* @brief Render a frozen list of issues into localized message strings.
|
|
31
|
+
* @details The issue array is copied before rendering so caller-owned issue
|
|
32
|
+
* objects cannot change while user path formatters or templates execute.
|
|
33
|
+
* @param issues Issue list to render.
|
|
34
|
+
* @param options Optional locale, catalog, and path formatter.
|
|
35
|
+
* @returns Frozen list of rendered messages aligned with the input issue order.
|
|
22
36
|
*/
|
|
23
37
|
export function formatIssues(issues, options) {
|
|
24
38
|
const copied = copyIssueArray(issues);
|
|
@@ -33,7 +47,13 @@ export function formatIssues(issues, options) {
|
|
|
33
47
|
return Object.freeze(messages);
|
|
34
48
|
}
|
|
35
49
|
/**
|
|
36
|
-
* @brief
|
|
50
|
+
* @brief Attach rendered messages to every issue in a failed check result.
|
|
51
|
+
* @details Successful results are returned unchanged. Failed results are copied
|
|
52
|
+
* into fresh issue objects so structured diagnostics keep their original fields
|
|
53
|
+
* while gaining a stable human-readable message.
|
|
54
|
+
* @param result Check result to decorate.
|
|
55
|
+
* @param options Optional locale, catalog, and path formatter.
|
|
56
|
+
* @returns Original success result or a failed result with rendered messages.
|
|
37
57
|
*/
|
|
38
58
|
export function withMessages(result, options) {
|
|
39
59
|
if (result.ok) {
|
|
@@ -51,7 +71,13 @@ export function withMessages(result, options) {
|
|
|
51
71
|
return err(freezeIssueArray(issues));
|
|
52
72
|
}
|
|
53
73
|
/**
|
|
54
|
-
* @brief render issue.
|
|
74
|
+
* @brief Select the template source and render one normalized issue.
|
|
75
|
+
* @details Custom catalogs take precedence, issue-local messages are respected
|
|
76
|
+
* next, and built-in catalogs are the final fallback. That order lets adapters
|
|
77
|
+
* inject precise messages without losing defaults.
|
|
78
|
+
* @param issue Issue currently being rendered.
|
|
79
|
+
* @param options Resolved message rendering configuration.
|
|
80
|
+
* @returns Rendered message text.
|
|
55
81
|
*/
|
|
56
82
|
function renderIssue(issue, options) {
|
|
57
83
|
const context = makeContext(issue, options.pathFormatter);
|
|
@@ -65,7 +91,12 @@ function renderIssue(issue, options) {
|
|
|
65
91
|
return renderTemplate(defaultCatalogs[options.locale][issue.code], issue, context);
|
|
66
92
|
}
|
|
67
93
|
/**
|
|
68
|
-
* @brief
|
|
94
|
+
* @brief Build the stable template context for one issue.
|
|
95
|
+
* @details Missing expected or actual fields become `"unknown"` so templates
|
|
96
|
+
* can stay branch-free and every placeholder always has a string value.
|
|
97
|
+
* @param issue Issue currently being rendered.
|
|
98
|
+
* @param pathFormatter Formatter selected by resolved options.
|
|
99
|
+
* @returns Context object passed to string and function templates.
|
|
69
100
|
*/
|
|
70
101
|
function makeContext(issue, pathFormatter) {
|
|
71
102
|
return {
|
|
@@ -76,7 +107,14 @@ function makeContext(issue, pathFormatter) {
|
|
|
76
107
|
};
|
|
77
108
|
}
|
|
78
109
|
/**
|
|
79
|
-
* @brief
|
|
110
|
+
* @brief Render a string or callback template against one issue context.
|
|
111
|
+
* @details Function templates are checked at runtime because they cross into
|
|
112
|
+
* user code. String templates use fixed token replacement without regular
|
|
113
|
+
* expressions, keeping the common path allocation pattern predictable.
|
|
114
|
+
* @param template Template selected for this issue code.
|
|
115
|
+
* @param issue Issue currently being rendered.
|
|
116
|
+
* @param context Preformatted replacement context.
|
|
117
|
+
* @returns Rendered message text.
|
|
80
118
|
*/
|
|
81
119
|
function renderTemplate(template, issue, context) {
|
|
82
120
|
if (typeof template === "function") {
|
|
@@ -93,7 +131,11 @@ function renderTemplate(template, issue, context) {
|
|
|
93
131
|
.split("{actual}").join(context.actual);
|
|
94
132
|
}
|
|
95
133
|
/**
|
|
96
|
-
* @brief
|
|
134
|
+
* @brief Normalize public rendering options into the internal shape.
|
|
135
|
+
* @details Validation happens once at the entry point. The render loop then
|
|
136
|
+
* works with concrete locale and formatter values without repeated guards.
|
|
137
|
+
* @param options Optional user configuration.
|
|
138
|
+
* @returns Resolved message rendering configuration.
|
|
97
139
|
*/
|
|
98
140
|
function readOptions(options) {
|
|
99
141
|
if (options === undefined) {
|
|
@@ -116,7 +158,11 @@ function readOptions(options) {
|
|
|
116
158
|
};
|
|
117
159
|
}
|
|
118
160
|
/**
|
|
119
|
-
* @brief
|
|
161
|
+
* @brief Validate and normalize the requested message locale.
|
|
162
|
+
* @details Message helpers keep structured issues separate from human-readable formatting
|
|
163
|
+
* until callers request text.
|
|
164
|
+
* @param value Locale field from the public options object.
|
|
165
|
+
* @returns Built-in locale identifier, defaulting to English.
|
|
120
166
|
*/
|
|
121
167
|
function readLocale(value) {
|
|
122
168
|
if (value === undefined || value === "en") {
|
|
@@ -128,7 +174,12 @@ function readLocale(value) {
|
|
|
128
174
|
throw new TypeError("message locale must be en or ko");
|
|
129
175
|
}
|
|
130
176
|
/**
|
|
131
|
-
* @brief
|
|
177
|
+
* @brief Validate the optional user path formatter.
|
|
178
|
+
* @details The returned wrapper enforces the string return contract at the
|
|
179
|
+
* boundary where user code is invoked, keeping downstream template replacement
|
|
180
|
+
* code simple.
|
|
181
|
+
* @param value Formatter value from public options.
|
|
182
|
+
* @returns Safe formatter callback used by the renderer.
|
|
132
183
|
*/
|
|
133
184
|
function readPathFormatter(value) {
|
|
134
185
|
if (value === undefined) {
|
|
@@ -147,7 +198,12 @@ function readPathFormatter(value) {
|
|
|
147
198
|
};
|
|
148
199
|
}
|
|
149
200
|
/**
|
|
150
|
-
* @brief copy catalog.
|
|
201
|
+
* @brief Validate and copy a user message catalog.
|
|
202
|
+
* @details The renderer stores only recognized issue-code keys and accepted
|
|
203
|
+
* template forms. Copying also prevents later caller mutation from changing
|
|
204
|
+
* messages during validation.
|
|
205
|
+
* @param value Candidate catalog object.
|
|
206
|
+
* @returns Catalog copy accepted by the renderer.
|
|
151
207
|
*/
|
|
152
208
|
function copyCatalog(value) {
|
|
153
209
|
if (!isRecord(value)) {
|
|
@@ -172,13 +228,21 @@ function copyCatalog(value) {
|
|
|
172
228
|
return copied;
|
|
173
229
|
}
|
|
174
230
|
/**
|
|
175
|
-
* @brief is
|
|
231
|
+
* @brief Check whether a catalog value is an accepted template form.
|
|
232
|
+
* @details Message helpers keep structured issues separate from human-readable formatting
|
|
233
|
+
* until callers request text.
|
|
234
|
+
* @param value Candidate catalog entry value.
|
|
235
|
+
* @returns True for string templates or formatter functions.
|
|
176
236
|
*/
|
|
177
237
|
function isIssueMessageTemplate(value) {
|
|
178
238
|
return typeof value === "string" || typeof value === "function";
|
|
179
239
|
}
|
|
180
240
|
/**
|
|
181
|
-
* @brief
|
|
241
|
+
* @brief Render a TypeSea issue path using JSON-like bracket segments.
|
|
242
|
+
* @details The root is `$`, numeric segments render as indexes, and string
|
|
243
|
+
* segments are JSON-escaped so dots or brackets in field names stay unambiguous.
|
|
244
|
+
* @param path Issue path to render.
|
|
245
|
+
* @returns Stable path string for message templates.
|
|
182
246
|
*/
|
|
183
247
|
function defaultPathFormatter(path) {
|
|
184
248
|
if (path.length === 0) {
|
|
@@ -197,13 +261,16 @@ function defaultPathFormatter(path) {
|
|
|
197
261
|
return result;
|
|
198
262
|
}
|
|
199
263
|
/**
|
|
200
|
-
* @brief
|
|
264
|
+
* @brief Check record.
|
|
265
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
201
266
|
*/
|
|
202
267
|
function isRecord(value) {
|
|
203
268
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
204
269
|
}
|
|
205
270
|
/**
|
|
206
|
-
* @brief
|
|
271
|
+
* @brief Built-in English issue message catalog.
|
|
272
|
+
* @details Templates stay terse and token-based so the same renderer can handle
|
|
273
|
+
* built-in and user-defined catalogs without locale-specific code paths.
|
|
207
274
|
*/
|
|
208
275
|
const enCatalog = Object.freeze({
|
|
209
276
|
expected_string: "Expected string at {path}; received {actual}.",
|
|
@@ -232,7 +299,9 @@ const enCatalog = Object.freeze({
|
|
|
232
299
|
unrecognized_key: "Unrecognized key at {path}; expected {expected}."
|
|
233
300
|
});
|
|
234
301
|
/**
|
|
235
|
-
* @brief
|
|
302
|
+
* @brief Built-in Korean issue message catalog.
|
|
303
|
+
* @details The catalog mirrors English issue-code coverage exactly so locale
|
|
304
|
+
* switching cannot expose missing template keys at runtime.
|
|
236
305
|
*/
|
|
237
306
|
const koCatalog = Object.freeze({
|
|
238
307
|
expected_string: "{path}에서 문자열이 필요하지만 {actual}을 받았습니다.",
|
|
@@ -261,7 +330,9 @@ const koCatalog = Object.freeze({
|
|
|
261
330
|
unrecognized_key: "{path}에서 알 수 없는 키입니다. 기대값은 {expected}입니다."
|
|
262
331
|
});
|
|
263
332
|
/**
|
|
264
|
-
* @brief
|
|
333
|
+
* @brief Frozen lookup table for built-in message catalogs.
|
|
334
|
+
* @details The table is keyed by normalized locale values, letting renderIssue
|
|
335
|
+
* index without optional fallback logic after option resolution.
|
|
265
336
|
*/
|
|
266
337
|
const defaultCatalogs = Object.freeze({
|
|
267
338
|
en: enCatalog,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file algebraic.ts
|
|
3
|
+
* @brief Boolean algebra simplification for validation predicates.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
6
|
+
*/
|
|
7
|
+
import { NodeTag } from "../kind/index.js";
|
|
8
|
+
import type { GraphNode, NodeId } from "../ir/index.js";
|
|
9
|
+
export interface AlgebraicFold {
|
|
10
|
+
/**
|
|
11
|
+
* @brief True when an And fold has proven false.
|
|
12
|
+
* @details The caller replaces the whole conjunction with a constant false node.
|
|
13
|
+
*/
|
|
14
|
+
readonly contradiction: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* @brief True when an Or fold has proven true.
|
|
17
|
+
* @details The caller replaces the whole disjunction with a constant true node.
|
|
18
|
+
*/
|
|
19
|
+
readonly tautology: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* @brief Remaining operand ids after algebraic simplification.
|
|
22
|
+
* @details Operand order is preserved so generated code keeps stable branch ordering.
|
|
23
|
+
*/
|
|
24
|
+
readonly values: readonly NodeId[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @brief Flatten nested boolean folds of the same kind.
|
|
28
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
29
|
+
* before code generation consumes the graph.
|
|
30
|
+
* @param values Input operand ids.
|
|
31
|
+
* @param nodes Graph node table used to inspect nested folds.
|
|
32
|
+
* @param tag Boolean fold kind to flatten.
|
|
33
|
+
* @returns Operand list with same-kind nested folds expanded in place.
|
|
34
|
+
*/
|
|
35
|
+
export declare function flattenBooleanValues(values: readonly NodeId[], nodes: readonly GraphNode[], tag: typeof NodeTag.And | typeof NodeTag.Or): readonly NodeId[];
|
|
36
|
+
/**
|
|
37
|
+
* @brief Simplify operands of an And fold.
|
|
38
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
39
|
+
* before code generation consumes the graph.
|
|
40
|
+
* @param values Input operand ids.
|
|
41
|
+
* @param nodes Graph node table used to inspect nested complement forms.
|
|
42
|
+
* @returns Simplification result with contradiction status and kept operands.
|
|
43
|
+
*/
|
|
44
|
+
export declare function simplifyAndValues(values: readonly NodeId[], nodes: readonly GraphNode[]): AlgebraicFold;
|
|
45
|
+
/**
|
|
46
|
+
* @brief Simplify operands of an Or fold.
|
|
47
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
48
|
+
* before code generation consumes the graph.
|
|
49
|
+
* @param values Input operand ids.
|
|
50
|
+
* @param nodes Graph node table used to inspect nested complement forms.
|
|
51
|
+
* @returns Simplification result with tautology status and kept operands.
|
|
52
|
+
*/
|
|
53
|
+
export declare function simplifyOrValues(values: readonly NodeId[], nodes: readonly GraphNode[]): AlgebraicFold;
|
|
54
|
+
//# sourceMappingURL=algebraic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"algebraic.d.ts","sourceRoot":"","sources":["../../src/optimize/algebraic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EACR,SAAS,EACT,MAAM,EACT,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,aAAa;IAC1B;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAChC,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,GAAG,EAAE,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,EAAE,GAC5C,SAAS,MAAM,EAAE,CAmBnB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,SAAS,EAAE,GAC5B,aAAa,CAuCf;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,SAAS,EAAE,GAC5B,aAAa,CAuCf"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file algebraic.ts
|
|
3
|
+
* @brief Boolean algebra simplification for validation predicates.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
6
|
+
*/
|
|
7
|
+
import { NodeTag } from "../kind/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* @brief Flatten nested boolean folds of the same kind.
|
|
10
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
11
|
+
* before code generation consumes the graph.
|
|
12
|
+
* @param values Input operand ids.
|
|
13
|
+
* @param nodes Graph node table used to inspect nested folds.
|
|
14
|
+
* @param tag Boolean fold kind to flatten.
|
|
15
|
+
* @returns Operand list with same-kind nested folds expanded in place.
|
|
16
|
+
*/
|
|
17
|
+
export function flattenBooleanValues(values, nodes, tag) {
|
|
18
|
+
const flattened = [];
|
|
19
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
20
|
+
const value = values[index];
|
|
21
|
+
if (value === undefined) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const node = nodes[value];
|
|
25
|
+
if (node?.tag === tag) {
|
|
26
|
+
/*
|
|
27
|
+
* And(And(a,b),c) and Or(Or(a,b),c) are associative. Flattening
|
|
28
|
+
* reduces later duplicate and complement checks to one linear pass.
|
|
29
|
+
*/
|
|
30
|
+
appendFlattenedBooleanValues(flattened, node.values, nodes, tag);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
flattened.push(value);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return flattened;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @brief Simplify operands of an And fold.
|
|
40
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
41
|
+
* before code generation consumes the graph.
|
|
42
|
+
* @param values Input operand ids.
|
|
43
|
+
* @param nodes Graph node table used to inspect nested complement forms.
|
|
44
|
+
* @returns Simplification result with contradiction status and kept operands.
|
|
45
|
+
*/
|
|
46
|
+
export function simplifyAndValues(values, nodes) {
|
|
47
|
+
const kept = [];
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
const positive = new Set();
|
|
50
|
+
const negative = new Set();
|
|
51
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
52
|
+
const value = values[index];
|
|
53
|
+
if (value === undefined || seen.has(value)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (isAbsorbedAndValue(value, nodes, seen)) {
|
|
57
|
+
/*
|
|
58
|
+
* a && (a || b) is equivalent to a. The Or branch cannot make the
|
|
59
|
+
* validation stricter once the shared value is already required.
|
|
60
|
+
*/
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (hasComplementConflict(value, nodes, positive, negative)) {
|
|
64
|
+
/*
|
|
65
|
+
* a && !a is impossible for side-effect-free predicate nodes. Only
|
|
66
|
+
* complement-safe nodes are allowed into the positive/negative sets.
|
|
67
|
+
*/
|
|
68
|
+
return {
|
|
69
|
+
contradiction: true,
|
|
70
|
+
tautology: false,
|
|
71
|
+
values: []
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
rememberComplementValue(value, nodes, positive, negative);
|
|
75
|
+
seen.add(value);
|
|
76
|
+
kept.push(value);
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
contradiction: false,
|
|
80
|
+
tautology: false,
|
|
81
|
+
values: kept
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* @brief Simplify operands of an Or fold.
|
|
86
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
87
|
+
* before code generation consumes the graph.
|
|
88
|
+
* @param values Input operand ids.
|
|
89
|
+
* @param nodes Graph node table used to inspect nested complement forms.
|
|
90
|
+
* @returns Simplification result with tautology status and kept operands.
|
|
91
|
+
*/
|
|
92
|
+
export function simplifyOrValues(values, nodes) {
|
|
93
|
+
const kept = [];
|
|
94
|
+
const seen = new Set();
|
|
95
|
+
const positive = new Set();
|
|
96
|
+
const negative = new Set();
|
|
97
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
98
|
+
const value = values[index];
|
|
99
|
+
if (value === undefined || seen.has(value)) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (isAbsorbedOrValue(value, nodes, seen)) {
|
|
103
|
+
/*
|
|
104
|
+
* a || (a && b) is equivalent to a. The And branch cannot widen the
|
|
105
|
+
* accepted set once the shared value already passes.
|
|
106
|
+
*/
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (hasComplementConflict(value, nodes, positive, negative)) {
|
|
110
|
+
/*
|
|
111
|
+
* a || !a is always true for complement-safe predicates, so the Or
|
|
112
|
+
* fold can collapse to a tautology.
|
|
113
|
+
*/
|
|
114
|
+
return {
|
|
115
|
+
contradiction: false,
|
|
116
|
+
tautology: true,
|
|
117
|
+
values: []
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
rememberComplementValue(value, nodes, positive, negative);
|
|
121
|
+
seen.add(value);
|
|
122
|
+
kept.push(value);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
contradiction: false,
|
|
126
|
+
tautology: false,
|
|
127
|
+
values: kept
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* @brief Recursively append flattened operands.
|
|
132
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
133
|
+
* before code generation consumes the graph.
|
|
134
|
+
* @param output Destination operand list.
|
|
135
|
+
* @param values Source operand ids.
|
|
136
|
+
* @param nodes Graph node table used to inspect nested folds.
|
|
137
|
+
* @param tag Boolean fold kind to flatten.
|
|
138
|
+
*/
|
|
139
|
+
function appendFlattenedBooleanValues(output, values, nodes, tag) {
|
|
140
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
141
|
+
const value = values[index];
|
|
142
|
+
if (value === undefined) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const node = nodes[value];
|
|
146
|
+
if (node?.tag === tag) {
|
|
147
|
+
appendFlattenedBooleanValues(output, node.values, nodes, tag);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
output.push(value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* @brief Test And absorption for `a && (a || b)`.
|
|
156
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
157
|
+
* before code generation consumes the graph.
|
|
158
|
+
* @param value Candidate operand id.
|
|
159
|
+
* @param nodes Graph node table.
|
|
160
|
+
* @param seen Operands already kept by the parent And.
|
|
161
|
+
* @returns True when the candidate is redundant.
|
|
162
|
+
*/
|
|
163
|
+
function isAbsorbedAndValue(value, nodes, seen) {
|
|
164
|
+
const node = nodes[value];
|
|
165
|
+
if (node?.tag !== NodeTag.Or) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return containsSeenValue(node.values, seen);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* @brief Test Or absorption for `a || (a && b)`.
|
|
172
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
173
|
+
* before code generation consumes the graph.
|
|
174
|
+
* @param value Candidate operand id.
|
|
175
|
+
* @param nodes Graph node table.
|
|
176
|
+
* @param seen Operands already kept by the parent Or.
|
|
177
|
+
* @returns True when the candidate is redundant.
|
|
178
|
+
*/
|
|
179
|
+
function isAbsorbedOrValue(value, nodes, seen) {
|
|
180
|
+
const node = nodes[value];
|
|
181
|
+
if (node?.tag !== NodeTag.And) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
return containsSeenValue(node.values, seen);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* @brief Test whether a nested fold contains an operand already kept.
|
|
188
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
189
|
+
* before code generation consumes the graph.
|
|
190
|
+
* @param values Nested fold operand ids.
|
|
191
|
+
* @param seen Parent fold operands already kept.
|
|
192
|
+
* @returns True when the nested fold repeats a kept operand.
|
|
193
|
+
*/
|
|
194
|
+
function containsSeenValue(values, seen) {
|
|
195
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
196
|
+
const value = values[index];
|
|
197
|
+
if (value !== undefined && seen.has(value)) {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* @brief Detect a positive/negative complement conflict.
|
|
205
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
206
|
+
* before code generation consumes the graph.
|
|
207
|
+
* @param value Candidate operand id.
|
|
208
|
+
* @param nodes Graph node table.
|
|
209
|
+
* @param positive Complement-safe positive operands already seen.
|
|
210
|
+
* @param negative Complement-safe negated operands already seen.
|
|
211
|
+
* @returns True when the candidate conflicts with prior operands.
|
|
212
|
+
*/
|
|
213
|
+
function hasComplementConflict(value, nodes, positive, negative) {
|
|
214
|
+
const negated = readNegatedValue(value, nodes);
|
|
215
|
+
if (negated !== undefined) {
|
|
216
|
+
return isComplementSafe(negated, nodes) && positive.has(negated);
|
|
217
|
+
}
|
|
218
|
+
return isComplementSafe(value, nodes) && negative.has(value);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* @brief Record a complement-safe operand in positive or negative form.
|
|
222
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
223
|
+
* before code generation consumes the graph.
|
|
224
|
+
* @param value Candidate operand id.
|
|
225
|
+
* @param nodes Graph node table.
|
|
226
|
+
* @param positive Mutable set for positive operands.
|
|
227
|
+
* @param negative Mutable set for negated operands.
|
|
228
|
+
*/
|
|
229
|
+
function rememberComplementValue(value, nodes, positive, negative) {
|
|
230
|
+
const negated = readNegatedValue(value, nodes);
|
|
231
|
+
if (negated !== undefined) {
|
|
232
|
+
if (isComplementSafe(negated, nodes)) {
|
|
233
|
+
negative.add(negated);
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (isComplementSafe(value, nodes)) {
|
|
238
|
+
positive.add(value);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* @brief Read the operand of a Not node.
|
|
243
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
244
|
+
* before code generation consumes the graph.
|
|
245
|
+
* @param value Candidate node id.
|
|
246
|
+
* @param nodes Graph node table.
|
|
247
|
+
* @returns Inner node id for Not, otherwise undefined.
|
|
248
|
+
*/
|
|
249
|
+
function readNegatedValue(value, nodes) {
|
|
250
|
+
const node = nodes[value];
|
|
251
|
+
return node?.tag === NodeTag.Not ? node.value : undefined;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* @brief Decide whether a node is safe for complement algebra.
|
|
255
|
+
* @details Only pure structural predicates are allowed. Nodes that inspect user
|
|
256
|
+
* predicates or nested graph execution stay out of `a`/`!a` folding.
|
|
257
|
+
* @param value Candidate node id.
|
|
258
|
+
* @param nodes Graph node table.
|
|
259
|
+
* @returns True when complement laws can be applied to the node.
|
|
260
|
+
*/
|
|
261
|
+
function isComplementSafe(value, nodes) {
|
|
262
|
+
const node = nodes[value];
|
|
263
|
+
if (node === undefined) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
switch (node.tag) {
|
|
267
|
+
case NodeTag.Const:
|
|
268
|
+
return typeof node.value === "boolean";
|
|
269
|
+
case NodeTag.IsString:
|
|
270
|
+
case NodeTag.IsNumber:
|
|
271
|
+
case NodeTag.IsBoolean:
|
|
272
|
+
case NodeTag.IsBigInt:
|
|
273
|
+
case NodeTag.IsSymbol:
|
|
274
|
+
case NodeTag.IsObject:
|
|
275
|
+
case NodeTag.IsArray:
|
|
276
|
+
case NodeTag.IsUndefined:
|
|
277
|
+
case NodeTag.IsNull:
|
|
278
|
+
case NodeTag.IsInteger:
|
|
279
|
+
case NodeTag.Equals:
|
|
280
|
+
case NodeTag.Gte:
|
|
281
|
+
case NodeTag.Lte:
|
|
282
|
+
case NodeTag.StringMin:
|
|
283
|
+
case NodeTag.StringMax:
|
|
284
|
+
case NodeTag.Regex:
|
|
285
|
+
case NodeTag.HasOwn:
|
|
286
|
+
case NodeTag.HasOwnData:
|
|
287
|
+
case NodeTag.StrictKeys:
|
|
288
|
+
return true;
|
|
289
|
+
case NodeTag.Not:
|
|
290
|
+
return isComplementSafe(node.value, nodes);
|
|
291
|
+
case NodeTag.And:
|
|
292
|
+
case NodeTag.Or:
|
|
293
|
+
return areComplementSafeValues(node.values, nodes);
|
|
294
|
+
default:
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* @brief Decide whether every value in a boolean fold is complement-safe.
|
|
300
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
301
|
+
* before code generation consumes the graph.
|
|
302
|
+
* @param values Operand ids from a nested fold.
|
|
303
|
+
* @param nodes Graph node table.
|
|
304
|
+
* @returns True when the whole nested fold can participate in complement laws.
|
|
305
|
+
*/
|
|
306
|
+
function areComplementSafeValues(values, nodes) {
|
|
307
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
308
|
+
const value = values[index];
|
|
309
|
+
if (value === undefined || !isComplementSafe(value, nodes)) {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file compact.ts
|
|
3
3
|
* @brief Reachability compaction for optimized graphs.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
4
6
|
*/
|
|
5
7
|
import type { Graph } from "../ir/index.js";
|
|
6
8
|
/**
|
|
7
|
-
* @brief
|
|
9
|
+
* @brief Remove unreachable IR nodes and remap the remaining node ids densely.
|
|
10
|
+
* @details Earlier optimizer passes may leave replaced nodes in the arena so
|
|
11
|
+
* alias bookkeeping stays simple. This pass is the boundary that rewrites the
|
|
12
|
+
* graph back into the dense id space expected by codegen and public graph reads.
|
|
13
|
+
* @param graph Graph produced by earlier optimizer passes.
|
|
14
|
+
* @returns Graph containing only nodes reachable from entry and result.
|
|
8
15
|
*/
|
|
9
16
|
export declare function compactReachable(graph: Graph): Graph;
|
|
10
17
|
//# sourceMappingURL=compact.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/optimize/compact.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/optimize/compact.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,gBAAgB,CAAC;AAG/D;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAyBpD"}
|
package/dist/optimize/compact.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file compact.ts
|
|
3
3
|
* @brief Reachability compaction for optimized graphs.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
4
6
|
*/
|
|
5
7
|
import { remapId, remapNode } from "./remap.js";
|
|
6
8
|
/**
|
|
7
|
-
* @brief
|
|
9
|
+
* @brief Remove unreachable IR nodes and remap the remaining node ids densely.
|
|
10
|
+
* @details Earlier optimizer passes may leave replaced nodes in the arena so
|
|
11
|
+
* alias bookkeeping stays simple. This pass is the boundary that rewrites the
|
|
12
|
+
* graph back into the dense id space expected by codegen and public graph reads.
|
|
13
|
+
* @param graph Graph produced by earlier optimizer passes.
|
|
14
|
+
* @returns Graph containing only nodes reachable from entry and result.
|
|
8
15
|
*/
|
|
9
16
|
export function compactReachable(graph) {
|
|
10
17
|
const reachable = markReachable(graph);
|
|
@@ -33,7 +40,11 @@ export function compactReachable(graph) {
|
|
|
33
40
|
};
|
|
34
41
|
}
|
|
35
42
|
/**
|
|
36
|
-
* @brief
|
|
43
|
+
* @brief Mark graph nodes reachable from the entry and result roots.
|
|
44
|
+
* @details The scan walks dependency edges with an explicit stack to avoid
|
|
45
|
+
* recursion limits on large generated schemas.
|
|
46
|
+
* @param graph Graph to scan.
|
|
47
|
+
* @returns Boolean reachability bitmap aligned with the original node table.
|
|
37
48
|
*/
|
|
38
49
|
function markReachable(graph) {
|
|
39
50
|
const reachable = new Array(graph.nodes.length).fill(false);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file domain.ts
|
|
3
|
+
* @brief Validation-domain specialization for dispatch child graphs.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
6
|
+
*/
|
|
7
|
+
import type { Graph } from "../ir/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* @brief Specialize nested validation graphs with domain knowledge.
|
|
10
|
+
* @details Dispatch nodes already know the primitive domain of each child arm.
|
|
11
|
+
* This pass pushes that fact into child graphs so redundant type checks collapse.
|
|
12
|
+
* @param graph Root graph to specialize.
|
|
13
|
+
* @returns The original graph when no node changed, otherwise a rewritten graph.
|
|
14
|
+
*/
|
|
15
|
+
export declare function specializeDomains(graph: Graph): Graph;
|
|
16
|
+
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/optimize/domain.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAER,KAAK,EAIR,MAAM,gBAAgB,CAAC;AAiDxB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAsBrD"}
|