mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-03 07:54:40 +08:00
Call chalk builders with one string through a typed method
A callable class's %call1 method takes a single string argument directly, skipping the variadic closure's checked-dynamic call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6de7864697
commit
284517accb
@@ -435,12 +435,14 @@ export class ChalkInstance {
|
||||
box: LevelBox;
|
||||
styler: Styler | undefined;
|
||||
isEmpty: boolean;
|
||||
private readonly root: boolean;
|
||||
private readonly cache: (ChalkInstance | undefined)[] = [];
|
||||
|
||||
constructor(box: LevelBox, styler: Styler | undefined, isEmpty: boolean, root: boolean) {
|
||||
this.box = box;
|
||||
this.styler = styler;
|
||||
this.isEmpty = isEmpty;
|
||||
this.root = root;
|
||||
// One unconditional store: the field's definite assignment.
|
||||
this["%call"] = (...text: unknown[]): string =>
|
||||
root
|
||||
@@ -448,6 +450,12 @@ export class ChalkInstance {
|
||||
: applyStyle(this, text.length === 1 ? "" + String(text[0]) : joinArguments(text));
|
||||
}
|
||||
|
||||
/** One string argument: the compiler calls this instead of `%call`
|
||||
* (no variadic arguments to box). */
|
||||
"%call1"(text: string): string {
|
||||
return this.root ? text : applyStyle(this, text);
|
||||
}
|
||||
|
||||
get level(): ColorSupportLevel {
|
||||
return this.box.level as ColorSupportLevel;
|
||||
}
|
||||
|
||||
@@ -1632,6 +1632,8 @@ export function lowerCall(lowerer: Lowerer, expr: ts.CallExpression): IrExpr {
|
||||
// A getter returning a callable class instance (chalk's
|
||||
// `chalk.red("x")`): call through its `%call` field.
|
||||
if (callee.type.kind === "object") {
|
||||
const direct = callableInstanceStringCall(lowerer, expr, callee, locOf(expr));
|
||||
if (direct) return direct;
|
||||
callee = lowerer.hybridCallUnwrap(callee);
|
||||
if (callee.type.kind === "func") return lowerCallThroughValue(lowerer, expr, callee, locOf(expr));
|
||||
}
|
||||
@@ -1886,11 +1888,47 @@ export function lowerCall(lowerer: Lowerer, expr: ts.CallExpression): IrExpr {
|
||||
// a non-func IR type was already rejected while lowering the callee.
|
||||
// HYBRID (function-with-properties) values call through their %call slot.
|
||||
let callee = lowerer.lowerExpr(expr.expression);
|
||||
{
|
||||
const direct = callableInstanceStringCall(lowerer, expr, callee, loc);
|
||||
if (direct) return direct;
|
||||
}
|
||||
if (callee.type.kind === "record" || callee.type.kind === "object")
|
||||
callee = lowerer.hybridCallUnwrap(callee);
|
||||
return lowerCallThroughValue(lowerer, expr, callee, loc);
|
||||
}
|
||||
|
||||
/** A callable class instance called with one string: its `%call1` method
|
||||
* when the class has one (the chalk shim's typed fast path), skipping the
|
||||
* variadic closure's checked-dynamic arguments. */
|
||||
function callableInstanceStringCall(
|
||||
lowerer: Lowerer,
|
||||
expr: ts.CallExpression,
|
||||
callee: IrExpr,
|
||||
loc: SrcLoc,
|
||||
): IrExpr | null {
|
||||
if (callee.type.kind !== "object" || expr.arguments.nodes.length !== 1) return null;
|
||||
const arg = expr.arguments.nodes[0]!;
|
||||
if (ts.isSpreadElement(arg)) return null;
|
||||
const info = lowerer.classes.get(callee.type.className);
|
||||
if (info === undefined || !info.fields.has("%call") || !lowerer.findMethodOn(info, "%call1"))
|
||||
return null;
|
||||
const value = lowerer.lowerExpr(arg);
|
||||
if (value.type.kind === "string")
|
||||
return lowerer.accessorCall(callee.type.className, "%call1", callee, [value], STRING, loc);
|
||||
// Any other argument (a number behind a cast): the variadic closure,
|
||||
// through the checked-dynamic call as lowerCallThroughValue would.
|
||||
const closure = lowerer.hybridCallUnwrap(callee);
|
||||
if (closure.type.kind !== "func") return null;
|
||||
return {
|
||||
kind: "dynCall",
|
||||
callee: { kind: "dynFrom", value: closure, type: DYN, loc },
|
||||
calleeName: ts.isIdentifier(expr.expression) ? expr.expression.text : "value",
|
||||
args: [lowerer.coerceToExpected(value, DYN)],
|
||||
type: DYN,
|
||||
loc,
|
||||
};
|
||||
}
|
||||
|
||||
/** A call through an evaluated callee value: checked-dynamic callees,
|
||||
* function unions, typed-rest and runtime-arity closures. */
|
||||
function lowerCallThroughValue(
|
||||
@@ -9208,6 +9246,10 @@ export function lowerRecordFieldCall(
|
||||
// A HYBRID (function-with-properties) field is callable through its
|
||||
// reserved %call slot — `colors.blue("x")` where blue also carries
|
||||
// `.bold` (the chalk shape).
|
||||
if (callee.type.kind === "object" && !init) {
|
||||
const direct = callableInstanceStringCall(lowerer, call, callee, loc);
|
||||
if (direct) return direct;
|
||||
}
|
||||
if (callee.type.kind === "record" || callee.type.kind === "object")
|
||||
callee = lowerer.hybridCallUnwrap(callee);
|
||||
// Inferred JavaScript option records can retain checked callables in
|
||||
|
||||
Reference in New Issue
Block a user