@@ -303,6 +303,8 @@ function parser(text, json, $filter, csp){
303
303
if ( tokens . length !== 0 ) {
304
304
throwError ( "is an unexpected token" , tokens [ 0 ] ) ;
305
305
}
306
+ value . literal = ! ! value . literal ;
307
+ value . constant = ! ! value . constant ;
306
308
return value ;
307
309
308
310
///////////////////////////////////
@@ -350,15 +352,19 @@ function parser(text, json, $filter, csp){
350
352
}
351
353
352
354
function unaryFn ( fn , right ) {
353
- return function ( self , locals ) {
355
+ return extend ( function ( self , locals ) {
354
356
return fn ( self , locals , right ) ;
355
- } ;
357
+ } , {
358
+ constant :right . constant
359
+ } ) ;
356
360
}
357
361
358
362
function binaryFn ( left , fn , right ) {
359
- return function ( self , locals ) {
363
+ return extend ( function ( self , locals ) {
360
364
return fn ( self , locals , left , right ) ;
361
- } ;
365
+ } , {
366
+ constant :left . constant && right . constant
367
+ } ) ;
362
368
}
363
369
364
370
function statements ( ) {
@@ -526,6 +532,9 @@ function parser(text, json, $filter, csp){
526
532
if ( ! primary ) {
527
533
throwError ( "not a primary expression" , token ) ;
528
534
}
535
+ if ( token . json ) {
536
+ primary . constant = primary . literal = true ;
537
+ }
529
538
}
530
539
531
540
var next , context ;
@@ -614,42 +623,57 @@ function parser(text, json, $filter, csp){
614
623
// This is used with json array declaration
615
624
function arrayDeclaration ( ) {
616
625
var elementFns = [ ] ;
626
+ var allConstant = true ;
617
627
if ( peekToken ( ) . text != ']' ) {
618
628
do {
619
- elementFns . push ( expression ( ) ) ;
629
+ var elementFn = expression ( ) ;
630
+ elementFns . push ( elementFn ) ;
631
+ if ( ! elementFn . constant ) {
632
+ allConstant = false ;
633
+ }
620
634
} while ( expect ( ',' ) ) ;
621
635
}
622
636
consume ( ']' ) ;
623
- return function ( self , locals ) {
637
+ return extend ( function ( self , locals ) {
624
638
var array = [ ] ;
625
639
for ( var i = 0 ; i < elementFns . length ; i ++ ) {
626
640
array . push ( elementFns [ i ] ( self , locals ) ) ;
627
641
}
628
642
return array ;
629
- } ;
643
+ } , {
644
+ literal :true ,
645
+ constant :allConstant
646
+ } ) ;
630
647
}
631
648
632
649
function object ( ) {
633
650
var keyValues = [ ] ;
651
+ var allConstant = true ;
634
652
if ( peekToken ( ) . text != '}' ) {
635
653
do {
636
654
var token = expect ( ) ,
637
655
key = token . string || token . text ;
638
656
consume ( ":" ) ;
639
657
var value = expression ( ) ;
640
658
keyValues . push ( { key :key , value :value } ) ;
659
+ if ( ! value . constant ) {
660
+ allConstant = false ;
661
+ }
641
662
} while ( expect ( ',' ) ) ;
642
663
}
643
664
consume ( '}' ) ;
644
- return function ( self , locals ) {
665
+ return extend ( function ( self , locals ) {
645
666
var object = { } ;
646
667
for ( var i = 0 ; i < keyValues . length ; i ++ ) {
647
668
var keyValue = keyValues [ i ] ;
648
669
var value = keyValue . value ( self , locals ) ;
649
670
object [ keyValue . key ] = value ;
650
671
}
651
672
return object ;
652
- } ;
673
+ } , {
674
+ literal :true ,
675
+ constant :allConstant
676
+ } ) ;
653
677
}
654
678
}
655
679
@@ -853,8 +877,13 @@ function getterFn(path, csp) {
853
877
* * `locals` – `{object=}` – local variables context object, useful for overriding values in
854
878
* `context`.
855
879
*
856
- * The return function also has an `assign` property, if the expression is assignable, which
857
- * allows one to set values to expressions.
880
+ * The returned function also has the following properties:
881
+ * * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript
882
+ * literal.
883
+ * * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript
884
+ * constant literals.
885
+ * * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be
886
+ * set to a function to change its value on the given context.
858
887
*
859
888
*/
860
889
function $ParseProvider ( ) {
0 commit comments