mirror of
https://github.com/morluto/rea.git
synced 2026-10-28 18:35:53 +00:00
fix(javascript): bound semantic expansion and resolve lexical receivers
This commit is contained in:
1 parent
eaf5734083
commit
16f4609d68
26 files changed
+868
-78
No files matched your search
@@ -6,23 +6,35 @@ import type {
|
||||
} from "./javascriptSemanticIr.js";
|
||||
import { compareCodePoints } from "../canonicalOrdering.js";
|
||||
import { semanticPrimitiveKey } from "./javascriptSemanticProvenance.js";
|
||||
import { readExactJavaScriptLiteral } from "./javascriptAstValues.js";
|
||||
import {
|
||||
SEMANTIC_PRIMITIVE_CANDIDATE_LIMIT,
|
||||
semanticResourceLimitUnknown,
|
||||
} from "./javascriptSemanticResourceLimits.js";
|
||||
|
||||
/**
|
||||
* Keep eight independent binary choices exact, while bounding the next
|
||||
* exponential expansion before it allocates hundreds more alternatives.
|
||||
*/
|
||||
export const MAX_SEMANTIC_PRIMITIVE_CANDIDATES =
|
||||
SEMANTIC_PRIMITIVE_CANDIDATE_LIMIT;
|
||||
|
||||
/** Normalize one bounded collection of possible primitive values. */
|
||||
export const semanticPrimitiveSet = (
|
||||
values: readonly JavaScriptSemanticPrimitive[],
|
||||
): JavaScriptSemanticValue => {
|
||||
if (
|
||||
values.some((value) => typeof value === "number" && !Number.isFinite(value))
|
||||
)
|
||||
return {
|
||||
status: "unknown",
|
||||
reason: "Nonfinite numbers are outside the JSON primitive lattice.",
|
||||
};
|
||||
const unique = [
|
||||
...new Map(
|
||||
values.map((value) => [semanticPrimitiveKey(value), value]),
|
||||
).values(),
|
||||
].sort((left, right) =>
|
||||
const byKey = new Map<string, JavaScriptSemanticPrimitive>();
|
||||
for (const value of values) {
|
||||
if (typeof value === "number" && !Number.isFinite(value))
|
||||
return {
|
||||
status: "unknown",
|
||||
reason: "Nonfinite numbers are outside the JSON primitive lattice.",
|
||||
};
|
||||
byKey.set(semanticPrimitiveKey(value), value);
|
||||
if (byKey.size > MAX_SEMANTIC_PRIMITIVE_CANDIDATES)
|
||||
return semanticResourceLimitUnknown("primitive-candidates");
|
||||
}
|
||||
const unique = [...byKey.values()].sort((left, right) =>
|
||||
compareCodePoints(semanticPrimitiveKey(left), semanticPrimitiveKey(right)),
|
||||
);
|
||||
const only = unique[0];
|
||||
@@ -47,10 +59,5 @@ export const semanticPrimitiveValue = (
|
||||
):
|
||||
| { readonly found: true; readonly value: JavaScriptSemanticPrimitive }
|
||||
| { readonly found: false } => {
|
||||
if (t.isStringLiteral(node)) return { found: true, value: node.value };
|
||||
if (t.isNumericLiteral(node) && Number.isFinite(node.value))
|
||||
return { found: true, value: node.value };
|
||||
if (t.isBooleanLiteral(node)) return { found: true, value: node.value };
|
||||
if (t.isNullLiteral(node)) return { found: true, value: null };
|
||||
return { found: false };
|
||||
return readExactJavaScriptLiteral(node);
|
||||
};
|
||||
Reference in new issue
Block a user