From 311b47720b8046083c7abfb566149c378346acd5 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 1 Jul 2015 13:20:12 -0700 Subject: [PATCH] fix(transformer): Fix string interpolation for bindings. Previously it did not stringify properties and used `+` instead of ` `. --- .../transform/bind_generator/generator.dart | 1 - .../src/transform/bind_generator/visitor.dart | 4 +- .../src/transform/common/options.dart | 3 +- .../transform/reflection_remover/codegen.dart | 5 ++- .../reflection_remover/rewriter.dart | 4 +- .../change_detector_codegen.dart | 4 +- .../transform/bind_generator/all_tests.dart | 4 +- .../events_files/bar.ng_deps.dart | 2 +- .../directive_processor/all_tests.dart | 4 +- .../invalid_url_files/hello.dart | 7 +--- .../two_annotations_files/bar.dart | 4 +- .../expected/bar.ng_deps.dart | 42 ++++++++++++++++++- 12 files changed, 62 insertions(+), 22 deletions(-) diff --git a/modules/angular2/src/transform/bind_generator/generator.dart b/modules/angular2/src/transform/bind_generator/generator.dart index ebc134a2fa..602b5e7eac 100644 --- a/modules/angular2/src/transform/bind_generator/generator.dart +++ b/modules/angular2/src/transform/bind_generator/generator.dart @@ -111,4 +111,3 @@ Map _createEventsMap(NgDeps ngDeps) { }); return bindMap; } - diff --git a/modules/angular2/src/transform/bind_generator/visitor.dart b/modules/angular2/src/transform/bind_generator/visitor.dart index ce05d619a5..7145cbfa92 100644 --- a/modules/angular2/src/transform/bind_generator/visitor.dart +++ b/modules/angular2/src/transform/bind_generator/visitor.dart @@ -6,8 +6,8 @@ import 'package:angular2/src/transform/common/logging.dart'; /// Visitor responsible for crawling the "annotations" value in a /// `registerType` call and pulling out the properties of any "bind" /// values found. -class ExtractNamedExpressionVisitor extends Object with - RecursiveAstVisitor { +class ExtractNamedExpressionVisitor extends Object + with RecursiveAstVisitor { final ConstantEvaluator _evaluator = new ConstantEvaluator(); final List bindConfig = []; final String nameToExtract; diff --git a/modules/angular2/src/transform/common/options.dart b/modules/angular2/src/transform/common/options.dart index 5dacca27d3..55447f8cda 100644 --- a/modules/angular2/src/transform/common/options.dart +++ b/modules/angular2/src/transform/common/options.dart @@ -61,8 +61,7 @@ class TransformerOptions { MirrorMode mirrorMode: MirrorMode.none, bool initReflector: true, List customAnnotationDescriptors: const [], int optimizationPhases: DEFAULT_OPTIMIZATION_PHASES, - bool inlineViews: true, - bool generateChangeDetectors: true}) { + bool inlineViews: true, bool generateChangeDetectors: true}) { if (reflectionEntryPoints == null || reflectionEntryPoints.isEmpty) { reflectionEntryPoints = entryPoints; } diff --git a/modules/angular2/src/transform/reflection_remover/codegen.dart b/modules/angular2/src/transform/reflection_remover/codegen.dart index 00d53060e5..cba64a63f2 100644 --- a/modules/angular2/src/transform/reflection_remover/codegen.dart +++ b/modules/angular2/src/transform/reflection_remover/codegen.dart @@ -16,8 +16,9 @@ class Codegen { Codegen(String reflectionEntryPointPath, Iterable newEntryPointPaths, {String prefix}) : this.prefix = prefix == null ? _PREFIX_BASE : prefix, - importUris = newEntryPointPaths.map((p) => - path.relative(p, from: path.dirname(reflectionEntryPointPath)).replaceAll('\\', '/')) { + importUris = newEntryPointPaths.map((p) => path + .relative(p, from: path.dirname(reflectionEntryPointPath)) + .replaceAll('\\', '/')) { if (this.prefix.isEmpty) throw new ArgumentError.value('(empty)', 'prefix'); } diff --git a/modules/angular2/src/transform/reflection_remover/rewriter.dart b/modules/angular2/src/transform/reflection_remover/rewriter.dart index 0d7607e3eb..60d3ed8697 100644 --- a/modules/angular2/src/transform/reflection_remover/rewriter.dart +++ b/modules/angular2/src/transform/reflection_remover/rewriter.dart @@ -113,7 +113,9 @@ class Rewriter { String _importDebugReflectionCapabilities(ImportDirective node) { var uri = '${node.uri}'; - uri = path.join(path.dirname(uri), 'debug_${path.basename(uri)}').replaceAll('\\', '/'); + uri = path + .join(path.dirname(uri), 'debug_${path.basename(uri)}') + .replaceAll('\\', '/'); var asClause = node.prefix != null ? ' as ${node.prefix}' : ''; return 'import $uri$asClause;'; } diff --git a/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart b/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart index bca0194b55..cefcdb4237 100644 --- a/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart +++ b/modules/angular2/src/transform/template_compiler/change_detector_codegen.dart @@ -424,7 +424,9 @@ class _CodegenState { String _genInterpolation(ProtoRecord r) { var res = new StringBuffer(); for (var i = 0; i < r.args.length; ++i) { - res.write('${JSON.encode(r.fixedArgs[i])} + ${_localNames[r.args[i]]} +'); + var name = _localNames[r.args[i]]; + res.write( + '${JSON.encode(r.fixedArgs[i])} "\$\{$name == null ? "" : $name\}" '); } res.write(JSON.encode(r.fixedArgs[r.args.length])); return '$res'; diff --git a/modules/angular2/test/transform/bind_generator/all_tests.dart b/modules/angular2/test/transform/bind_generator/all_tests.dart index 119ab858cd..fd3b8351ec 100644 --- a/modules/angular2/test/transform/bind_generator/all_tests.dart +++ b/modules/angular2/test/transform/bind_generator/all_tests.dart @@ -41,10 +41,10 @@ void allTests() { () async { var inputPath = 'bind_generator/events_files/bar.ng_deps.dart'; var expected = formatter.format( - readFile('bind_generator/events_files/expected/bar.ng_deps.dart')); + readFile('bind_generator/events_files/expected/bar.ng_deps.dart')); var output = formatter.format( - await createNgSettersAndGetters(reader, new AssetId('a', inputPath))); + await createNgSettersAndGetters(reader, new AssetId('a', inputPath))); expect(output).toEqual(expected); }); } diff --git a/modules/angular2/test/transform/bind_generator/events_files/bar.ng_deps.dart b/modules/angular2/test/transform/bind_generator/events_files/bar.ng_deps.dart index 53018d38a2..4fee5dcb61 100644 --- a/modules/angular2/test/transform/bind_generator/events_files/bar.ng_deps.dart +++ b/modules/angular2/test/transform/bind_generator/events_files/bar.ng_deps.dart @@ -13,7 +13,7 @@ void initReflector(reflector) { 'parameters': const [], 'annotations': const [ const Directive( - selector: '[tool-tip]', events: ['onOpen', 'close: onClose']) + selector: '[tool-tip]', events: ['onOpen', 'close: onClose']) ] }); } diff --git a/modules/angular2/test/transform/directive_processor/all_tests.dart b/modules/angular2/test/transform/directive_processor/all_tests.dart index 953c9fdd02..5dce1bad0f 100644 --- a/modules/angular2/test/transform/directive_processor/all_tests.dart +++ b/modules/angular2/test/transform/directive_processor/all_tests.dart @@ -121,8 +121,8 @@ void _testNgDeps(String name, String inputPath, if (output == null) { expect(await reader.hasInput(expectedId)).toBeFalse(); } else { - expect(formatter.format(output)) - .toEqual((await reader.readAsString(expectedId)).replaceAll('\r\n', '\n')); + expect(formatter.format(output)).toEqual( + (await reader.readAsString(expectedId)).replaceAll('\r\n', '\n')); } if (expectedLogs != null) { diff --git a/modules/angular2/test/transform/directive_processor/invalid_url_files/hello.dart b/modules/angular2/test/transform/directive_processor/invalid_url_files/hello.dart index 3a0b965ef3..796f2d9738 100644 --- a/modules/angular2/test/transform/directive_processor/invalid_url_files/hello.dart +++ b/modules/angular2/test/transform/directive_processor/invalid_url_files/hello.dart @@ -1,13 +1,10 @@ library test.transform.directive_processor.url_expression_files.hello; import 'package:angular2/angular2.dart' -show bootstrap, Component, Directive, View, NgElement; + show bootstrap, Component, Directive, View, NgElement; @Component(selector: 'hello-app') @View( templateUrl: '/bad/absolute/url.html', - styleUrls: const [ - 'package:invalid/package.css', - 'bad_relative_url.css' - ]) + styleUrls: const ['package:invalid/package.css', 'bad_relative_url.css']) class HelloCmp {} diff --git a/modules/angular2/test/transform/integration/two_annotations_files/bar.dart b/modules/angular2/test/transform/integration/two_annotations_files/bar.dart index 0b15af6758..85ae2eec85 100644 --- a/modules/angular2/test/transform/integration/two_annotations_files/bar.dart +++ b/modules/angular2/test/transform/integration/two_annotations_files/bar.dart @@ -4,7 +4,9 @@ import 'package:angular2/src/core/annotations_impl/annotations.dart'; import 'package:angular2/src/core/annotations_impl/view.dart'; @Component(selector: '[soup]') -@View(template: 'Salad') +@View(template: 'Salad: {{myNum}} is awesome') class MyComponent { + int myNum; + MyComponent(); } diff --git a/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart b/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart index 6682e577f3..ea430ff3bf 100644 --- a/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart +++ b/modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart @@ -17,9 +17,11 @@ void initReflector(reflector) { 'parameters': const [], 'annotations': const [ const Component(selector: '[soup]'), - const View(template: 'Salad') + const View(template: 'Salad: {{myNum}} is awesome') ] - }); + }) + ..registerGetters({'myNum': (o) => o.myNum}) + ..registerSetters({'myNum': (o, v) => o.myNum = v}); _gen.preGeneratedProtoDetectors['MyComponent_comp_0'] = _MyComponent_ChangeDetector0.newProtoChangeDetector; } @@ -31,6 +33,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector { dynamic _locals = null; dynamic _alreadyChecked = false; MyComponent _context = null; + dynamic _myNum0 = _gen.ChangeDetectionUtil.uninitialized(); + dynamic _interpolate1 = _gen.ChangeDetectionUtil.uninitialized(); _MyComponent_ChangeDetector0(this._dispatcher, this._pipeRegistry, this._protos, this._directiveRecords) @@ -41,12 +45,44 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector { _gen.ChangeDetectionUtil.throwDehydrated(); } var context = null; + var myNum0 = null; + var interpolate1 = null; var change_context = false; + var change_myNum0 = false; + var change_interpolate1 = false; var isChanged = false; var currentProto; var changes = null; context = _context; + currentProto = _protos[0]; + myNum0 = context.myNum; + if (!_gen.looseIdentical(myNum0, _myNum0)) { + change_myNum0 = true; + + _myNum0 = myNum0; + } + if (change_myNum0) { + currentProto = _protos[1]; + interpolate1 = "Salad: " "${myNum0 == null ? "" : myNum0}" " is awesome"; + if (!_gen.looseIdentical(interpolate1, _interpolate1)) { + change_interpolate1 = true; + if (throwOnChange) { + _gen.ChangeDetectionUtil.throwOnChange(currentProto, + _gen.ChangeDetectionUtil.simpleChange( + _interpolate1, interpolate1)); + } + + _dispatcher.notifyOnBinding(currentProto.bindingRecord, interpolate1); + + _interpolate1 = interpolate1; + } + } else { + interpolate1 = _interpolate1; + } + changes = null; + + isChanged = false; _alreadyChecked = true; } @@ -65,6 +101,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector { void dehydrate() { _context = null; + _myNum0 = _gen.ChangeDetectionUtil.uninitialized(); + _interpolate1 = _gen.ChangeDetectionUtil.uninitialized(); _locals = null; }