54 lines
1.4 KiB
JavaScript
54 lines
1.4 KiB
JavaScript
import fastCall from '@/util/fast-call.js';
|
|
|
|
export default function(node, {evaluate, scope}) {
|
|
let asyncArgs = false;
|
|
const args = [];
|
|
for (let i = 0; i < node.arguments.length; i++) {
|
|
const arg = node.arguments[i];
|
|
const {async, value} = evaluate(arg, {scope});
|
|
asyncArgs ||= async;
|
|
args.push(value);
|
|
}
|
|
const {callee} = node;
|
|
const {
|
|
computed,
|
|
object,
|
|
property,
|
|
} = callee;
|
|
const invoke = (fn, holder, args) => {
|
|
if (node.optional && !fn) {
|
|
return undefined;
|
|
}
|
|
return fastCall(fn, holder, args);
|
|
};
|
|
if (!('MemberExpression' === callee.type)) {
|
|
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 O = evaluate(object, {scope});
|
|
const P = computed
|
|
? evaluate(property, {scope})
|
|
// Otherwise, identifier.
|
|
: {value: property.name};
|
|
if (asyncArgs || O.async || P.async) {
|
|
return {
|
|
async: true,
|
|
value: Promise
|
|
.all([O.value, P.value, Promise.all(args)])
|
|
.then(([O, P, args]) => invoke(callee.optional ? O?.[P] : O[P], O, args)),
|
|
};
|
|
}
|
|
return {
|
|
async: false,
|
|
value: invoke(callee.optional ? O.value?.[P.value] : O.value[P.value], O.value, args),
|
|
};
|
|
}
|