From 1d03c2af5dadb4fdbba40f997dea8355989de40b Mon Sep 17 00:00:00 2001 From: vsavkin Date: Tue, 16 Dec 2014 16:45:08 -0800 Subject: [PATCH] feat(change_detector): add a way to inspect records and record ranges --- modules/change_detection/src/parser/ast.js | 4 +- modules/change_detection/src/parser/parser.js | 2 +- modules/change_detection/src/record.js | 76 +++++++++++++++++++ modules/change_detection/src/record_range.js | 28 +++++-- .../test/record_range_spec.js | 24 +++++- 5 files changed, 123 insertions(+), 11 deletions(-) diff --git a/modules/change_detection/src/parser/ast.js b/modules/change_detection/src/parser/ast.js index 11ff062ca0..e38011b3eb 100644 --- a/modules/change_detection/src/parser/ast.js +++ b/modules/change_detection/src/parser/ast.js @@ -345,10 +345,12 @@ export class MethodCall extends AST { receiver:AST; fn:Function; args:List; - constructor(receiver:AST, fn:Function, args:List) { + name:string; + constructor(receiver:AST, name:string, fn:Function, args:List) { this.receiver = receiver; this.fn = fn; this.args = args; + this.name = name; } eval(context) { diff --git a/modules/change_detection/src/parser/parser.js b/modules/change_detection/src/parser/parser.js index 3197cf7746..8795156911 100644 --- a/modules/change_detection/src/parser/parser.js +++ b/modules/change_detection/src/parser/parser.js @@ -404,7 +404,7 @@ class _ParseAST { var args = this.parseCallArguments(); this.expectCharacter($RPAREN); var fn = this.reflector.method(id); - return new MethodCall(receiver, fn, args); + return new MethodCall(receiver, id, fn, args); } else { var getter = this.reflector.getter(id); diff --git a/modules/change_detection/src/record.js b/modules/change_detection/src/record.js index 94e1b55df1..0840dfbc0c 100644 --- a/modules/change_detection/src/record.js +++ b/modules/change_detection/src/record.js @@ -394,6 +394,82 @@ export class Record { } return record; } + + inspect() { + return _inspect(this); + } + + inspectRange() { + return this.recordRange.inspect(); + } +} + +function _inspect(record:Record) { + function mode() { + switch (record.getType()) { + case RECORD_TYPE_PROPERTY: + return "property"; + case RECORD_TYPE_INVOKE_METHOD: + return "invoke_method"; + case RECORD_TYPE_INVOKE_CLOSURE: + return "invoke_closure"; + case RECORD_TYPE_INVOKE_PURE_FUNCTION: + return "pure_function"; + case RECORD_TYPE_INVOKE_FORMATTER: + return "invoke_formatter"; + case RECORD_TYPE_CONST: + return "const"; + case RECORD_TYPE_KEY_VALUE: + return "key_value"; + case RECORD_TYPE_ARRAY: + return "array"; + case RECORD_TYPE_NULL: + return "null"; + case RECORD_TYPE_MARKER: + return "marker"; + default: + return "unexpected type!"; + } + } + + function disabled() { + return record.isDisabled() ? "disabled" : "enabled"; + } + + function description() { + var name = isPresent(record.protoRecord) ? record.protoRecord.name : ""; + var exp = isPresent(record.protoRecord) ? record.protoRecord.expressionAsString : ""; + var currValue = record.currentValue; + var context = record.context; + + return `${mode()}, ${name}, ${disabled()} ` + + ` Current: ${currValue}, Context: ${context} in [${exp}]`; + } + + if (isBlank(record)) return null; + if (!(record instanceof Record)) return record; + + return new _RecordInspect(description(), record); +} + +class _RecordInspect { + description:string; + record:Record; + + constructor(description:string,record:Record) { + this.description = description; + this.record = record; + } + + get next() { + return _inspect(this.record.next); + } + get nextEnabled() { + return _inspect(this.record.nextEnabled); + } + get dest() { + return _inspect(this.record.dest); + } } function isSame(a, b) { diff --git a/modules/change_detection/src/record_range.js b/modules/change_detection/src/record_range.js index 6448313bcb..4496c32b91 100644 --- a/modules/change_detection/src/record_range.js +++ b/modules/change_detection/src/record_range.js @@ -284,6 +284,18 @@ export class RecordRange { record.funcOrValue = proto.funcOrValue; record.updateContext(context); } + + inspect() { + return _inspect(this); + } +} + +function _inspect(recordRange:RecordRange) { + var res = []; + for(var r = recordRange.headRecord.next; r != recordRange.tailRecord; r = r.next){ + ListWrapper.push(res, r.inspect().description); + } + return res; } function _link(a:Record, b:Record) { @@ -336,14 +348,14 @@ class ProtoRecordCreator { visitBinary(ast:Binary, dest) { var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, - _operationToFunction(ast.operation), 2, null, dest); + _operationToFunction(ast.operation), 2, ast.operation, dest); ast.left.visit(this, new Destination(record, 0)); ast.right.visit(this, new Destination(record, 1)); this.add(record); } visitPrefixNot(ast:PrefixNot, dest) { - var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _operation_negate, 1, null, dest); + var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _operation_negate, 1, "-", dest); ast.expression.visit(this, new Destination(record, 0)); this.add(record); } @@ -359,7 +371,7 @@ class ProtoRecordCreator { } visitFormatter(ast:Formatter, dest) { - var record = this.construct(RECORD_TYPE_INVOKE_FORMATTER, ast.name, ast.allArgs.length, null, dest); + var record = this.construct(RECORD_TYPE_INVOKE_FORMATTER, ast.name, ast.allArgs.length, ast.name, dest); for (var i = 0; i < ast.allArgs.length; ++i) { ast.allArgs[i].visit(this, new Destination(record, i)); } @@ -367,7 +379,7 @@ class ProtoRecordCreator { } visitMethodCall(ast:MethodCall, dest) { - var record = this.construct(RECORD_TYPE_INVOKE_METHOD, ast.fn, ast.args.length, null, dest); + var record = this.construct(RECORD_TYPE_INVOKE_METHOD, ast.fn, ast.args.length, ast.name, dest); for (var i = 0; i < ast.args.length; ++i) { ast.args[i].visit(this, new Destination(record, i)); } @@ -395,7 +407,7 @@ class ProtoRecordCreator { } visitConditional(ast:Conditional, dest) { - var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _cond, 3, null, dest); + var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _cond, 3, "?:", dest); ast.condition.visit(this, new Destination(record, 0)); ast.trueExp.visit(this, new Destination(record, 1)); ast.falseExp.visit(this, new Destination(record, 2)); @@ -403,7 +415,7 @@ class ProtoRecordCreator { } visitKeyedAccess(ast:KeyedAccess, dest) { - var record = this.construct(RECORD_TYPE_INVOKE_METHOD, _keyedAccess, 1, null, dest); + var record = this.construct(RECORD_TYPE_INVOKE_METHOD, _keyedAccess, 1, "[]", dest); ast.obj.visit(this, new Destination(record, null)); ast.key.visit(this, new Destination(record, 0)); this.add(record); @@ -411,7 +423,7 @@ class ProtoRecordCreator { visitLiteralArray(ast:LiteralArray, dest) { var length = ast.expressions.length; - var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _arrayFn(length), length, null, dest); + var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _arrayFn(length), length, "Array()", dest); for (var i = 0; i < length; ++i) { ast.expressions[i].visit(this, new Destination(record, i)); } @@ -420,7 +432,7 @@ class ProtoRecordCreator { visitLiteralMap(ast:LiteralMap, dest) { var length = ast.values.length; - var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _mapFn(ast.keys, length), length, null, dest); + var record = this.construct(RECORD_TYPE_INVOKE_PURE_FUNCTION, _mapFn(ast.keys, length), length, "Map()", dest); for (var i = 0; i < length; ++i) { ast.values[i].visit(this, new Destination(record, i)); } diff --git a/modules/change_detection/test/record_range_spec.js b/modules/change_detection/test/record_range_spec.js index ddb0cd7c6d..b0c977767b 100644 --- a/modules/change_detection/test/record_range_spec.js +++ b/modules/change_detection/test/record_range_spec.js @@ -9,7 +9,8 @@ import { ChangeDetector, ProtoRecordRange, RecordRange, - ProtoRecord + ProtoRecord, + RECORD_TYPE_CONST } from 'change_detection/change_detector'; import {Record} from 'change_detection/record'; @@ -337,5 +338,26 @@ export function main() { ]); }); }); + + describe("inspect", () => { + it("should return the description of the record", () => { + var proto = new ProtoRecord(null, RECORD_TYPE_CONST, 1, 0, "name", null, "group", "expression"); + var record = new Record(null, proto, null); + + var i = record.inspect(); + expect(i.description).toContain("const, name, enabled"); + }); + + it("should return the description of the records in the range", () => { + var proto = new ProtoRecord(null, RECORD_TYPE_CONST, 1, 0, "name", null, "group", "expression"); + var record = new Record(null, proto, null); + var range = new RecordRange(null, null); + range.addRecord(record); + + var i = range.inspect();; + expect(i.length).toEqual(1); + expect(i[0]).toContain("const, name, enabled"); + }); + }); }); }