54 lines
1.6 KiB
JavaScript
54 lines
1.6 KiB
JavaScript
|
import fastCall from '@/util/fast-call.js';
|
||
|
import {
|
||
|
isComputed,
|
||
|
isMemberExpression,
|
||
|
unwrap,
|
||
|
} from '@/swcx/types.js';
|
||
|
|
||
|
export default function(node, {evaluate, scope}) {
|
||
|
let asyncArgs = false;
|
||
|
const args = [];
|
||
|
for (let i = 0; i < node.arguments.length; i++) {
|
||
|
const {expression: arg} = node.arguments[i];
|
||
|
const {async, value} = evaluate(arg, {scope});
|
||
|
asyncArgs ||= async;
|
||
|
args.push(value);
|
||
|
}
|
||
|
const {callee: wrappedCallee} = node;
|
||
|
const callee = unwrap(wrappedCallee);
|
||
|
const callOptional = callee.wrapper?.optional || node.wrapper?.optional;
|
||
|
const invoke = (fn, holder, args) => {
|
||
|
if (callOptional && !fn) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return fastCall(fn, holder, args);
|
||
|
};
|
||
|
if (!isMemberExpression(callee)) {
|
||
|
const {async, value} = evaluate(callee, {scope});
|
||
|
if (asyncArgs || async) {
|
||
|
return {
|
||
|
async: true,
|
||
|
value: Promise
|
||
|
.all([value, Promise.all(args)])
|
||
|
.then(([callee, args]) => invoke(callee, undefined, args)),
|
||
|
};
|
||
|
}
|
||
|
return {value: invoke(value, undefined, args)};
|
||
|
}
|
||
|
const {
|
||
|
object,
|
||
|
property,
|
||
|
} = callee;
|
||
|
const O = evaluate(object, {scope});
|
||
|
const P = isComputed(property) ? evaluate(property, {scope}) : {value: property.value};
|
||
|
if (asyncArgs || O.async || P.async) {
|
||
|
return {
|
||
|
async: true,
|
||
|
value: Promise
|
||
|
.all([O.value, P.value, Promise.all(args)])
|
||
|
.then(([O, P, args]) => invoke(callOptional ? O?.[P] : O[P], O, args)),
|
||
|
};
|
||
|
}
|
||
|
return {value: invoke(callOptional ? O.value?.[P.value] : O.value[P.value], O.value, args)};
|
||
|
}
|