From 3d534928b597dc15a3bd364095678bb784de98d6 Mon Sep 17 00:00:00 2001 From: vsavkin Date: Tue, 16 Dec 2014 10:10:32 -0800 Subject: [PATCH] refactor(parser): align expression language with host language Remove "enhancements" to the language from the parser, so the expression language mimics the host language. --- modules/change_detection/src/parser/ast.js | 31 ++++--------------- modules/change_detection/src/record_range.js | 9 +++--- .../test/change_detector_spec.js | 4 +-- .../test/parser/parser_spec.js | 29 +++-------------- modules/facade/src/lang.dart | 15 --------- modules/facade/src/lang.es6 | 4 --- 6 files changed, 17 insertions(+), 75 deletions(-) diff --git a/modules/change_detection/src/parser/ast.js b/modules/change_detection/src/parser/ast.js index e38011b3eb..042630242c 100644 --- a/modules/change_detection/src/parser/ast.js +++ b/modules/change_detection/src/parser/ast.js @@ -1,5 +1,5 @@ import {FIELD, autoConvertAdd, isBlank, isPresent, FunctionWrapper, BaseException} from "facade/lang"; -import {List, Map, ListWrapper, MapWrapper} from "facade/collection"; +import {List, Map, ListWrapper, StringMapWrapper} from "facade/collection"; import {ContextWithVariableBindings} from "./context_with_variable_bindings"; export class AST { @@ -162,14 +162,7 @@ export class KeyedAccess extends AST { eval(context) { var obj = this.obj.eval(context); var key = this.key.eval(context); - - if (obj instanceof Map) { - return MapWrapper.get(obj, key); - } else if (obj instanceof List) { - return ListWrapper.get(obj, key); - } else { - return obj[key]; - } + return obj[key]; } get isAssignable() { @@ -179,14 +172,7 @@ export class KeyedAccess extends AST { assign(context, value) { var obj = this.obj.eval(context); var key = this.key.eval(context); - - if (obj instanceof Map) { - MapWrapper.set(obj, key, value); - } else if (obj instanceof List) { - ListWrapper.set(obj, key, value); - } else { - obj[key] = value; - } + obj[key] = value; return value; } @@ -251,9 +237,9 @@ export class LiteralMap extends AST { } eval(context) { - var res = MapWrapper.create(); + var res = StringMapWrapper.create(); for(var i = 0; i < this.keys.length; ++i) { - MapWrapper.set(res, this.keys[i], this.values[i].eval(context)); + StringMapWrapper.set(res, this.keys[i], this.values[i].eval(context)); } return res; } @@ -281,13 +267,8 @@ export class Binary extends AST { } var right = this.right.eval(context); - // Null check for the operations. - if (isBlank(left)|| isBlank(right)) { - throw new BaseException("One of the operands is not defined"); - } - switch (this.operation) { - case '+' : return autoConvertAdd(left, right); + case '+' : return left + right; case '-' : return left - right; case '*' : return left * right; case '/' : return left / right; diff --git a/modules/change_detection/src/record_range.js b/modules/change_detection/src/record_range.js index f35ef83f5b..d6b579b764 100644 --- a/modules/change_detection/src/record_range.js +++ b/modules/change_detection/src/record_range.js @@ -13,7 +13,7 @@ import { import {FIELD, IMPLEMENTS, isBlank, isPresent, int, toBool, autoConvertAdd, BaseException, NumberWrapper} from 'facade/lang'; -import {List, Map, ListWrapper, MapWrapper} from 'facade/collection'; +import {List, Map, ListWrapper, MapWrapper, StringMapWrapper} from 'facade/collection'; import {ContextWithVariableBindings} from './parser/context_with_variable_bindings'; import { AccessMember, @@ -524,9 +524,9 @@ function _arrayFn(length:int) { function _mapFn(keys:List, length:int) { function buildMap(values) { - var res = MapWrapper.create(); + var res = StringMapWrapper.create(); for(var i = 0; i < keys.length; ++i) { - MapWrapper.set(res, keys[i], values[i]); + StringMapWrapper.set(res, keys[i], values[i]); } return res; } @@ -554,6 +554,5 @@ function _mapGetter(key) { } function _keyedAccess(obj, args) { - var key = args[0]; - return obj instanceof Map ? MapWrapper.get(obj, key):obj[key]; + return obj[args[0]]; } diff --git a/modules/change_detection/test/change_detector_spec.js b/modules/change_detection/test/change_detector_spec.js index d063e1581a..882292723d 100644 --- a/modules/change_detection/test/change_detector_spec.js +++ b/modules/change_detection/test/change_detector_spec.js @@ -118,11 +118,11 @@ export function main() { it("should support literal maps", () => { var c = createChangeDetector('map', '{z:1}'); c["changeDetector"].detectChanges(); - expect(MapWrapper.get(c["dispatcher"].loggedValues[0][0], 'z')).toEqual(1); + expect(c["dispatcher"].loggedValues[0][0]['z']).toEqual(1); c = createChangeDetector('map', '{z:a}', new TestData(1)); c["changeDetector"].detectChanges(); - expect(MapWrapper.get(c["dispatcher"].loggedValues[0][0], 'z')).toEqual(1); + expect(c["dispatcher"].loggedValues[0][0]['z']).toEqual(1); }); it("should support binary operations", () => { diff --git a/modules/change_detection/test/parser/parser_spec.js b/modules/change_detection/test/parser/parser_spec.js index d0f907249e..0c32e5075b 100644 --- a/modules/change_detection/test/parser/parser_spec.js +++ b/modules/change_detection/test/parser/parser_spec.js @@ -134,25 +134,6 @@ export function main() { expectEval("(1+2)*3").toEqual((1+2)*3); }); - it('should auto convert ints to strings', () => { - expectEval("'str ' + 4").toEqual("str 4"); - expectEval("4 + ' str'").toEqual("4 str"); - expectEval("4 + 4").toEqual(8); - expectEval("4 + 4 + ' str'").toEqual("8 str"); - expectEval("'str ' + 4 + 4").toEqual("str 44"); - }); - - it('should throw when one of the operands is null', () => { - expectEvalError("null < 0").toThrowError(); - expectEvalError("null * 3").toThrowError(); - expectEvalError("null + 6").toThrowError(); - expectEvalError("5 + null").toThrowError(); - expectEvalError("null - 4").toThrowError(); - expectEvalError("3 - null").toThrowError(); - expectEvalError("null + null").toThrowError(); - expectEvalError("null - null").toThrowError(); - }); - it('should parse an empty string', () => { expectEval('').toBeNull(); }); @@ -168,7 +149,7 @@ export function main() { }); it('should evaluate map', () => { - expectEval("{}").toEqual(MapWrapper.create()); + expectEval("{}").toEqual({}); expectEval("{a:'b'}['a']").toEqual('b'); expectEval("{'a':'b'}['a']").toEqual('b'); expectEval("{\"a\":'b'}['a']").toEqual('b'); @@ -285,15 +266,15 @@ export function main() { }); it("should support map updates", () => { - var context = td(MapWrapper.createFromPairs([["key", 100]])); + var context = td({"key" : 100}); expectEval('a["key"] = 200', context).toEqual(200); - expect(MapWrapper.get(context.a, "key")).toEqual(200); + expect(context.a["key"]).toEqual(200); }); it("should support array/map updates", () => { - var context = td([MapWrapper.createFromPairs([["key", 100]])]); + var context = td([{"key" : 100}]); expectEval('a[0]["key"] = 200', context).toEqual(200); - expect(MapWrapper.get(context.a[0], "key")).toEqual(200); + expect(context.a[0]["key"]).toEqual(200); }); it('should allow assignment after array dereference', () => { diff --git a/modules/facade/src/lang.dart b/modules/facade/src/lang.dart index bc9e857cd7..0cbcaba349 100644 --- a/modules/facade/src/lang.dart +++ b/modules/facade/src/lang.dart @@ -33,21 +33,6 @@ bool toBool(x) { return false; } -autoConvertAdd(a, b) { - if (a != null && b != null) { - if (a is String && b is! String) { - return a + b.toString(); - } - if (a is! String && b is String) { - return a.toString() + b; - } - return a + b; - } - if (a != null) return a; - if (b != null) return b; - return 0; -} - String stringify(obj) => obj.toString(); class StringWrapper { diff --git a/modules/facade/src/lang.es6 b/modules/facade/src/lang.es6 index 70606e88cd..30fb0d4e57 100644 --- a/modules/facade/src/lang.es6 +++ b/modules/facade/src/lang.es6 @@ -30,10 +30,6 @@ export function toBool(obj) { return !!obj; } -export function autoConvertAdd(a, b) { - return a + b; -} - export function stringify(token):string { if (typeof token === 'string') { return token;