mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-24 06:14:01 +08:00
Dispatch literal bracket calls to native class methods
This commit is contained in:
@@ -4897,6 +4897,29 @@ export function lowerCall(lowerer: Lowerer, expr: ts.CallExpression): IrExpr {
|
||||
ts.isStringLiteralLike(expr.expression.argumentExpression)
|
||||
) {
|
||||
const memberName = expr.expression.argumentExpression.text;
|
||||
const receiverType = lowerer.mapTypeOf(lowerer.typeOf(expr.expression.expression));
|
||||
if (receiverType?.kind === "object") {
|
||||
const info = lowerer.classes.get(receiverType.className);
|
||||
const found = info ? lowerer.findMethodOn(info, memberName) : null;
|
||||
if (info && found) {
|
||||
const virtual = lowerer.overrideBelow(info, memberName);
|
||||
if (found.sig.abstract === true && !virtual) {
|
||||
lowerer.unsupported("SC1090", expr, `calls of the abstract method '${memberName}' with no concrete implementation below the receiver's static class`);
|
||||
}
|
||||
if (virtual) lowerer.noteVirtualEdge(info, memberName);
|
||||
else lowerer.noteEdge(`%${found.declarer.def.name}.${memberName}`);
|
||||
const receiver = lowerer.lowerExpr(expr.expression.expression);
|
||||
const args = lowerer.completeArgs(expr.arguments, found.sig.params, locOf(expr), expr);
|
||||
return reconcileOverloadReturn(lowerer, expr, {
|
||||
...(virtual
|
||||
? { kind: "virtualCall" as const, className: info.def.name, method: memberName }
|
||||
: { kind: "call" as const, callee: `%${found.declarer.def.name}.${memberName}` }),
|
||||
args: [lowerer.upcastTo(receiver, virtual ? info.def.name : found.declarer.def.name), ...args],
|
||||
type: found.sig.ret,
|
||||
loc: locOf(expr),
|
||||
});
|
||||
}
|
||||
}
|
||||
// ts7's getSymbolAtLocation does not resolve element accesses; the
|
||||
// member symbol comes from the receiver's (apparent) type instead —
|
||||
// same provenance answer as the dot spelling's name symbol.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
class Base {
|
||||
value() { return 'base'; }
|
||||
}
|
||||
class Derived extends Base {
|
||||
value() { return 'derived'; }
|
||||
}
|
||||
const base = new Base();
|
||||
const derived = new Derived();
|
||||
console.log(base['value'](), derived['value']());
|
||||
let asBase = derived;
|
||||
console.log(asBase['value']());
|
||||
class Keyword {
|
||||
w\u0069th() { return 42; }
|
||||
}
|
||||
console.log(new Keyword()['with']());
|
||||
Reference in New Issue
Block a user