@@ -158,39 +158,6 @@ function isArrayElementCompatible(expected, elem) {
158158 return expected . kind === elem . kind ;
159159}
160160
161- // Used to concatenate all elements into a string, like `1 + "a" + 12` -> "1a12".
162- function concatExprAsString ( elems ) {
163- let out = '' ;
164- for ( const elem of elems ) {
165- if ( elem . kind === 'operator' ) {
166- continue ;
167- } else if ( [ 'number' , 'string' , 'boolean' ] . includes ( elem . kind ) ) {
168- out += elem . value ;
169- } else {
170- out += concatExprAsString ( elem . value ) ;
171- }
172- }
173- return out ;
174- }
175-
176- function concatExprAsObjectPath ( elems ) {
177- let s = '' ;
178- const parts = [ ] ;
179-
180- for ( const elem of elems ) {
181- if ( elem . kind === 'operator' ) {
182- continue ;
183- } else if ( elem . kind !== 'object-path' ) {
184- s += concatExprAsString ( [ elem ] ) ;
185- } else {
186- elem . value [ 0 ] . value = s + elem . value [ 0 ] . value ;
187- parts . push ( ...elem . value ) ;
188- s = '' ;
189- }
190- }
191- return parts ;
192- }
193-
194161// This function is used when generating an expression interpreted as a boolean.
195162function concatExprAsExpr ( elems ) {
196163 const out = [ ] ;
@@ -261,24 +228,19 @@ function canBeCompared(kind1, kind2) {
261228}
262229
263230function convertAsString ( elem ) {
264- if ( elem . value . some ( v => v . kind === 'object-path' ) ) {
265- return new ObjectPathElement (
266- concatExprAsObjectPath ( elem . value ) ,
267- elem . startPos ,
268- elem . endPos ,
269- elem . fullText ,
270- elem . line ,
271- elem . error ,
272- ) ;
273- }
274- return new StringElement (
275- concatExprAsString ( elem . value ) ,
276- elem . startPos ,
277- elem . endPos ,
278- elem . fullText ,
279- elem . line ,
280- elem . error ,
281- ) ;
231+ const pos = elem . value . findIndex ( v => v . kind === 'object-path' ) ;
232+ elem . kind = 'string' ;
233+ if ( pos !== - 1 ) {
234+ // We remove the object-path from the expression.
235+ const objPath = elem . value . pop ( ) ;
236+ // We remove the first item of the object path and push it at the end of the expression.
237+ elem . value . push ( ...objPath . value . splice ( 0 , 1 ) ) ;
238+ // We put the expression as the first element of the object path.
239+ objPath . value . splice ( 0 , 0 , elem ) ;
240+ // All done!
241+ return objPath ;
242+ }
243+ return elem ;
282244}
283245
284246function convertExprAs ( elem , convertAs ) {
@@ -363,7 +325,8 @@ class Element {
363325 }
364326
365327 isRecursive ( ) {
366- // Only Tuple and JSON elements are "recursive" (meaning they can contain sub-levels).
328+ // Expression, Array, Tuple and JSON elements are "recursive" (meaning they can contain
329+ // sub-levels).
367330 return false ;
368331 }
369332
@@ -433,6 +396,18 @@ class ExpressionElement extends Element {
433396 super ( 'expression' , value , startPos , endPos , fullText , line , error ) ;
434397 }
435398
399+ isRecursive ( ) {
400+ return true ;
401+ }
402+
403+ displayInCode ( ) {
404+ return this . value . map ( v => v . displayInCode ( ) ) . join ( '' ) ;
405+ }
406+
407+ getStringValue ( ) {
408+ return this . value . map ( v => v . getStringValue ( ) ) . join ( '' ) ;
409+ }
410+
436411 clone ( ) {
437412 const elems = this . value . map ( elem => elem . clone ( ) ) ;
438413 return new this . constructor (
@@ -537,8 +512,8 @@ class ObjectPathElement extends Element {
537512 super ( 'object-path' , value , startPos , endPos , fullText , line , error ) ;
538513 }
539514
540- getStringValue ( trim , clean = true ) {
541- const content = this . value . map ( v => `" ${ v . getStringValue ( clean ) } " ` ) . join ( ',' ) ;
515+ getStringValue ( ) {
516+ const content = this . value . map ( v => `${ v . displayInCode ( ) } ` ) . join ( ',' ) ;
542517 return `[${ content } ]` ;
543518 }
544519
0 commit comments