mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
* Expand static compilation for common Effect 4 patterns * Run every Effect 4 fixture slice in CI * Preserve existing corpus behavior across Effect 4 lowering * Preserve Effect platform callbacks and native stream state * Record new corpus baselines and retain child stdin refusals * Retire the obsolete stateful regex diagnostic * Preserve promise reference count layout for cycle collection
249 lines
8.6 KiB
JavaScript
249 lines
8.6 KiB
JavaScript
export function openLocal(register) {
|
|
let result = false;
|
|
register((value) => { result = value; });
|
|
return result;
|
|
}
|
|
|
|
export function callbackResult(register) {
|
|
if (register) return register();
|
|
return Symbol.for("shape/pending");
|
|
}
|
|
|
|
export function defaultObject(options = { value: 1 }) {
|
|
return options.value;
|
|
}
|
|
|
|
export function restArguments(...values) {
|
|
const later = () => arguments[1];
|
|
values[0] = "changed";
|
|
return [values[0], arguments[0], arguments.length, later()];
|
|
}
|
|
|
|
export function openRecord() {
|
|
const value = { next: undefined, count: 0 };
|
|
const alias = value;
|
|
alias.next = { value: 42 };
|
|
value.count++;
|
|
return [alias.next.value, alias.count];
|
|
}
|
|
|
|
export class State {
|
|
state = { _tag: "Empty" };
|
|
}
|
|
|
|
export function advance(value) {
|
|
value.state = { _tag: "Ready", value: 42 };
|
|
return [value.state._tag, value.state.value];
|
|
}
|
|
|
|
export function copyProperties(source) {
|
|
const target = {};
|
|
for (const key of Reflect.ownKeys(source)) {
|
|
if (Object.prototype.propertyIsEnumerable.call(source, key)) target[key] = source[key];
|
|
}
|
|
return target;
|
|
}
|
|
|
|
export const Tagged = (tag) => {
|
|
class Base extends Error {
|
|
_tag = tag;
|
|
constructor(properties) {
|
|
super(properties.message);
|
|
Object.assign(this, properties);
|
|
}
|
|
}
|
|
Base.prototype.name = tag;
|
|
return Base;
|
|
};
|
|
|
|
export function cached(key) {
|
|
const values = {};
|
|
let calls = 0;
|
|
const make = () => ++calls;
|
|
values[key] ??= make();
|
|
values[key] ??= make();
|
|
return [values[key], calls];
|
|
}
|
|
|
|
|
|
export const nestedFactory = (label) => (suffix) => class {
|
|
static label = label + suffix;
|
|
constructor(value) { this.value = value; }
|
|
read() { return this.value + label.length + suffix.length; }
|
|
};
|
|
|
|
export function optionalReads(value, key) {
|
|
let calls = 0;
|
|
const select = () => { calls++; return key; };
|
|
const first = value?.[select()];
|
|
const tail = value?.[key].child;
|
|
const call = value?.[key].method?.();
|
|
return [first, tail, call, calls];
|
|
}
|
|
|
|
export function missingProperties(value) {
|
|
const { missing, count = 7 } = value;
|
|
return [missing, count];
|
|
}
|
|
|
|
export function dynamicIndex(value, index) { return value[index]; }
|
|
|
|
export function callableProperties() {
|
|
const fn = Object.assign(function () { return this.value; }, {
|
|
value: 42,
|
|
tools: { double: 2 },
|
|
[Symbol.iterator]: function* () { return yield 1; }
|
|
});
|
|
return [Object.keys(fn.tools), Reflect.apply(fn, fn, []), fn.call(fn), [...fn]];
|
|
}
|
|
|
|
export class Cached {
|
|
calls = 0;
|
|
save(key, value) { Object.defineProperty(this, key, { value }); return value; }
|
|
get result() { this.calls++; return this.save("result", { value: 42 }); }
|
|
}
|
|
|
|
export function readCached(value) { return [value.result, value.result, value.calls]; }
|
|
export function spreadMethod(value, args) { return value.add(...args); }
|
|
|
|
export function checkedTag(strings) {
|
|
return [strings[0], strings.raw[0], Object.isFrozen(strings), Object.isFrozen(strings.raw),
|
|
Object.getOwnPropertyDescriptor(strings, "raw"), strings];
|
|
}
|
|
export function templateProperties() {
|
|
const first = () => checkedTag`line\n`;
|
|
const a = first(), b = first();
|
|
return [a.slice(0, 5), a[5] === b[5], a[5] === checkedTag`line\n`[5]];
|
|
}
|
|
export function freezeValues() {
|
|
const values = ["one", "two"];
|
|
values.forEach(Object.freeze);
|
|
return values.map(value => Object.isFrozen(value));
|
|
}
|
|
export function prototypeRecord() {
|
|
const record = { value: 42 };
|
|
const identity = Object.setPrototypeOf(record, { read() { return this.value; } });
|
|
return [identity === record, record.read(), Object.getPrototypeOf(record).read.call(record)];
|
|
}
|
|
|
|
export function objectRest(source) {
|
|
const { omitted, ...remaining } = source;
|
|
return [remaining, remaining[Symbol.for("rest/key")], Object.getPrototypeOf(remaining) === Object.prototype];
|
|
}
|
|
|
|
export function evolvingFields() {
|
|
const builder = { statements: [], bindings: [], next: 0 };
|
|
builder.statements.push("hello");
|
|
builder.bindings.push({ reference: "world" });
|
|
return { statements: builder.statements, bindings: builder.bindings };
|
|
}
|
|
|
|
export function nativeSymbols(value) {
|
|
const key = Symbol.for("shape/native");
|
|
const before = key in value;
|
|
value[key] = 42;
|
|
return [before, value[key], key in value, Object.getOwnPropertySymbols(value).includes(key)];
|
|
}
|
|
|
|
export function uriDecoders(value) {
|
|
return [decodeURI(value), decodeURIComponent(value)];
|
|
}
|
|
|
|
export function clearStoredTimer() {
|
|
const timers = new Map();
|
|
timers.set("pending", setTimeout(() => console.log("unexpected"), 50));
|
|
clearTimeout(timers.get("pending"));
|
|
clearTimeout({});
|
|
return "cleared";
|
|
}
|
|
|
|
export function webConstructors() {
|
|
const headers = new globalThis.Headers({ "x-test": "yes" });
|
|
const request = new globalThis.Request("http://localhost/hello", { headers });
|
|
const response = new globalThis.Response("hello", { headers });
|
|
const keys = new WeakMap();
|
|
keys.set(request, "request"); keys.set(response, "response");
|
|
return [request.url, headers.get("x-test"), response.status, request instanceof Request, response instanceof Response, headers instanceof Headers, ({}) instanceof Response, keys.get(request), keys.get(response)];
|
|
}
|
|
export function stringPositions() {
|
|
const url = "http://localhost/hello";
|
|
return [url.indexOf("/", url.indexOf("//") + 2), url.includes("http", 1), url.lastIndexOf("/", 6)];
|
|
}
|
|
const exportedFactory = () => ({ left: () => 21, right: () => 21 });
|
|
export const { left, right } = exportedFactory();
|
|
export function readDestructuredExports() { return left() + right(); }
|
|
class ConditionalBase {
|
|
constructor(value) { this.value = value; }
|
|
}
|
|
export class ConditionalDerived extends ConditionalBase {
|
|
initialized = this.value + 1;
|
|
constructor(flag) { if (flag) super(1); else super(2); }
|
|
}
|
|
export class RepeatedSuper extends ConditionalBase {
|
|
constructor() { super(1); super(2); }
|
|
}
|
|
|
|
export function collectionCopies() {
|
|
const original = new Set([1, 2]);
|
|
const copied = new Set(original);
|
|
copied.add(3);
|
|
const map = new Map([["one", 1], ["two", 2]]);
|
|
const copiedMap = new Map(map);
|
|
return [[...original], [...copied], [...copiedMap]];
|
|
}
|
|
|
|
export function decodeViews(input) {
|
|
const stored = new TextDecoder();
|
|
return [new TextDecoder().decode(input), stored.decode(input)];
|
|
}
|
|
|
|
export function mappedCollections() {
|
|
return [Array.from(new Set([1, 2]), value => value.toString()), Array.from(new Map([["one", 1]]), ([key, value]) => key + value)];
|
|
}
|
|
|
|
export function spreadPush() { const routes = []; routes.push(...[1, 2]); return routes; }
|
|
export function regexReset() { const re = new globalThis.RegExp(/^[+-]?\d+$/); re.lastIndex = 0; return [re.test("42"), re.test("wrong")]; }
|
|
|
|
export const staticFactory = () => class { static inherited = "base"; };
|
|
export class OwnStatic extends staticFactory() { static transform = value => value + 1; }
|
|
export function readOwnStatic() { return [OwnStatic.inherited, OwnStatic.transform(41), [OwnStatic.transform].map(fn => fn(41))]; }
|
|
export function arrayBufferBrand(value) { const ctor = globalThis.ArrayBuffer; return [value instanceof ctor, ctor === ArrayBuffer]; }
|
|
|
|
export function surplusCallbacks() {
|
|
const trace = [];
|
|
const object = { get callback() { trace.push("callee"); return () => 42; } };
|
|
const result = object.callback((trace.push("argument"), 1));
|
|
return [result, trace];
|
|
}
|
|
export class StaticReceiver {
|
|
static value = 42;
|
|
static read = function () { return this.value; };
|
|
}
|
|
export function ownStaticReceiver() { return StaticReceiver.read(); }
|
|
export class InheritedReceiver extends StaticReceiver { static value = 43; }
|
|
export function inheritedStaticReceiver() { return InheritedReceiver.read(); }
|
|
export function detachedStaticReceiver() {
|
|
const read = StaticReceiver.read;
|
|
try { return read(); } catch (error) { return error instanceof TypeError; }
|
|
}
|
|
export function methodEvaluationOrder() {
|
|
const trace = [];
|
|
const target = { callback: () => 1 };
|
|
const old = target.callback((target.callback = () => 2, trace.push("argument")));
|
|
const throwing = { get callback() { trace.push("getter"); throw new Error("stop"); } };
|
|
try { throwing.callback(trace.push("unexpected")); } catch { trace.push("caught"); }
|
|
const noncallable = { get callback() { trace.push("noncallable"); return undefined; } };
|
|
try { noncallable.callback(trace.push("evaluated")); } catch { trace.push("type-error"); }
|
|
const absent = {};
|
|
try { absent.callback((absent.callback = () => 3, trace.push("added"))); } catch { trace.push("still-absent"); }
|
|
const missing = null;
|
|
try { missing.callback(trace.push("unexpected-null")); } catch { trace.push("null-error"); }
|
|
return [old, target.callback(), trace];
|
|
}
|
|
export function surplusNativeCallback() {
|
|
let counter = 0;
|
|
const options = { callback: () => 42 };
|
|
const result = options.callback(++counter);
|
|
return [result, counter];
|
|
}
|