aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2011-04-05 11:00:26 -0700
committerMisko Hevery2011-06-08 15:01:32 -0700
commit0e17ade959cc77369dc102d180e43be2af68505a (patch)
tree334c001ee00005eb3f67325523feb2afd961fdad
parentbb67ee8d28f2cddb4b503dc8909649994a4d67e1 (diff)
downloadangular.js-0e17ade959cc77369dc102d180e43be2af68505a.tar.bz2
Cleanup parser code to expose smaller API
-rw-r--r--src/JSON.js9
-rw-r--r--src/Scope.js1
-rw-r--r--src/parser.js53
-rw-r--r--test/BinderSpec.js2
-rw-r--r--test/JsonSpec.js14
-rw-r--r--test/ParserSpec.js2
-rw-r--r--test/widgetsSpec.js4
7 files changed, 31 insertions, 54 deletions
diff --git a/src/JSON.js b/src/JSON.js
index 186bdb1c..942ce7c0 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -35,19 +35,14 @@ function toJson(obj, pretty) {
function fromJson(json, useNative) {
if (!isString(json)) return json;
- var obj, p, expression;
+ var obj;
try {
if (useNative && window.JSON && window.JSON.parse) {
obj = JSON.parse(json);
return transformDates(obj);
}
-
- p = parser(json, true);
- expression = p.primary();
- p.assertAllConsumed();
- return expression();
-
+ return parser(json, true).primary()();
} catch (e) {
error("fromJson error: ", json, e);
throw e;
diff --git a/src/Scope.js b/src/Scope.js
index bf582474..1ab583e8 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -92,7 +92,6 @@ function expressionCompile(exp){
if (!fn) {
var p = parser(exp);
var fnSelf = p.statements();
- p.assertAllConsumed();
fn = compileCache[exp] = extend(
function(){ return fnSelf(this);},
{fnSelf: fnSelf});
diff --git a/src/parser.js b/src/parser.js
index 8d7e607c..59d7899a 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -240,22 +240,29 @@ function parser(text, json){
function (){ throwError("is not valid json", {text:text, index:0}); };
}
return {
- assertAllConsumed: assertAllConsumed,
- assignable: assignable,
- primary: primary,
- statements: statements,
- validator: validator,
- formatter: formatter,
- filter: filter,
- //TODO: delete me, since having watch in UI is logic in UI. (leftover form getangular)
- watch: watch
+ assignable: assertConsumed(assignable),
+ primary: assertConsumed(primary),
+ statements: assertConsumed(statements),
+ validator: assertConsumed(validator),
+ formatter: assertConsumed(formatter),
+ filter: assertConsumed(filter)
};
+ function assertConsumed(fn) {
+ return function(){
+ var value = fn();
+ if (tokens.length !== 0) {
+ throwError("is an unexpected token", tokens[0]);
+ }
+ return value;
+ };
+ }
+
///////////////////////////////////
function throwError(msg, token) {
- throw Error("Parse Error: Token '" + token.text +
+ throw Error("Syntax Error: Token '" + token.text +
"' " + msg + " at column " +
- (token.index + 1) + " of expression [" +
+ (token.index + 1) + " of the expression [" +
text + "] starting at [" + text.substring(token.index) + "].");
}
@@ -313,12 +320,6 @@ function parser(text, json){
return tokens.length > 0;
}
- function assertAllConsumed(){
- if (tokens.length !== 0) {
- throwError("is extra token not part of expression", tokens[0]);
- }
- }
-
function statements(){
var statements = [];
while(true) {
@@ -639,24 +640,6 @@ function parser(text, json){
};
}
- //TODO: delete me, since having watch in UI is logic in UI. (leftover form getangular)
- function watch () {
- var decl = [];
- while(hasTokens()) {
- decl.push(watchDecl());
- if (!expect(';')) {
- assertAllConsumed();
- }
- }
- assertAllConsumed();
- return function (self){
- for ( var i = 0; i < decl.length; i++) {
- var d = decl[i](self);
- self.addListener(d.name, d.fn);
- }
- };
- }
-
function watchDecl () {
var anchorName = expect().text;
consume(":");
diff --git a/test/BinderSpec.js b/test/BinderSpec.js
index dfa388e3..15a1b5c7 100644
--- a/test/BinderSpec.js
+++ b/test/BinderSpec.js
@@ -581,7 +581,7 @@ describe('Binder', function(){
browserTrigger(second, 'click');
assertTrue(second.hasClass("ng-exception"));
- expect(errorLogs.shift()[0]).toMatchError(/Parse Error: Token ':' not a primary expression/);
+ expect(errorLogs.shift()[0]).toMatchError(/Syntax Error: Token ':' not a primary expression/);
});
it('ItShouldSelectTheCorrectRadioBox', function(){
diff --git a/test/JsonSpec.js b/test/JsonSpec.js
index 3b81a44f..0dac0318 100644
--- a/test/JsonSpec.js
+++ b/test/JsonSpec.js
@@ -163,37 +163,37 @@ describe('json', function(){
describe('security', function(){
it('should not allow naked expressions', function(){
expect(function(){fromJson('1+2');}).
- toThrow(new Error("Parse Error: Token '+' is extra token not part of expression at column 2 of expression [1+2] starting at [+2]."));
+ toThrow(new Error("Syntax Error: Token '+' is an unexpected token at column 2 of the expression [1+2] starting at [+2]."));
});
it('should not allow naked expressions group', function(){
expect(function(){fromJson('(1+2)');}).
- toThrow(new Error("Parse Error: Token '(' is not valid json at column 1 of expression [(1+2)] starting at [(1+2)]."));
+ toThrow(new Error("Syntax Error: Token '(' is not valid json at column 1 of the expression [(1+2)] starting at [(1+2)]."));
});
it('should not allow expressions in objects', function(){
expect(function(){fromJson('{a:abc()}');}).
- toThrow(new Error("Parse Error: Token 'abc' is not valid json at column 4 of expression [{a:abc()}] starting at [abc()}]."));
+ toThrow(new Error("Syntax Error: Token 'abc' is not valid json at column 4 of the expression [{a:abc()}] starting at [abc()}]."));
});
it('should not allow expressions in arrays', function(){
expect(function(){fromJson('[1+2]');}).
- toThrow(new Error("Parse Error: Token '+' is not valid json at column 3 of expression [[1+2]] starting at [+2]]."));
+ toThrow(new Error("Syntax Error: Token '+' is not valid json at column 3 of the expression [[1+2]] starting at [+2]]."));
});
it('should not allow vars', function(){
expect(function(){fromJson('[1, x]');}).
- toThrow(new Error("Parse Error: Token 'x' is not valid json at column 5 of expression [[1, x]] starting at [x]]."));
+ toThrow(new Error("Syntax Error: Token 'x' is not valid json at column 5 of the expression [[1, x]] starting at [x]]."));
});
it('should not allow dereference', function(){
expect(function(){fromJson('["".constructor]');}).
- toThrow(new Error("Parse Error: Token '.' is not valid json at column 4 of expression [[\"\".constructor]] starting at [.constructor]]."));
+ toThrow(new Error("Syntax Error: Token '.' is not valid json at column 4 of the expression [[\"\".constructor]] starting at [.constructor]]."));
});
it('should not allow expressions ofter valid json', function(){
expect(function(){fromJson('[].constructor');}).
- toThrow(new Error("Parse Error: Token '.' is not valid json at column 3 of expression [[].constructor] starting at [.constructor]."));
+ toThrow(new Error("Syntax Error: Token '.' is not valid json at column 3 of the expression [[].constructor] starting at [.constructor]."));
});
it('should not allow object dereference', function(){
diff --git a/test/ParserSpec.js b/test/ParserSpec.js
index 62d6731a..641420cb 100644
--- a/test/ParserSpec.js
+++ b/test/ParserSpec.js
@@ -200,7 +200,7 @@ describe('parser', function() {
expect(function() {
scope.$eval("1|nonExistant");
- }).toThrow(new Error("Parse Error: Token 'nonExistant' should be a function at column 3 of expression [1|nonExistant] starting at [nonExistant]."));
+ }).toThrow(new Error("Syntax Error: Token 'nonExistant' should be a function at column 3 of the expression [1|nonExistant] starting at [nonExistant]."));
scope.$set('offset', 3);
expect(scope.$eval("'abcd'|upper._case")).toEqual("ABCD");
diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js
index 36aabb33..b412cd6d 100644
--- a/test/widgetsSpec.js
+++ b/test/widgetsSpec.js
@@ -537,7 +537,7 @@ describe("widget", function(){
compile('<input type="text" name="throw \'\'" value="x"/>');
expect(element.hasClass('ng-exception')).toBeTruthy();
expect(scope.$service('$log').error.logs.shift()[0]).
- toMatchError(/Parse Error: Token '''' is extra token not part of expression/);
+ toMatchError(/Syntax Error: Token '''' is an unexpected token/);
});
it('should report error on ng:change exception', function(){
@@ -545,7 +545,7 @@ describe("widget", function(){
browserTrigger(element);
expect(element.hasClass('ng-exception')).toBeTruthy();
expect(scope.$service('$log').error.logs.shift()[0]).
- toMatchError(/Parse Error: Token '=' implies assignment but \[a-2\] can not be assigned to/);
+ toMatchError(/Syntax Error: Token '=' implies assignment but \[a-2\] can not be assigned to/);
});
});