@@ -269,16 +269,17 @@ const defaultMethods = {
269269 } ,
270270 // Adding this to spec something out, not to merge it quite yet
271271 val : {
272- method : ( args , context , above ) => {
272+ method : ( args , context , above , engine ) => {
273273 if ( Array . isArray ( args ) && args . length === 1 ) args = args [ 0 ]
274+ // A unary optimization
274275 if ( ! Array . isArray ( args ) ) {
275- if ( args === null || args === undefined ) return context
276276 const result = context [ args ]
277277 if ( typeof result === 'undefined' ) return null
278278 return result
279279 }
280280 let result = context
281281 let start = 0
282+ // This block handles scope traversal
282283 if ( Array . isArray ( args [ 0 ] ) && args [ 0 ] . length === 1 ) {
283284 start ++
284285 const climb = + Math . abs ( args [ 0 ] [ 0 ] )
@@ -292,12 +293,13 @@ const defaultMethods = {
292293 }
293294 }
294295 }
296+ // This block handles traversing the path
295297 for ( let i = start ; i < args . length ; i ++ ) {
296- if ( args [ i ] === null ) continue
297298 if ( result === null || result === undefined ) return null
298299 result = result [ args [ i ] ]
299300 }
300301 if ( typeof result === 'undefined' ) return null
302+ if ( typeof result === 'function' && ! engine . allowFunctions ) return null
301303 return result
302304 } ,
303305 optimizeUnary : true ,
@@ -310,9 +312,14 @@ const defaultMethods = {
310312 } ,
311313 compile : ( data , buildState ) => {
312314 function wrapNull ( data ) {
313- if ( ! chainingSupported ) return buildState . compile `((( a) => a === null || a === undefined ? null : a)(${ data } ))`
314- return buildState . compile `(${ data } ?? null)`
315+ if ( ! chainingSupported ) return buildState . compile `(methods.preventFunctions((( a) => a === null || a === undefined ? null : a)(${ data } ) ))`
316+ return buildState . compile `(methods.preventFunctions( ${ data } ?? null) )`
315317 }
318+
319+ if ( ! buildState . engine . allowFunctions ) buildState . methods . preventFunctions = a => typeof a === 'function' ? null : a
320+ else buildState . methods . preventFunctions = a => a
321+
322+ if ( typeof data === 'object' && ! Array . isArray ( data ) ) return false
316323 if ( Array . isArray ( data ) && Array . isArray ( data [ 0 ] ) ) {
317324 // A very, very specific optimization.
318325 if ( buildState . iteratorCompile && Math . abs ( data [ 0 ] [ 0 ] || 0 ) === 1 && data [ 1 ] === 'index' ) return buildState . compile `index`
@@ -445,7 +452,7 @@ const defaultMethods = {
445452 buildState . methods . push ( mapper )
446453 if ( async ) {
447454 if ( ! isSync ( mapper ) || selector . includes ( 'await' ) ) {
448- buildState . detectAsync = true
455+ buildState . asyncDetected = true
449456 if ( typeof defaultValue !== 'undefined' ) {
450457 return `await asyncIterators.reduce(${ selector } || [], (a,b) => methods[${
451458 buildState . methods . length - 1
@@ -672,8 +679,8 @@ function createArrayIterativeMethod (name, useTruthy = false) {
672679 const aboveArray = method . aboveDetected ? buildState . compile `[{ iterator: z, index: x }, context, above]` : buildState . compile `null`
673680
674681 if ( async ) {
675- if ( ! isSyncDeep ( mapper , buildState . engine , buildState ) ) {
676- buildState . detectAsync = true
682+ if ( ! isSync ( method ) ) {
683+ buildState . asyncDetected = true
677684 return buildState . compile `await asyncIterators[${ name } ](${ selector } || [], async (i, x, z) => ${ method } (i, x, ${ aboveArray } ))`
678685 }
679686 }
0 commit comments