import { Node , ESTree } from "../../Node" ; import { BaseClosure , } from '../../Closure' ; import { Messages } from '../../Message' ; import { Interpreter } from '../../../interpreter/main' ; import { createScope } from '../../Scope' ; import { Return } from '../../TokenClass' ; import { defineFunctionName } from '../../../util' ; export function arrowFunctionExpressionHandler ( this , node ) { const source = this . source ; const oldDeclVars = this . collectDeclVars ; const oldDeclFuncs = this . collectDeclFuncs ; const oldDeclLex = this . collectDeclLex ; this . collectDeclVars = Object . create ( null ) ; this . collectDeclFuncs = Object . create ( null ) ; this . collectDeclLex = [ ] ; const name = 'anonymous_arrow_func' ; const paramLength = node . params . length ; const paramsGetter = node . params . map ( param => ( { type : param . type , closure : this . createParamNameGetter ( param ) , } ) ) ; this . blockDeclareStart ( ) ; const bodyClosure = this . createClosure ( node . expression === true ? { type : 'GroupStatement' , body : [ { type : 'ReturnStatement' , argument : node . body , } ] } : node . body ) ; let lexDecls = this . blockDeclareEnd ( ) ; const declVars = this . collectDeclVars ; const declFuncs = this . collectDeclFuncs ; const declLex = this . collectDeclLex ; this . collectDeclVars = oldDeclVars ; this . collectDeclFuncs = oldDeclFuncs ; this . collectDeclLex = oldDeclLex ; return ( ) => { const runtimeScope = this . getCurrentScope ( ) ; const ctx = this . getCurrentContext ( ) ; const func = ( ... args ) => { this . callStack . push ( `${ name }` ) ; const prevScope = this . getCurrentScope ( ) ; const currentScope = createScope ( runtimeScope , `FunctionScope(${ name })` ) ; currentScope . lexDeclared = lexDecls ! ; this . setCurrentScope ( currentScope ) ; this . addDeclarationsToScope ( declVars , declFuncs , currentScope ) ; paramsGetter . forEach ( ( getter , i ) => { if ( getter . type === 'RestElement' ) { currentScope . data [ getter . closure ( ) ] = args . slice ( i ) ; } else { currentScope . data [ getter . closure ( ) ] = args [ i ] ; } } ) ; const prevContext = this . getCurrentContext ( ) ; this . setCurrentContext ( ctx ) ; const result = bodyClosure ( ) ; this . setCurrentContext ( prevContext ) ; this . setCurrentScope ( prevScope ) ; this . callStack . pop ( ) ; if ( result instanceof Return ) { return result . value ; } } ; defineFunctionName ( func , name ) ; Object . defineProperty ( func , "toString" , { value : ( ) => { return source . slice ( node . start , node . end ) ; } , writable : true , configurable : true , enumerable : false , } ) ; Object . defineProperty ( func , "valueOf" , { value : ( ) => { return source . slice ( node . start , node . end ) ; } , writable : true , configurable : true , enumerable : false , } ) ; return func ; } ; }