diff options
| author | Daniel Luz | 2012-11-04 11:05:58 -0200 |
|---|---|---|
| committer | Misko Hevery | 2013-02-14 14:43:56 -0800 |
| commit | 1ed638582d2f2c7f89384d9712f4cfac52cc5b70 (patch) | |
| tree | 2e2868b6939f2db28ed0cdb9692a32a3b8b85b8d /src/ng | |
| parent | 3b14092135ab02a4b08c0ba21d40726684acf83e (diff) | |
| download | angular.js-1ed638582d2f2c7f89384d9712f4cfac52cc5b70.tar.bz2 | |
feat($parse): added `constant` and `literal` properties
* `literal` is set to true if the expression's top-level is a JavaScript
literal (number, string, boolean, null/undefined, array, object), even
if it contains non-literals inside.
* `constant` is set to true if the expression is known to be made
entirely of constant values, i.e., evaluating it will always yield the
same result.
A consequence is that a JSON expression is guaranteed to be both literal
and constant.
Diffstat (limited to 'src/ng')
| -rw-r--r-- | src/ng/parse.js | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/src/ng/parse.js b/src/ng/parse.js index 60181f96..4651fc10 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -303,6 +303,8 @@ function parser(text, json, $filter, csp){ if (tokens.length !== 0) { throwError("is an unexpected token", tokens[0]); } + value.literal = !!value.literal; + value.constant = !!value.constant; return value; /////////////////////////////////// @@ -350,15 +352,19 @@ function parser(text, json, $filter, csp){ } function unaryFn(fn, right) { - return function(self, locals) { + return extend(function(self, locals) { return fn(self, locals, right); - }; + }, { + constant:right.constant + }); } function binaryFn(left, fn, right) { - return function(self, locals) { + return extend(function(self, locals) { return fn(self, locals, left, right); - }; + }, { + constant:left.constant && right.constant + }); } function statements() { @@ -526,6 +532,9 @@ function parser(text, json, $filter, csp){ if (!primary) { throwError("not a primary expression", token); } + if (token.json) { + primary.constant = primary.literal = true; + } } var next, context; @@ -614,23 +623,32 @@ function parser(text, json, $filter, csp){ // This is used with json array declaration function arrayDeclaration () { var elementFns = []; + var allConstant = true; if (peekToken().text != ']') { do { - elementFns.push(expression()); + var elementFn = expression(); + elementFns.push(elementFn); + if (!elementFn.constant) { + allConstant = false; + } } while (expect(',')); } consume(']'); - return function(self, locals){ + return extend(function(self, locals){ var array = []; for ( var i = 0; i < elementFns.length; i++) { array.push(elementFns[i](self, locals)); } return array; - }; + }, { + literal:true, + constant:allConstant + }); } function object () { var keyValues = []; + var allConstant = true; if (peekToken().text != '}') { do { var token = expect(), @@ -638,10 +656,13 @@ function parser(text, json, $filter, csp){ consume(":"); var value = expression(); keyValues.push({key:key, value:value}); + if (!value.constant) { + allConstant = false; + } } while (expect(',')); } consume('}'); - return function(self, locals){ + return extend(function(self, locals){ var object = {}; for ( var i = 0; i < keyValues.length; i++) { var keyValue = keyValues[i]; @@ -649,7 +670,10 @@ function parser(text, json, $filter, csp){ object[keyValue.key] = value; } return object; - }; + }, { + literal:true, + constant:allConstant + }); } } @@ -853,8 +877,13 @@ function getterFn(path, csp) { * * `locals` – `{object=}` – local variables context object, useful for overriding values in * `context`. * - * The return function also has an `assign` property, if the expression is assignable, which - * allows one to set values to expressions. + * The returned function also has the following properties: + * * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript + * literal. + * * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript + * constant literals. + * * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be + * set to a function to change its value on the given context. * */ function $ParseProvider() { |
