X Tutup
Skip to content

Commit efddc90

Browse files
author
Tim Blasi
committed
fix(dart/transform): Parse directives agnostic of annotation order
Now that we can specify `directives` in either `@View` or `@Component`, we will try to parse from both. Previously, we would trash any `directives` parsed in the first annotation upon encountering the second annotation. This ensures that we maintain that list of `directives` regardless of annotation ordering.
1 parent f515938 commit efddc90

File tree

6 files changed

+139
-9
lines changed

6 files changed

+139
-9
lines changed

modules_dart/transform/lib/src/transform/template_compiler/compile_data_creator.dart

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ class _CompileDataCreator {
172172
return retVal;
173173
}
174174
}
175+
175176
/// Visitor responsible for processing the `annotations` property of a
176177
/// [RegisterType] object, extracting the `directives` dependencies, and adding
177178
/// their associated [CompileDirectiveMetadata] to the `directives` of a
@@ -198,8 +199,14 @@ class _DirectiveDependenciesVisitor extends Object
198199
@override
199200
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
200201
if (_isViewAnnotation(node) || _isComponentAnnotation(node)) {
201-
compileData = new NormalizedComponentWithViewDirectives(
202-
null, <CompileDirectiveMetadata>[]);
202+
if (compileData == null) {
203+
compileData = new NormalizedComponentWithViewDirectives(
204+
null, <CompileDirectiveMetadata>[]);
205+
} else {
206+
// This is set above, after the visitor is finished. If this value is
207+
// non-null it indicates that we forgot to call `reset()`.
208+
assert(compileData.component == null);
209+
}
203210
node.visitChildren(this);
204211
}
205212
return null;
@@ -212,7 +219,7 @@ class _DirectiveDependenciesVisitor extends Object
212219
if (node.name is! Label || node.name.label is! SimpleIdentifier) {
213220
logger.error(
214221
'Angular 2 currently only supports simple identifiers in directives.'
215-
' Source: ${node}');
222+
' Source: ${node}');
216223
return null;
217224
}
218225
if ('${node.name.label}' == 'directives') {
@@ -244,7 +251,7 @@ class _DirectiveDependenciesVisitor extends Object
244251
} else {
245252
logger.error(
246253
'Angular 2 currently only supports simple and prefixed identifiers '
247-
'as values for "directives". Source: $node');
254+
'as values for "directives". Source: $node');
248255
return;
249256
}
250257
if (ngMeta.types.containsKey(name)) {

modules_dart/transform/test/transform/template_compiler/all_tests.dart

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,23 @@ void changeDetectorTests() {
6161
'template_compiler/directive_aliases_files/hello2.ng_deps.dart';
6262
// Except for the directive argument in the View annotation, the generated
6363
// change detectors are identical.
64+
var output1 = (await process(new AssetId('a', input1Path))).templatesCode;
65+
var output2 = (await process(new AssetId('a', input2Path))).templatesCode;
66+
_formatThenExpectEquals(output1, output2);
67+
});
68+
69+
it('should handle `directives` regardless of annotation ordering', () async {
70+
// Input 2 is the same as input1, but has the @View annotation listed first.
71+
var input1Path = 'template_compiler/annotation_ordering_files/'
72+
'component_first.ng_deps.dart';
73+
var input2Path = 'template_compiler/annotation_ordering_files/'
74+
'view_first.ng_deps.dart';
75+
// Except for the type name, the generated change detectors are identical.
6476
var output1 = (await process(new AssetId('a', input1Path)))
65-
.ngDepsCode
66-
.replaceFirst(
67-
'directives: const [alias1]', 'directives: const [GoodbyeCmp]')
68-
.replaceFirst('hello1', 'hello2');
69-
var output2 = (await process(new AssetId('a', input2Path))).ngDepsCode;
77+
.templatesCode
78+
.replaceAll('ComponentFirst', 'ViewFirst')
79+
.replaceAll('component_first', 'view_first');
80+
var output2 = (await process(new AssetId('a', input2Path))).templatesCode;
7081
_formatThenExpectEquals(output1, output2);
7182
});
7283
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library test.src.transform.template_compiler.annotation_ordering_files.component_first.ng_deps.dart;
2+
3+
import 'component_first.dart';
4+
import 'package:angular2/angular2.dart'
5+
show Component, Directive, View, NgElement;
6+
import 'package:angular2/src/directives/ng_for.dart';
7+
export 'component_first.dart';
8+
9+
var _visited = false;
10+
void initReflector(reflector) {
11+
if (_visited) return;
12+
_visited = true;
13+
reflector
14+
..registerType(
15+
ComponentFirst,
16+
new ReflectionInfo(const [
17+
const Component(selector: 'hello-app'),
18+
const View(
19+
template: '<li *ng-for="#thing of things"><div>test</div></li>',
20+
directives: const [NgFor])
21+
], const [
22+
const []
23+
], () => new ComponentFirst()));
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"ComponentFirst":
3+
{
4+
"kind": "type",
5+
"value": {
6+
"isComponent": true,
7+
"dynamicLoadable": true,
8+
"selector":"hello-app",
9+
"exportAs": null,
10+
"type": {
11+
"id": 1,
12+
"name": "ComponentFirst",
13+
"moduleUrl": "asset:angular2/test/transform/template_compiler/ng_for_files/hello.dart"
14+
},
15+
"changeDetection": 5,
16+
"inputs": {},
17+
"outputs": {},
18+
"hostListeners": {},
19+
"hostProperties": {},
20+
"hostAttributes": {},
21+
"lifecycleHooks": [],
22+
"template": {
23+
"encapsulation": 0,
24+
"template": "<li *ng-for=\"#thing of things\"><div>test</div></li>",
25+
"templateUrl": null,
26+
"styles": null,
27+
"styleUrls": null,
28+
"ngContentSelectors": null
29+
}
30+
}
31+
}
32+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library test.src.transform.template_compiler.annotation_ordering_files.view_first.ng_deps.dart;
2+
3+
import 'view_first.dart';
4+
import 'package:angular2/angular2.dart'
5+
show Component, Directive, View, NgElement;
6+
import 'package:angular2/src/directives/ng_for.dart';
7+
export 'view_first.dart';
8+
9+
var _visited = false;
10+
void initReflector(reflector) {
11+
if (_visited) return;
12+
_visited = true;
13+
reflector
14+
..registerType(
15+
ViewFirst,
16+
new ReflectionInfo(const [
17+
const View(
18+
template: '<li *ng-for="#thing of things"><div>test</div></li>',
19+
directives: const [NgFor]),
20+
const Component(selector: 'hello-app')
21+
], const [
22+
const []
23+
], () => new ViewFirst()));
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"ViewFirst":
3+
{
4+
"kind": "type",
5+
"value": {
6+
"isComponent": true,
7+
"dynamicLoadable": true,
8+
"selector":"hello-app",
9+
"exportAs": null,
10+
"type": {
11+
"id": 1,
12+
"name": "ViewFirst",
13+
"moduleUrl": "asset:angular2/test/transform/template_compiler/ng_for_files/hello.dart"
14+
},
15+
"changeDetection": 5,
16+
"inputs": {},
17+
"outputs": {},
18+
"hostListeners": {},
19+
"hostProperties": {},
20+
"hostAttributes": {},
21+
"lifecycleHooks": [],
22+
"template": {
23+
"encapsulation": 0,
24+
"template": "<li *ng-for=\"#thing of things\"><div>test</div></li>",
25+
"templateUrl": null,
26+
"styles": null,
27+
"styleUrls": null,
28+
"ngContentSelectors": null
29+
}
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)
X Tutup