@velarscript/compiler 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advisory-suppression.d.ts +62 -0
- package/dist/advisory-suppression.d.ts.map +1 -0
- package/dist/advisory-suppression.js +179 -0
- package/dist/advisory-suppression.js.map +1 -0
- package/dist/analyzer.d.ts +405 -17
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +1755 -211
- package/dist/analyzer.js.map +1 -1
- package/dist/ast.d.ts +6 -3
- package/dist/ast.d.ts.map +1 -1
- package/dist/ast.js.map +1 -1
- package/dist/binding-stability.d.ts +22 -0
- package/dist/binding-stability.d.ts.map +1 -0
- package/dist/binding-stability.js +63 -0
- package/dist/binding-stability.js.map +1 -0
- package/dist/collection-lowering-runtime.d.ts +1 -1
- package/dist/collection-lowering-runtime.d.ts.map +1 -1
- package/dist/collection-lowering-runtime.js +183 -56
- package/dist/collection-lowering-runtime.js.map +1 -1
- package/dist/diagnostic.d.ts +34 -0
- package/dist/diagnostic.d.ts.map +1 -1
- package/dist/diagnostic.js +11 -1
- package/dist/diagnostic.js.map +1 -1
- package/dist/embedded-javascript.d.ts +12 -1
- package/dist/embedded-javascript.d.ts.map +1 -1
- package/dist/embedded-javascript.js +111 -2
- package/dist/embedded-javascript.js.map +1 -1
- package/dist/embedded-module.d.ts.map +1 -1
- package/dist/embedded-module.js +22 -0
- package/dist/embedded-module.js.map +1 -1
- package/dist/emitter.d.ts +83 -1
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +518 -41
- package/dist/emitter.js.map +1 -1
- package/dist/error-runtime.d.ts +9 -0
- package/dist/error-runtime.d.ts.map +1 -1
- package/dist/error-runtime.js +21 -0
- package/dist/error-runtime.js.map +1 -1
- package/dist/extension.d.ts +5 -2
- package/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +2 -1
- package/dist/extension.js.map +1 -1
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +222 -91
- package/dist/formatter.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -5
- package/dist/index.js.map +1 -1
- package/dist/interpolated-string.d.ts.map +1 -1
- package/dist/interpolated-string.js +29 -2
- package/dist/interpolated-string.js.map +1 -1
- package/dist/json-runtime.d.ts.map +1 -1
- package/dist/json-runtime.js +27 -3
- package/dist/json-runtime.js.map +1 -1
- package/dist/lexer.d.ts +217 -1
- package/dist/lexer.d.ts.map +1 -1
- package/dist/lexer.js +799 -37
- package/dist/lexer.js.map +1 -1
- package/dist/limits.d.ts +9 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +9 -0
- package/dist/limits.js.map +1 -1
- package/dist/mechanical-fix.d.ts.map +1 -1
- package/dist/mechanical-fix.js +38 -0
- package/dist/mechanical-fix.js.map +1 -1
- package/dist/parser.d.ts +30 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +137 -21
- package/dist/parser.js.map +1 -1
- package/dist/promise-runtime.d.ts +20 -1
- package/dist/promise-runtime.d.ts.map +1 -1
- package/dist/promise-runtime.js +38 -3
- package/dist/promise-runtime.js.map +1 -1
- package/dist/reactive-bridge-runtime.d.ts.map +1 -1
- package/dist/reactive-bridge-runtime.js +7 -1
- package/dist/reactive-bridge-runtime.js.map +1 -1
- package/dist/runtime-abi.d.ts +21 -1
- package/dist/runtime-abi.d.ts.map +1 -1
- package/dist/runtime-abi.js +23 -3
- package/dist/runtime-abi.js.map +1 -1
- package/dist/source-names.d.ts +26 -0
- package/dist/source-names.d.ts.map +1 -1
- package/dist/source-names.js +49 -5
- package/dist/source-names.js.map +1 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +13 -0
- package/dist/source.js.map +1 -1
- package/dist/stable-order.d.ts +16 -0
- package/dist/stable-order.d.ts.map +1 -0
- package/dist/stable-order.js +18 -0
- package/dist/stable-order.js.map +1 -0
- package/dist/text-runtime.d.ts.map +1 -1
- package/dist/text-runtime.js +182 -41
- package/dist/text-runtime.js.map +1 -1
- package/dist/token.d.ts +11 -0
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js.map +1 -1
- package/dist/type-registry-runtime.d.ts.map +1 -1
- package/dist/type-registry-runtime.js +8 -1
- package/dist/type-registry-runtime.js.map +1 -1
- package/dist/type-validation-runtime.d.ts.map +1 -1
- package/dist/type-validation-runtime.js +129 -1
- package/dist/type-validation-runtime.js.map +1 -1
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +161 -17
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/dist/text-runtime.js
CHANGED
|
@@ -6,6 +6,7 @@ const __velarTextNativeString = globalThis.String;
|
|
|
6
6
|
const __velarTextNativeNumber = globalThis.Number;
|
|
7
7
|
const __velarTextNativeMath = globalThis.Math;
|
|
8
8
|
const __velarTextNativeObject = globalThis.Object;
|
|
9
|
+
const __velarTextNativeMap = globalThis.Map;
|
|
9
10
|
const __velarTextNativeTypeError = globalThis.TypeError;
|
|
10
11
|
const __velarTextNativeRangeError = globalThis.RangeError;
|
|
11
12
|
const __velarTextGetOwnPropertyDescriptor = __velarTextNativeObject.getOwnPropertyDescriptor;
|
|
@@ -25,9 +26,12 @@ const __velarNativeStringTrim = __velarTextGetOwnPropertyDescriptor(__velarTextS
|
|
|
25
26
|
const __velarNativeStringUpper = __velarTextGetOwnPropertyDescriptor(__velarTextStringPrototype, "toUpperCase")?.value;
|
|
26
27
|
const __velarNativeStringLower = __velarTextGetOwnPropertyDescriptor(__velarTextStringPrototype, "toLowerCase")?.value;
|
|
27
28
|
const __velarNativeStringSplit = __velarTextGetOwnPropertyDescriptor(__velarTextStringPrototype, "split")?.value;
|
|
28
|
-
const __velarNativeStringReplace = __velarTextGetOwnPropertyDescriptor(__velarTextStringPrototype, "replace")?.value;
|
|
29
29
|
const __velarNativeStringReplaceAll = __velarTextGetOwnPropertyDescriptor(__velarTextStringPrototype, "replaceAll")?.value;
|
|
30
30
|
const __velarNativeStringRepeat = __velarTextGetOwnPropertyDescriptor(__velarTextStringPrototype, "repeat")?.value;
|
|
31
|
+
const __velarTextMapPrototype = typeof __velarTextNativeMap === "function" ? __velarTextGetOwnPropertyDescriptor(__velarTextNativeMap, "prototype")?.value : null;
|
|
32
|
+
const __velarTextMapGet = __velarTextMapPrototype ? __velarTextGetOwnPropertyDescriptor(__velarTextMapPrototype, "get")?.value : null;
|
|
33
|
+
const __velarTextMapSet = __velarTextMapPrototype ? __velarTextGetOwnPropertyDescriptor(__velarTextMapPrototype, "set")?.value : null;
|
|
34
|
+
const __velarTextMapClear = __velarTextMapPrototype ? __velarTextGetOwnPropertyDescriptor(__velarTextMapPrototype, "clear")?.value : null;
|
|
31
35
|
const __velarTextSurrogatePattern = /[\u{10000}-\u{10FFFF}\uD800-\uDFFF]/u;
|
|
32
36
|
const __velarTextRegExpPrototype = typeof __velarTextRuntimeGetPrototypeOf === "function" ? __velarTextRuntimeGetPrototypeOf(__velarTextSurrogatePattern) : null;
|
|
33
37
|
const __velarTextSurrogateExec = __velarTextRegExpPrototype ? __velarTextGetOwnPropertyDescriptor(__velarTextRegExpPrototype, "exec")?.value : null;
|
|
@@ -66,48 +70,146 @@ function __velarTextNextCodePointOffset(value, offset) {
|
|
|
66
70
|
const second = __velarTextCall(__velarNativeStringCharCodeAt, value, [offset + 1]);
|
|
67
71
|
return second >= 0xDC00 && second <= 0xDFFF ? offset + 2 : offset + 1;
|
|
68
72
|
}
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
// D90 R7, performance half. Measuring a string used to be a whole-string job
|
|
74
|
+
// every single time: the surrogate probe ran per call, and one astral character
|
|
75
|
+
// anywhere forced every offset conversion to walk code points from zero, which
|
|
76
|
+
// made a loop of char/slice calls quadratic: 20,000 char/slice calls over a
|
|
77
|
+
// 200 KiB string with one leading astral character took 17.1 s, and 34 ms
|
|
78
|
+
// once measurement was memoised. A measurement is a pure function of an
|
|
79
|
+
// immutable value, so it is memoised: a dense string answers offset conversions in
|
|
80
|
+
// O(1) when no surrogate pair splits it, and otherwise the checkpoint list
|
|
81
|
+
// records the code-unit offset of every stride-th code point so a conversion
|
|
82
|
+
// starts from the nearest checkpoint instead of from the start of the string.
|
|
83
|
+
// The cache may only change the cost of an answer, never the answer.
|
|
84
|
+
const __velarTextCheckpointStride = 64;
|
|
85
|
+
const __velarTextMeasureMinimumUnits = 64;
|
|
86
|
+
// The cache holds its keys strongly, so its budget is memory the program has
|
|
87
|
+
// stopped using but cannot reclaim. Eight MiB buys the loops that matter and
|
|
88
|
+
// bounds what a document-processing program leaves behind; a single string
|
|
89
|
+
// larger than the budget still measures once and stays, because evicting the
|
|
90
|
+
// string a loop is walking would put the cliff back. The entry count only
|
|
91
|
+
// bounds the cache's own bookkeeping, so it is set well above the number of
|
|
92
|
+
// strings a loop cycles through: a tighter count made a walk over 65 short
|
|
93
|
+
// strings 15x slower than the same walk over 64.
|
|
94
|
+
const __velarTextMeasureCacheEntries = 512;
|
|
95
|
+
const __velarTextMeasureCacheUnits = 8 * 1024 * 1024;
|
|
96
|
+
const __velarTextMeasureCache = typeof __velarTextNativeMap === "function"
|
|
97
|
+
&& typeof __velarTextMapGet === "function" && typeof __velarTextMapSet === "function" && typeof __velarTextMapClear === "function"
|
|
98
|
+
? new __velarTextNativeMap() : null;
|
|
99
|
+
let __velarTextMeasureCacheCount = 0;
|
|
100
|
+
let __velarTextMeasureCacheHeld = 0;
|
|
101
|
+
function __velarTextMeasureText(value) {
|
|
102
|
+
if (__velarTextCall(__velarTextSurrogateExec, __velarTextSurrogatePattern, [value]) === null) {
|
|
103
|
+
return { length: value.length, dense: true, checkpoints: null };
|
|
104
|
+
}
|
|
105
|
+
const checkpoints = new __velarTextNativeArray();
|
|
71
106
|
let length = 0, offset = 0;
|
|
72
|
-
while (offset < value.length) {
|
|
73
|
-
|
|
107
|
+
while (offset < value.length) {
|
|
108
|
+
if (length % __velarTextCheckpointStride === 0) checkpoints[length / __velarTextCheckpointStride] = offset;
|
|
109
|
+
offset = __velarTextNextCodePointOffset(value, offset);
|
|
110
|
+
length += 1;
|
|
111
|
+
}
|
|
112
|
+
// A string that carries only unpaired surrogates still has one unit per code
|
|
113
|
+
// point, so it keeps the O(1) path even though the probe matched.
|
|
114
|
+
return { length: length, dense: length === value.length, checkpoints: checkpoints };
|
|
74
115
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
116
|
+
function __velarTextMeasure(value) {
|
|
117
|
+
if (__velarTextMeasureCache === null || value.length < __velarTextMeasureMinimumUnits) return __velarTextMeasureText(value);
|
|
118
|
+
const cached = __velarTextCall(__velarTextMapGet, __velarTextMeasureCache, [value]);
|
|
119
|
+
if (cached !== undefined) return cached;
|
|
120
|
+
const measured = __velarTextMeasureText(value);
|
|
121
|
+
if (__velarTextMeasureCacheCount >= __velarTextMeasureCacheEntries
|
|
122
|
+
|| (__velarTextMeasureCacheCount > 0 && __velarTextMeasureCacheHeld + value.length > __velarTextMeasureCacheUnits)) {
|
|
123
|
+
__velarTextCall(__velarTextMapClear, __velarTextMeasureCache, []);
|
|
124
|
+
__velarTextMeasureCacheCount = 0;
|
|
125
|
+
__velarTextMeasureCacheHeld = 0;
|
|
126
|
+
}
|
|
127
|
+
__velarTextCall(__velarTextMapSet, __velarTextMeasureCache, [value, measured]);
|
|
128
|
+
__velarTextMeasureCacheCount += 1;
|
|
129
|
+
__velarTextMeasureCacheHeld += value.length;
|
|
130
|
+
return measured;
|
|
131
|
+
}
|
|
132
|
+
function __velarTextCodePointLength(value) {
|
|
133
|
+
return __velarTextMeasure(value).length;
|
|
86
134
|
}
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
135
|
+
function __velarTextCodePointPrefix(value, count) { return __velarTextCall(__velarNativeStringSlice, value, [0, __velarTextCodeUnitOffset(value, count)]); }
|
|
136
|
+
function __velarTextCodeUnitOffset(value, position) {
|
|
137
|
+
const measured = __velarTextMeasure(value);
|
|
138
|
+
if (measured.dense) return position < value.length ? position : value.length;
|
|
139
|
+
if (position <= 0) return 0;
|
|
140
|
+
const checkpoints = measured.checkpoints;
|
|
141
|
+
let block = __velarTextCall(__velarTextMathFloor, __velarTextNativeMath, [position / __velarTextCheckpointStride]);
|
|
142
|
+
if (block >= checkpoints.length) block = checkpoints.length - 1;
|
|
143
|
+
let offset = checkpoints[block], current = block * __velarTextCheckpointStride;
|
|
90
144
|
while (offset < value.length && current < position) { offset = __velarTextNextCodePointOffset(value, offset); current += 1; }
|
|
91
145
|
return offset;
|
|
92
146
|
}
|
|
93
|
-
function __velarTextCodePointIndex(value, unitOffset
|
|
94
|
-
|
|
95
|
-
|
|
147
|
+
function __velarTextCodePointIndex(value, unitOffset) {
|
|
148
|
+
const measured = __velarTextMeasure(value);
|
|
149
|
+
if (measured.dense) return unitOffset <= value.length ? unitOffset : null;
|
|
150
|
+
if (unitOffset < 0 || unitOffset > value.length) return null;
|
|
151
|
+
const checkpoints = measured.checkpoints;
|
|
152
|
+
let low = 0, high = checkpoints.length - 1;
|
|
153
|
+
while (low < high) {
|
|
154
|
+
const middle = low + __velarTextCall(__velarTextMathFloor, __velarTextNativeMath, [(high - low + 1) / 2]);
|
|
155
|
+
if (checkpoints[middle] <= unitOffset) low = middle; else high = middle - 1;
|
|
156
|
+
}
|
|
157
|
+
let offset = checkpoints[low], position = low * __velarTextCheckpointStride;
|
|
96
158
|
while (offset < unitOffset && offset < value.length) { offset = __velarTextNextCodePointOffset(value, offset); position += 1; }
|
|
97
159
|
return offset === unitOffset ? position : null;
|
|
98
160
|
}
|
|
99
161
|
function __velarTextCodePointDistance(value, start, end) {
|
|
162
|
+
if (__velarTextMeasure(value).dense) return end >= start ? end - start : null;
|
|
100
163
|
let offset = start, distance = 0;
|
|
101
164
|
while (offset < end) { offset = __velarTextNextCodePointOffset(value, offset); distance += 1; }
|
|
102
165
|
return offset === end ? distance : null;
|
|
103
166
|
}
|
|
167
|
+
// D90 R7: a code-unit offset sits between two code points unless it splits a
|
|
168
|
+
// surrogate pair, and only an adjacent lead/trail pair can be split. The test
|
|
169
|
+
// is O(1), so every search below can reject a mid-pair hit without measuring
|
|
170
|
+
// the string.
|
|
171
|
+
function __velarTextIsBoundary(value, offset) {
|
|
172
|
+
if (offset <= 0 || offset >= value.length) return true;
|
|
173
|
+
const lead = __velarTextCall(__velarNativeStringCharCodeAt, value, [offset - 1]);
|
|
174
|
+
if (lead < 0xD800 || lead > 0xDBFF) return true;
|
|
175
|
+
const trail = __velarTextCall(__velarNativeStringCharCodeAt, value, [offset]);
|
|
176
|
+
return trail < 0xDC00 || trail > 0xDFFF;
|
|
177
|
+
}
|
|
178
|
+
// D90 R7, performance half. A match can only start inside a pair when the
|
|
179
|
+
// needle starts with a trail surrogate, and can only end inside one when the
|
|
180
|
+
// needle ends with a lead surrogate: the unit the gate reads at each end of a
|
|
181
|
+
// match is the needle's own edge unit. Both are properties of the needle
|
|
182
|
+
// alone, so one O(1) look says whether the native scan already answers what
|
|
183
|
+
// the bounded scan answers, and an ordinary needle keeps native speed on any
|
|
184
|
+
// haystack. The needle must not be empty; each caller handles that case.
|
|
185
|
+
function __velarTextNeedsBoundaryCheck(search) {
|
|
186
|
+
const first = __velarTextCall(__velarNativeStringCharCodeAt, search, [0]);
|
|
187
|
+
if (first >= 0xDC00 && first <= 0xDFFF) return true;
|
|
188
|
+
const last = __velarTextCall(__velarNativeStringCharCodeAt, search, [search.length - 1]);
|
|
189
|
+
return last >= 0xD800 && last <= 0xDBFF;
|
|
190
|
+
}
|
|
191
|
+
// Every search operation goes through here so that a match is accepted only
|
|
192
|
+
// when it starts and ends on a code-point boundary. A needle that begins or
|
|
193
|
+
// ends with an unpaired surrogate therefore never matches inside a pair, which
|
|
194
|
+
// is what keeps split/replace/replaceAll from manufacturing lone surrogates.
|
|
195
|
+
// The needle must not be empty; each caller handles that case in its own voice.
|
|
196
|
+
function __velarTextBoundedIndexOf(value, search, cursor) {
|
|
197
|
+
if (!__velarTextNeedsBoundaryCheck(search)) return __velarTextCall(__velarNativeStringIndexOf, value, [search, cursor]);
|
|
198
|
+
while (cursor <= value.length) {
|
|
199
|
+
const found = __velarTextCall(__velarNativeStringIndexOf, value, [search, cursor]);
|
|
200
|
+
if (found < 0) return -1;
|
|
201
|
+
if (__velarTextIsBoundary(value, found) && __velarTextIsBoundary(value, found + search.length)) return found;
|
|
202
|
+
cursor = found + 1;
|
|
203
|
+
}
|
|
204
|
+
return -1;
|
|
205
|
+
}
|
|
104
206
|
function __velarTextReplacementOutputUnits(value, search, replacement, all) {
|
|
105
207
|
let matches = 0;
|
|
106
208
|
if (search === "") matches = all ? __velarTextCodePointLength(value) + 1 : 1;
|
|
107
209
|
else {
|
|
108
210
|
let cursor = 0;
|
|
109
211
|
while (true) {
|
|
110
|
-
const index =
|
|
212
|
+
const index = __velarTextBoundedIndexOf(value, search, cursor);
|
|
111
213
|
if (index < 0) break;
|
|
112
214
|
matches += 1;
|
|
113
215
|
if (!all) break;
|
|
@@ -157,8 +259,14 @@ function __velarStringCompare(left, right) {
|
|
|
157
259
|
// which one is known only at runtime. A string pair keeps code-point order
|
|
158
260
|
// (TXT-D1); everything else uses the plain relational order, exactly as a
|
|
159
261
|
// monomorphic comparison of that category would.
|
|
262
|
+
// D90 R6: one NaN policy. A NaN may be held and tested with .isNaN(), but an
|
|
263
|
+
// operation that orders it raises instead of answering. Without this the
|
|
264
|
+
// "neither less nor greater" arm returned 0, which made NaN compare both <=
|
|
265
|
+
// and >= as true at a generic site while the same source on a plain number
|
|
266
|
+
// answered false, and produced genuinely mis-sorted output.
|
|
160
267
|
function __velarOrderCompare(left, right) {
|
|
161
268
|
if (typeof left === "string" && typeof right === "string") return __velarStringCompare(left, right);
|
|
269
|
+
if (left !== left || right !== right) throw new __velarTextNativeTypeError("ordered comparison found NaN, which has no ordering; drop it with filter(x => not x.isNaN()) or fix the upstream computation");
|
|
162
270
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
163
271
|
}
|
|
164
272
|
function __velarStringSize(value) { return __velarTextCodePointLength(__velarTextValue(value)); }
|
|
@@ -173,7 +281,7 @@ function __velarStringSlice(value, start = 0, end = null) {
|
|
|
173
281
|
if (!__velarTextCall(__velarTextNumberIsInteger, __velarTextNativeNumber, [start]) || !__velarTextCall(__velarTextNumberIsInteger, __velarTextNativeNumber, [end])) throw new __velarTextNativeTypeError("String.slice positions must be integers");
|
|
174
282
|
const first = start < 0 ? __velarTextCall(__velarTextMathMax, __velarTextNativeMath, [total + start, 0]) : __velarTextCall(__velarTextMathMin, __velarTextNativeMath, [start, total]);
|
|
175
283
|
const last = end < 0 ? __velarTextCall(__velarTextMathMax, __velarTextNativeMath, [total + end, 0]) : __velarTextCall(__velarTextMathMin, __velarTextNativeMath, [end, total]);
|
|
176
|
-
return __velarTextCall(__velarNativeStringSlice, value, [__velarTextCodeUnitOffset(value, first
|
|
284
|
+
return __velarTextCall(__velarNativeStringSlice, value, [__velarTextCodeUnitOffset(value, first), __velarTextCodeUnitOffset(value, last)]);
|
|
177
285
|
}
|
|
178
286
|
function __velarStringChar(value, index) {
|
|
179
287
|
value = __velarTextValue(value);
|
|
@@ -182,25 +290,23 @@ function __velarStringChar(value, index) {
|
|
|
182
290
|
if (index < 0) index += total;
|
|
183
291
|
if (index < 0) return null;
|
|
184
292
|
if (index >= total) return null;
|
|
185
|
-
const start = __velarTextCodeUnitOffset(value, index
|
|
293
|
+
const start = __velarTextCodeUnitOffset(value, index);
|
|
186
294
|
return __velarTextCall(__velarNativeStringSlice, value, [start, __velarTextNextCodePointOffset(value, start)]);
|
|
187
295
|
}
|
|
188
|
-
function __velarStringHas(value, text) {
|
|
296
|
+
function __velarStringHas(value, text) {
|
|
297
|
+
value = __velarTextValue(value); text = __velarTextArgument(text, "String.has text");
|
|
298
|
+
return text === "" || __velarTextBoundedIndexOf(value, text, 0) >= 0;
|
|
299
|
+
}
|
|
189
300
|
function __velarStringIndex(value, text, start = 0) {
|
|
190
301
|
value = __velarTextValue(value); text = __velarTextArgument(text, "String.index text");
|
|
191
302
|
if (!__velarTextCall(__velarTextNumberIsInteger, __velarTextNativeNumber, [start])) throw new __velarTextNativeTypeError("String.index start must be an integer");
|
|
192
303
|
const total = __velarTextCodePointLength(value);
|
|
193
304
|
const first = start < 0 ? __velarTextCall(__velarTextMathMax, __velarTextNativeMath, [total + start, 0]) : __velarTextCall(__velarTextMathMin, __velarTextNativeMath, [start, total]);
|
|
194
|
-
|
|
305
|
+
const cursor = __velarTextCodeUnitOffset(value, first);
|
|
195
306
|
if (text === "") return first;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const position = __velarTextCodePointIndex(value, found, total);
|
|
200
|
-
if (position !== null && __velarTextCodePointIndex(value, found + text.length, total) !== null) return position;
|
|
201
|
-
cursor = found + 1;
|
|
202
|
-
}
|
|
203
|
-
return null;
|
|
307
|
+
const found = __velarTextBoundedIndexOf(value, text, cursor);
|
|
308
|
+
if (found < 0) return null;
|
|
309
|
+
return __velarTextCodePointIndex(value, found);
|
|
204
310
|
}
|
|
205
311
|
function __velarStringCount(value, text) {
|
|
206
312
|
value = __velarTextValue(value); text = __velarTextArgument(text, "String.count text");
|
|
@@ -208,7 +314,7 @@ function __velarStringCount(value, text) {
|
|
|
208
314
|
let count = 0;
|
|
209
315
|
let cursor = 0;
|
|
210
316
|
while (true) {
|
|
211
|
-
const index =
|
|
317
|
+
const index = __velarTextBoundedIndexOf(value, text, cursor);
|
|
212
318
|
if (index < 0) return count;
|
|
213
319
|
count += 1;
|
|
214
320
|
cursor = index + text.length;
|
|
@@ -216,12 +322,12 @@ function __velarStringCount(value, text) {
|
|
|
216
322
|
}
|
|
217
323
|
function __velarStringStartsWith(value, text) {
|
|
218
324
|
value = __velarTextValue(value); text = __velarTextArgument(text, "String.startsWith text");
|
|
219
|
-
return __velarTextCall(__velarNativeStringIndexOf, value, [text, 0]) === 0;
|
|
325
|
+
return __velarTextCall(__velarNativeStringIndexOf, value, [text, 0]) === 0 && __velarTextIsBoundary(value, text.length);
|
|
220
326
|
}
|
|
221
327
|
function __velarStringEndsWith(value, text) {
|
|
222
328
|
value = __velarTextValue(value); text = __velarTextArgument(text, "String.endsWith text");
|
|
223
329
|
const start = value.length - text.length;
|
|
224
|
-
return start >= 0 && __velarTextCall(__velarNativeStringIndexOf, value, [text, start]) === start;
|
|
330
|
+
return start >= 0 && __velarTextIsBoundary(value, start) && __velarTextCall(__velarNativeStringIndexOf, value, [text, start]) === start;
|
|
225
331
|
}
|
|
226
332
|
function __velarStringSplit(value, separator) {
|
|
227
333
|
value = __velarTextValue(value); separator = __velarTextArgument(separator, "String.split separator");
|
|
@@ -237,12 +343,35 @@ function __velarStringSplit(value, separator) {
|
|
|
237
343
|
}
|
|
238
344
|
return output;
|
|
239
345
|
}
|
|
240
|
-
|
|
346
|
+
// The native split matches UTF-16 code units, so it would cut a surrogate
|
|
347
|
+
// pair in half on a separator that begins or ends with an unpaired
|
|
348
|
+
// surrogate. Every other separator makes the two scans agree match for
|
|
349
|
+
// match, and the native one is the faster: its limit argument also stops it
|
|
350
|
+
// before it can build an oversize array.
|
|
351
|
+
if (!__velarTextNeedsBoundaryCheck(separator)) {
|
|
352
|
+
return __velarTextList(__velarTextCall(__velarNativeStringSplit, value, [separator, __velarMaxTextItems + 1]), "String.split");
|
|
353
|
+
}
|
|
354
|
+
// Searching on code-point boundaries keeps every piece well formed; the
|
|
355
|
+
// pieces themselves are still plain slices of the input.
|
|
356
|
+
const parts = new __velarTextNativeArray();
|
|
357
|
+
let cursor = 0;
|
|
358
|
+
while (true) {
|
|
359
|
+
const found = __velarTextBoundedIndexOf(value, separator, cursor);
|
|
360
|
+
if (found < 0) break;
|
|
361
|
+
parts[parts.length] = __velarTextCall(__velarNativeStringSlice, value, [cursor, found]);
|
|
362
|
+
if (parts.length > __velarMaxTextItems) return __velarTextList(parts, "String.split");
|
|
363
|
+
cursor = found + separator.length;
|
|
364
|
+
}
|
|
365
|
+
parts[parts.length] = __velarTextCall(__velarNativeStringSlice, value, [cursor]);
|
|
366
|
+
return __velarTextList(parts, "String.split");
|
|
241
367
|
}
|
|
242
368
|
function __velarStringReplace(value, from, to) {
|
|
243
369
|
value = __velarTextValue(value); from = __velarTextArgument(from, "String.replace from"); to = __velarTextArgument(to, "String.replace to");
|
|
244
370
|
if (__velarTextReplacementOutputUnits(value, from, to, false) > __velarMaxTextCodeUnits) throw new __velarTextNativeRangeError("String.replace output cannot exceed 16 MiB");
|
|
245
|
-
|
|
371
|
+
if (from === "") return to + value;
|
|
372
|
+
const found = __velarTextBoundedIndexOf(value, from, 0);
|
|
373
|
+
if (found < 0) return value;
|
|
374
|
+
return __velarTextCall(__velarNativeStringSlice, value, [0, found]) + to + __velarTextCall(__velarNativeStringSlice, value, [found + from.length]);
|
|
246
375
|
}
|
|
247
376
|
function __velarStringReplaceAll(value, from, to) {
|
|
248
377
|
value = __velarTextValue(value); from = __velarTextArgument(from, "String.replaceAll from"); to = __velarTextArgument(to, "String.replaceAll to");
|
|
@@ -253,7 +382,19 @@ function __velarStringReplaceAll(value, from, to) {
|
|
|
253
382
|
while (offset < value.length) { const next = __velarTextNextCodePointOffset(value, offset); output += __velarTextCall(__velarNativeStringSlice, value, [offset, next]) + to; offset = next; }
|
|
254
383
|
return output;
|
|
255
384
|
}
|
|
256
|
-
|
|
385
|
+
// A separator that cannot split a pair leaves nothing for the bounded walk
|
|
386
|
+
// to reject, so the native rewrite answers the same string faster. The
|
|
387
|
+
// replacement is passed as a function so that a '$' in it stays literal.
|
|
388
|
+
if (!__velarTextNeedsBoundaryCheck(from)) return __velarTextCall(__velarNativeStringReplaceAll, value, [from, () => to]);
|
|
389
|
+
let output = "";
|
|
390
|
+
let cursor = 0;
|
|
391
|
+
while (true) {
|
|
392
|
+
const found = __velarTextBoundedIndexOf(value, from, cursor);
|
|
393
|
+
if (found < 0) break;
|
|
394
|
+
output += __velarTextCall(__velarNativeStringSlice, value, [cursor, found]) + to;
|
|
395
|
+
cursor = found + from.length;
|
|
396
|
+
}
|
|
397
|
+
return output + __velarTextCall(__velarNativeStringSlice, value, [cursor]);
|
|
257
398
|
}
|
|
258
399
|
function __velarStringPad(value, size, fill, start) {
|
|
259
400
|
const name = start ? "String.padStart" : "String.padEnd";
|
package/dist/text-runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-runtime.js","sourceRoot":"","sources":["../src/text-runtime.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"text-runtime.js","sourceRoot":"","sources":["../src/text-runtime.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwalD,CAAC,SAAS,EAAE,CAAC"}
|
package/dist/token.d.ts
CHANGED
|
@@ -14,6 +14,17 @@ export interface Token {
|
|
|
14
14
|
readonly span: Span;
|
|
15
15
|
readonly payload?: unknown;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* A number token's payload, carried only when the author's own spelling differs
|
|
19
|
+
* from the value the token holds — digit separators (`1_000_000_1`) and an
|
|
20
|
+
* uppercase radix prefix (`0X20`) are the two differences the lexer makes.
|
|
21
|
+
* D90 R6's representability report quotes the literal back at the author, and
|
|
22
|
+
* quoting the normalized spelling would show them text that appears nowhere in
|
|
23
|
+
* their source.
|
|
24
|
+
*/
|
|
25
|
+
export interface NumberTokenPayload {
|
|
26
|
+
readonly written: string;
|
|
27
|
+
}
|
|
17
28
|
/**
|
|
18
29
|
* Hard reserved words: spellings the lexer always turns into a keyword token,
|
|
19
30
|
* so they can never name a binding. D30 item 16 softened the statement-head
|
package/dist/token.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,KAAK,GACL,KAAK,GACL,OAAO,GACP,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,IAAI,GACJ,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,UAAU,GACV,OAAO,GACP,SAAS,GACT,UAAU,GACV,SAAS,GACT,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,IAAI,GACJ,MAAM,GACN,KAAK,GACL,IAAI,GACJ,OAAO,GACP,OAAO,GACP,UAAU,GACV,KAAK,GACL,OAAO,GACP,SAAS,GACT,MAAM,GACN,IAAI,GACJ,MAAM,GACN,OAAO,GACP,MAAM,GACN,KAAK,GACL,IAAI,GACJ,KAAK,GACL,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,aAAa,GACb,cAAc,GACd,WAAW,GACX,YAAY,GACZ,OAAO,GACP,OAAO;AACT,mGAAmG,IAAI,IAAI,GACzG,KAAK,GACL,UAAU,GACV,UAAU;AACZ;;;;;GAKG;GACD,MAAM,GACN,aAAa,GACb,SAAS,GACT,OAAO,GACP,UAAU,GACV,MAAM,GACN,KAAK,GACL,OAAO,GACP,OAAO,GACP,WAAW,GACX,YAAY,GACZ,oBAAoB,GACpB,QAAQ,GACR,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,aAAa,GACb,eAAe,GACf,aAAa,GACb,cAAc,GACd,cAAc,GACd,iBAAiB,GACjB,kBAAkB,GAClB,0BAA0B,GAC1B,OAAO,GACP,UAAU,GACV,MAAM,GACN,WAAW,GACX,SAAS,GACT,cAAc,GACd,MAAM,GACN,OAAO,GACP,MAAM,GACN,UAAU,GACV,OAAO,GACP,SAAS,GACT,KAAK,CAAC;AAEV,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAyC5D,CAAC"}
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,KAAK,GACL,KAAK,GACL,OAAO,GACP,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,IAAI,GACJ,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,UAAU,GACV,OAAO,GACP,SAAS,GACT,UAAU,GACV,SAAS,GACT,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,IAAI,GACJ,MAAM,GACN,KAAK,GACL,IAAI,GACJ,OAAO,GACP,OAAO,GACP,UAAU,GACV,KAAK,GACL,OAAO,GACP,SAAS,GACT,MAAM,GACN,IAAI,GACJ,MAAM,GACN,OAAO,GACP,MAAM,GACN,KAAK,GACL,IAAI,GACJ,KAAK,GACL,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,aAAa,GACb,cAAc,GACd,WAAW,GACX,YAAY,GACZ,OAAO,GACP,OAAO;AACT,mGAAmG,IAAI,IAAI,GACzG,KAAK,GACL,UAAU,GACV,UAAU;AACZ;;;;;GAKG;GACD,MAAM,GACN,aAAa,GACb,SAAS,GACT,OAAO,GACP,UAAU,GACV,MAAM,GACN,KAAK,GACL,OAAO,GACP,OAAO,GACP,WAAW,GACX,YAAY,GACZ,oBAAoB,GACpB,QAAQ,GACR,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,aAAa,GACb,eAAe,GACf,aAAa,GACb,cAAc,GACd,cAAc,GACd,iBAAiB,GACjB,kBAAkB,GAClB,0BAA0B,GAC1B,OAAO,GACP,UAAU,GACV,MAAM,GACN,WAAW,GACX,SAAS,GACT,cAAc,GACd,MAAM,GACN,OAAO,GACP,MAAM,GACN,UAAU,GACV,OAAO,GACP,SAAS,GACT,KAAK,CAAC;AAEV,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAyC5D,CAAC"}
|
package/dist/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AA+HA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAwC;IAC/D,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,EAAE,EAAE,IAAI;IACR,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,IAAI;IACR,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,KAAK;CACX,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-registry-runtime.d.ts","sourceRoot":"","sources":["../src/type-registry-runtime.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,
|
|
1
|
+
{"version":3,"file":"type-registry-runtime.d.ts","sourceRoot":"","sources":["../src/type-registry-runtime.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,QAkD3B,CAAC"}
|
|
@@ -42,7 +42,14 @@ function __velarRegisterRuntimeType(value) {
|
|
|
42
42
|
}
|
|
43
43
|
function __velarRequireRuntimeType(value, name, optional = false) {
|
|
44
44
|
if (optional && value == null) return null;
|
|
45
|
-
|
|
45
|
+
// Registry membership proves the value was registered somewhere in this
|
|
46
|
+
// realm; it does not prove it still presents the Type surface. A module built
|
|
47
|
+
// by another generation registers into the same WeakSet whenever both
|
|
48
|
+
// generations share the registry key, so the surface itself is asserted here:
|
|
49
|
+
// 'is' and 'parse' are the two operations every caller of this helper goes on
|
|
50
|
+
// to invoke.
|
|
51
|
+
if (!value || typeof value !== "object" || !__velarTypeCall(__velarTypeWeakSetHas, __velarRuntimeTypeRegistry, [value])
|
|
52
|
+
|| typeof value.is !== "function" || typeof value.parse !== "function") {
|
|
46
53
|
throw new __velarTypeNativeTypeError(name + " requires a compiler-known VelarScript runtime type");
|
|
47
54
|
}
|
|
48
55
|
return value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-registry-runtime.js","sourceRoot":"","sources":["../src/type-registry-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;kGAY6C,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC
|
|
1
|
+
{"version":3,"file":"type-registry-runtime.js","sourceRoot":"","sources":["../src/type-registry-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;kGAY6C,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCxI,CAAC,SAAS,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-validation-runtime.d.ts","sourceRoot":"","sources":["../src/type-validation-runtime.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,
|
|
1
|
+
{"version":3,"file":"type-validation-runtime.d.ts","sourceRoot":"","sources":["../src/type-validation-runtime.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,QAgL7B,CAAC;AAEd,+DAA+D;AAC/D,eAAO,MAAM,qCAAqC,QAsCrC,CAAC;AAEd,eAAO,MAAM,8BAA8B,QAc9B,CAAC;AAEd,eAAO,MAAM,4BAA4B,oCAAoC,CAAC;AAE9E;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,QA+BnC,CAAC"}
|
|
@@ -24,11 +24,19 @@ const __velarValidationSetDeleteOperation = __velarCollectionGetOwnPropertyDescr
|
|
|
24
24
|
const __velarValidationSetSizeOperation = __velarCollectionGetOwnPropertyDescriptor(__velarValidationSetPrototype, "size")?.get;
|
|
25
25
|
const __velarValidationFunctionHasInstanceOperation = __velarCollectionGetOwnPropertyDescriptor(__velarValidationFunctionPrototype, __velarValidationHasInstanceSymbol)?.value;
|
|
26
26
|
const __velarValidationFreezeOperation = __velarCollectionGetOwnPropertyDescriptor(__velarCollectionNativeObject, "freeze")?.value;
|
|
27
|
-
|
|
27
|
+
const __velarValidationDefinePropertyOperation = __velarCollectionGetOwnPropertyDescriptor(__velarCollectionNativeObject, "defineProperty")?.value;
|
|
28
|
+
const __velarValidationMapSetOperation = __velarCollectionGetOwnPropertyDescriptor(__velarCollectionMapPrototype, "set")?.value;
|
|
29
|
+
const __velarValidationMapGetOperation = __velarCollectionGetOwnPropertyDescriptor(__velarCollectionMapPrototype, "get")?.value;
|
|
30
|
+
// D90 rule R5: the per-call graph state carries both the validator's cycle
|
|
31
|
+
// guard and the copy memo, because parse runs one then the other over the same
|
|
32
|
+
// object graph. 'copies' stays null until something is actually copied.
|
|
33
|
+
function __velarValidationState() { return { active: new __velarValidationNativeWeakMap(), depth: 0, copies: null, copy: __velarValidationCopy }; }
|
|
28
34
|
function __velarValidationSet() { return new __velarValidationNativeSet(); }
|
|
29
35
|
function __velarValidationWeakMapGet(value, key) { return __velarCollectionHostCall(__velarValidationWeakMapGetOperation, value, [key]); }
|
|
30
36
|
function __velarValidationWeakMapSet(value, key, item) { return __velarCollectionHostCall(__velarValidationWeakMapSetOperation, value, [key, item]); }
|
|
31
37
|
function __velarValidationWeakMapDelete(value, key) { return __velarCollectionHostCall(__velarValidationWeakMapDeleteOperation, value, [key]); }
|
|
38
|
+
function __velarValidationMapGet(value, key) { return __velarCollectionHostCall(__velarValidationMapGetOperation, value, [key]); }
|
|
39
|
+
function __velarValidationMapSet(value, key, item) { return __velarCollectionHostCall(__velarValidationMapSetOperation, value, [key, item]); }
|
|
32
40
|
function __velarValidationSetHas(value, item) { return __velarCollectionHostCall(__velarValidationSetHasOperation, value, [item]); }
|
|
33
41
|
function __velarValidationSetAdd(value, item) { return __velarCollectionHostCall(__velarValidationSetAddOperation, value, [item]); }
|
|
34
42
|
function __velarValidationSetDelete(value, item) { return __velarCollectionHostCall(__velarValidationSetDeleteOperation, value, [item]); }
|
|
@@ -48,6 +56,126 @@ function __velarValidationIsPlainObject(value) {
|
|
|
48
56
|
if (prototype === null) return true;
|
|
49
57
|
return __velarCollectionHostCall(__velarCollectionGetPrototypeOf, __velarCollectionNativeObject, [prototype]) === null;
|
|
50
58
|
}
|
|
59
|
+
// D90 rule R5: parse returns a copy, so "validated" means "and it stays
|
|
60
|
+
// valid" rather than "it was correct at the instant of the check". The copy
|
|
61
|
+
// follows the declared shape — the generated validators supply one callback
|
|
62
|
+
// per element position — and the memo answers per source object *and* copy
|
|
63
|
+
// plan, so a shared or cyclic subgraph is copied once per declared shape and
|
|
64
|
+
// the copy preserves the sharing the source had. Keying on the source alone
|
|
65
|
+
// would hand the second projection of one object the first projection's copy:
|
|
66
|
+
// a value the caller never wrote and no declared type ever accepted. The four
|
|
67
|
+
// container members are spelled with an "Of" suffix because this runtime
|
|
68
|
+
// reaches every host collection through a captured operation: no member call
|
|
69
|
+
// inside it may read as a get, set, has, add, or delete call, which is the
|
|
70
|
+
// boundary gate's rule for this file.
|
|
71
|
+
const __velarValidationCopy = {
|
|
72
|
+
seen(state, value, plan) {
|
|
73
|
+
if (state.copies === null) return undefined;
|
|
74
|
+
const plans = __velarValidationWeakMapGet(state.copies, value);
|
|
75
|
+
return plans === undefined ? undefined : __velarValidationMapGet(plans, plan);
|
|
76
|
+
},
|
|
77
|
+
remember(state, value, copy, plan) {
|
|
78
|
+
if (state.copies === null) state.copies = new __velarValidationNativeWeakMap();
|
|
79
|
+
let plans = __velarValidationWeakMapGet(state.copies, value);
|
|
80
|
+
if (plans === undefined) {
|
|
81
|
+
plans = new __velarCollectionNativeMap();
|
|
82
|
+
__velarValidationWeakMapSet(state.copies, value, plans);
|
|
83
|
+
}
|
|
84
|
+
__velarValidationMapSet(plans, plan, copy);
|
|
85
|
+
return copy;
|
|
86
|
+
},
|
|
87
|
+
object(state, value, plan) {
|
|
88
|
+
return __velarValidationCopy.remember(state, value, {}, plan);
|
|
89
|
+
},
|
|
90
|
+
// Fields are written through defineProperty so a field literally named
|
|
91
|
+
// '__proto__' lands as an own data property instead of retargeting the
|
|
92
|
+
// copy's prototype, and so every copied field is an ordinary mutable
|
|
93
|
+
// enumerable data property whatever the source's descriptor said.
|
|
94
|
+
field(target, name, value) {
|
|
95
|
+
__velarCollectionHostCall(__velarValidationDefinePropertyOperation, __velarCollectionNativeObject, [target, name, { value: value, writable: true, enumerable: true, configurable: true }]);
|
|
96
|
+
},
|
|
97
|
+
// A null element callback means the element position has nothing to copy —
|
|
98
|
+
// a primitive, an enum member, a class instance, or an opaque 'unknown'.
|
|
99
|
+
// 'plan' is the container position's own stable identity: the emitter hoists
|
|
100
|
+
// one function per distinct copy plan and hands it in as both the element
|
|
101
|
+
// callback and the key this memo files the copy under.
|
|
102
|
+
listOf(value, state, item, plan) {
|
|
103
|
+
const found = __velarValidationCopy.seen(state, value, plan);
|
|
104
|
+
if (found !== undefined) return found;
|
|
105
|
+
const result = __velarValidationCopy.remember(state, value, [], plan);
|
|
106
|
+
const length = __velarValidationOwnDescriptor(value, "length")?.value ?? 0;
|
|
107
|
+
for (let index = 0; index < length; index += 1) {
|
|
108
|
+
const descriptor = __velarValidationOwnDescriptor(value, index);
|
|
109
|
+
result[index] = item === null ? descriptor?.value : item(descriptor?.value, state);
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
},
|
|
113
|
+
setOf(value, state, item, plan) {
|
|
114
|
+
const found = __velarValidationCopy.seen(state, value, plan);
|
|
115
|
+
if (found !== undefined) return found;
|
|
116
|
+
const result = __velarValidationCopy.remember(state, value, __velarValidationSet(), plan);
|
|
117
|
+
const iterator = __velarCollectionSetTypeIterator(value);
|
|
118
|
+
while (true) {
|
|
119
|
+
const step = __velarCollectionSetTypeNext(iterator);
|
|
120
|
+
if (step.done) break;
|
|
121
|
+
__velarValidationSetAdd(result, item === null ? step.value : item(step.value, state));
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
},
|
|
125
|
+
mapOf(value, state, key, item, plan) {
|
|
126
|
+
const found = __velarValidationCopy.seen(state, value, plan);
|
|
127
|
+
if (found !== undefined) return found;
|
|
128
|
+
const result = __velarValidationCopy.remember(state, value, new __velarCollectionNativeMap(), plan);
|
|
129
|
+
const iterator = __velarCollectionMapTypeIterator(value);
|
|
130
|
+
while (true) {
|
|
131
|
+
const step = __velarCollectionMapTypeNext(iterator);
|
|
132
|
+
if (step.done) break;
|
|
133
|
+
const entry = step.value;
|
|
134
|
+
__velarValidationMapSet(result, key === null ? entry[0] : key(entry[0], state), item === null ? entry[1] : item(entry[1], state));
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
},
|
|
138
|
+
recordOf(value, state, item, plan) {
|
|
139
|
+
const found = __velarValidationCopy.seen(state, value, plan);
|
|
140
|
+
if (found !== undefined) return found;
|
|
141
|
+
const result = __velarValidationCopy.remember(state, value, {}, plan);
|
|
142
|
+
const keys = __velarCollectionHostCall(__velarCollectionOwnKeys, __velarCollectionNativeReflect, [value]);
|
|
143
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
144
|
+
const name = keys[index];
|
|
145
|
+
if (typeof name !== "string") continue;
|
|
146
|
+
const descriptor = __velarValidationOwnDescriptor(value, name);
|
|
147
|
+
if (!descriptor?.enumerable || !("value" in descriptor)) continue;
|
|
148
|
+
__velarValidationCopy.field(result, name, item === null ? descriptor.value : item(descriptor.value, state));
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
},
|
|
152
|
+
// A generic instantiation supplies a predicate per type argument but no copy
|
|
153
|
+
// plan, and a structural or union position is validated as a shape the
|
|
154
|
+
// predicate did not fully decide. Both copy the plain data they can see:
|
|
155
|
+
// arrays, Maps, Sets, and plain objects recurse; anything else — a class
|
|
156
|
+
// instance, a promise, a function, a binary buffer — is not plain data and
|
|
157
|
+
// passes through by reference.
|
|
158
|
+
plain(value, state) {
|
|
159
|
+
if (value === null || typeof value !== "object") return value;
|
|
160
|
+
const found = __velarValidationCopy.seen(state, value, __velarValidationCopy.plain);
|
|
161
|
+
if (found !== undefined) return found;
|
|
162
|
+
if (__velarValidationIsArray(value)) return __velarValidationCopy.listOf(value, state, __velarValidationCopy.plain, __velarValidationCopy.plain);
|
|
163
|
+
if (__velarIsMap(value)) return __velarValidationCopy.mapOf(value, state, __velarValidationCopy.plain, __velarValidationCopy.plain, __velarValidationCopy.plain);
|
|
164
|
+
if (__velarIsSet(value)) return __velarValidationCopy.setOf(value, state, __velarValidationCopy.plain, __velarValidationCopy.plain);
|
|
165
|
+
if (!__velarValidationIsPlainObject(value)) return value;
|
|
166
|
+
return __velarValidationCopy.recordOf(value, state, __velarValidationCopy.plain, __velarValidationCopy.plain);
|
|
167
|
+
},
|
|
168
|
+
// A Type object from a target extension, or one emitted by an older build,
|
|
169
|
+
// may carry no copy plan; the structural copy is what is left to fall back on.
|
|
170
|
+
// A Type that does answer 'copy' owns its own plan identity — a declared
|
|
171
|
+
// record files under its copy function, an instantiation under its arguments
|
|
172
|
+
// — so nothing is threaded in from here.
|
|
173
|
+
through(type, value, state) {
|
|
174
|
+
const operation = type === null || type === undefined ? undefined : type.copy;
|
|
175
|
+
if (typeof operation !== "function") return __velarValidationCopy.plain(value, state);
|
|
176
|
+
return __velarCollectionHostCall(operation, type, [value, state]);
|
|
177
|
+
},
|
|
178
|
+
};
|
|
51
179
|
// Teaching suffix for record parse failures caused by the plain-object rule.
|
|
52
180
|
function __velarValidationRejectionHint(value) {
|
|
53
181
|
if (value === null || typeof value !== "object" || __velarValidationIsArray(value) || __velarValidationIsPlainObject(value)) return "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-validation-runtime.js","sourceRoot":"","sources":["../src/type-validation-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC3G,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,MAAM,CAAC,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"type-validation-runtime.js","sourceRoot":"","sources":["../src/type-validation-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC3G,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgLtD,CAAC,SAAS,EAAE,CAAC;AAEd,+DAA+D;AAC/D,MAAM,CAAC,MAAM,qCAAqC,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsC9D,CAAC,SAAS,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,8BAA8B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;CAcvD,CAAC,SAAS,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,4BAA4B,GAAG,iCAAiC,CAAC;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,MAAM,CAAC,GAAG,CAAA;EAC3D,iCAAiC;EACjC,6BAA6B;EAC7B,2BAA2B;EAC3B,6BAA6B;EAC7B,qCAAqC;EACrC,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;CAyB/B,CAAC,SAAS,EAAE,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -69,9 +69,16 @@ export interface GenericApplication {
|
|
|
69
69
|
readonly name: string;
|
|
70
70
|
readonly arguments: readonly ValueType[];
|
|
71
71
|
}
|
|
72
|
-
export type ValueType =
|
|
72
|
+
export type ValueType =
|
|
73
|
+
/**
|
|
74
|
+
* `restricted` is the recursion placeholder and `boundary` is the `unknown`
|
|
75
|
+
* a program wrote down — the type of data nobody has checked yet. Neither
|
|
76
|
+
* may be absorbed by a merge; see `mergeTypes`.
|
|
77
|
+
*/
|
|
78
|
+
{
|
|
73
79
|
readonly kind: "unknown";
|
|
74
80
|
readonly restricted?: boolean;
|
|
81
|
+
readonly boundary?: true;
|
|
75
82
|
}
|
|
76
83
|
/**
|
|
77
84
|
* `textConvertible` marks the compiler-owned text-conversion domain (charter
|
|
@@ -212,6 +219,14 @@ export type BinaryStorageKind = "bytes" | "uint8" | "uint16" | "uint32" | "float
|
|
|
212
219
|
*/
|
|
213
220
|
export declare function binaryStorageKind(type: ValueType): BinaryStorageKind | null;
|
|
214
221
|
export declare const unknownType: ValueType;
|
|
222
|
+
/**
|
|
223
|
+
* The `unknown` a program wrote in an annotation, and the type every boundary
|
|
224
|
+
* that hands back unchecked data should carry. It differs from the inference
|
|
225
|
+
* seed above in exactly one rule — a merge may not absorb it — so `unknown`
|
|
226
|
+
* arriving from outside stays unassignable until the value is validated,
|
|
227
|
+
* instead of being retyped as whatever the other branch produced.
|
|
228
|
+
*/
|
|
229
|
+
export declare const boundaryUnknownType: ValueType;
|
|
215
230
|
export declare const invalidType: ValueType;
|
|
216
231
|
export declare const anyType: ValueType;
|
|
217
232
|
/** The declared parameter domain of the built-in `str`; see `isTextConvertibleType`. */
|
|
@@ -320,6 +335,7 @@ export declare function typeContainsParameter(type: ValueType, matches?: (parame
|
|
|
320
335
|
kind: "parameter";
|
|
321
336
|
}>) => boolean): boolean;
|
|
322
337
|
export declare function typeContainsRuntimeTypeCheck(type: ValueType): boolean;
|
|
338
|
+
export declare function typeContainsAnyOutput(type: ValueType): boolean;
|
|
323
339
|
export declare function substituteTypeParameters(type: ValueType, bindings: readonly (ValueType | null)[]): ValueType;
|
|
324
340
|
export declare function bindNamedTypeParameters(type: ValueType, parameters: ReadonlyMap<string, ValueType>): ValueType;
|
|
325
341
|
/**
|