visitFunctionNode method
dynamic
visitFunctionNode(
- FunctionNode node, {
- bool? inheritContext,
})
Implementation
@override
visitFunctionNode(FunctionNode node, {bool? inheritContext}) {
final List<dynamic> args = computeArguments(node.params);
final capturedLexicalContexts =
List<_LexicalContext>.from(_lexicalContexts);
late JavascriptFunction fn;
fn = JavascriptFunction((List<dynamic>? _params, [dynamic thisArg]) {
/*
1. create a map, parmValueMap
2. go through params and create a args[i]: parm[i] entry in the map
3. push the map to the context stack
4. execute the blockstatement or expression
*/
List<dynamic> params = _params ?? [];
Map<String, dynamic> ctx = {};
if (node.params != null) {
for (int i = 0; i < node.params.length; i++) {
final param = node.params[i];
if (param is RestParameter) {
_bindParameter(ctx, param.name, params.skip(i).toList(),
line: param.line ?? node.line ?? 1);
break;
}
dynamic value = i < params.length ? params[i] : null;
if (param is DefaultParameter && value == null) {
value = getValueFromExpression(param.defaultValue);
}
_bindParameter(
ctx, param is DefaultParameter ? param.name : param, value,
line: param.line ?? node.line ?? 1);
}
}
ctx['arguments'] = _buildArgumentsObject(params, fn);
ctx['this'] = thisArg ?? getContextForScope(program).getContextMap();
Context context = SimpleContext(ctx);
// Inherit parent contexts so nested functions can see outer declarations.
JSInterpreter i = cloneForContext(node, context, inheritContext ?? true);
i._lexicalContexts
..clear()
..addAll(capturedLexicalContexts);
if (node.isAsync) {
return JSPromise.fromFuture(i._executeAsyncBody(node.body));
}
dynamic rtn;
try {
if (node.body != null) {
rtn = node.body.visitBy(i);
}
} on ControlFlowReturnException catch (e) {
rtn = e.returnValue;
}
if (rtn is Node) {
rtn = i.getValueFromNode(rtn);
}
return rtn;
}, code.substring(node.start!, node.end));
return fn;
}