mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
Hold Reflect.ownKeys's function value in the Reflect namespace object
Reading `ownKeys` from Reflect read as a value (`const r = Reflect; r.ownKeys`) gave the member function that throws SC1090 when called, although the spelled `Reflect.ownKeys` read already has a function value. The namespace object now holds that function value, so calls through the alias run and `r.ownKeys === Reflect.ownKeys` is true, as in Node. The spelled read and the namespace member share one lowering (reflectMemberValue).
This commit is contained in:
@@ -24,6 +24,7 @@ import type { Lowerer } from "./lowerer.js";
|
||||
import { InternalCompilerError } from "../../errors.js";
|
||||
import { mathMemberValue } from "./lower-stdlib.js";
|
||||
import { jsonMemberValue } from "./builtins/json.js";
|
||||
import { reflectMemberValue } from "./builtins/reflection.js";
|
||||
|
||||
/** A function member with its `length`, or a constant (`length` -1). */
|
||||
interface NamespaceMember {
|
||||
@@ -244,7 +245,7 @@ function functionValue(lowerer: Lowerer, canonical: string, key: string, loc: Sr
|
||||
? mathMemberValue(lowerer, key, loc)
|
||||
: canonical === "JSON"
|
||||
? jsonMemberValue(lowerer, key, loc)
|
||||
: null;
|
||||
: reflectMemberValue(lowerer, key, loc);
|
||||
if (value !== null)
|
||||
return value.type.kind === "dyn"
|
||||
? value
|
||||
|
||||
@@ -3,7 +3,24 @@ import * as ts from "../../ts7/adapter.js";
|
||||
import { type Lowerer } from "../lowerer.js";
|
||||
import { locOf } from "../../program.js";
|
||||
import { builtinModuleFnOf } from "../surfaces.js";
|
||||
import { BOOL, DYN, type IrExpr, STRING, arrayOf } from "../../../ir/ir.js";
|
||||
import { BOOL, DYN, type IrExpr, STRING, type SrcLoc, arrayOf } from "../../../ir/ir.js";
|
||||
|
||||
/** The function value of the Reflect member `member` (ownKeys, on native
|
||||
* computed-key reflection), or null for members without one. */
|
||||
export function reflectMemberValue(lowerer: Lowerer, member: string, loc: SrcLoc): IrExpr | null {
|
||||
if (member !== "ownKeys") return null;
|
||||
const value = lowerer.lowerNativeCallableValue(
|
||||
{
|
||||
fn: "dyn.ownKeys",
|
||||
params: [DYN],
|
||||
result: DYN,
|
||||
valueParams: [{ mode: "required", type: DYN }],
|
||||
},
|
||||
"Reflect.ownKeys",
|
||||
loc,
|
||||
)!;
|
||||
return { kind: "dynFrom", value, fnName: "ownKeys", type: DYN, loc };
|
||||
}
|
||||
|
||||
/** Reflect.ownKeys uses native computed-key reflection. Reflect.apply(target,
|
||||
* thisArg, argsList) where the TARGET is a builtin
|
||||
|
||||
@@ -161,6 +161,7 @@ import { lowerNetAddressStaticRead } from "../builtins/net-address.js";
|
||||
import { STATS_TYPE_TESTS } from "../builtins/filesystem.js";
|
||||
import { arrayValueRead, arrayValueType } from "../array-values.js";
|
||||
import { lowerClassMethodValue } from "../class-method-values.js";
|
||||
import { reflectMemberValue } from "../builtins/reflection.js";
|
||||
import {
|
||||
objLitGenericFnInfoOf,
|
||||
objLitGenericFnNodeOf,
|
||||
@@ -1691,19 +1692,8 @@ export function lowerIntrinsicProperty(
|
||||
);
|
||||
}
|
||||
}
|
||||
if (lowerer.stdlibGlobalMember(expr, "Reflect") === "ownKeys") {
|
||||
const value = lowerer.lowerNativeCallableValue(
|
||||
{
|
||||
fn: "dyn.ownKeys",
|
||||
params: [DYN],
|
||||
result: DYN,
|
||||
valueParams: [{ mode: "required", type: DYN }],
|
||||
},
|
||||
"Reflect.ownKeys",
|
||||
locOf(expr),
|
||||
)!;
|
||||
return { kind: "dynFrom", value, fnName: "ownKeys", type: DYN, loc: locOf(expr) };
|
||||
}
|
||||
if (lowerer.stdlibGlobalMember(expr, "Reflect") === "ownKeys")
|
||||
return reflectMemberValue(lowerer, "ownKeys", locOf(expr));
|
||||
if (lowerer.chainBlocked(expr)) return null;
|
||||
// Object.prototype.constructor: the Object constructor value.
|
||||
if (
|
||||
|
||||
@@ -20,3 +20,8 @@ console.log(parse("[1,2]").length, JSON.stringify({ a: [1] }));
|
||||
|
||||
console.log(typeof Math === "object" && typeof Reflect === "object");
|
||||
console.log(Math.max.length, Math.min.length, Math.hypot.length, Math.abs.length);
|
||||
|
||||
const r = Reflect;
|
||||
const ownKeys = r.ownKeys;
|
||||
console.log(ownKeys === Reflect.ownKeys, r.ownKeys === Reflect.ownKeys, typeof ownKeys);
|
||||
console.log(r.ownKeys({ a: 1, b: 2 }).length, ownKeys({ c: 3 })[0], ownKeys.name, ownKeys.length);
|
||||
|
||||
Reference in New Issue
Block a user