Skip to content

Commit e927342

Browse files
author
Tim Blasi
committed
Read only a single DirectiveMetadata (will be squashed)
1 parent ae84eb7 commit e927342

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

modules/angular2/src/transform/template_compiler/directive_metadata_reader.dart

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import 'package:angular2/src/transform/common/logging.dart';
66
import 'package:angular2/src/transform/common/parser.dart';
77

88
/// Reads [DirectiveMetadata] from the `attributes` of `t`.
9-
List<DirectiveMetadata> readDirectiveMetadata(RegisteredType t) {
9+
DirectiveMetadata readDirectiveMetadata(RegisteredType t) {
1010
var visitor = new _DirectiveMetadataVisitor();
1111
t.annotations.accept(visitor);
12-
return visitor.directiveMetadata;
12+
return visitor.meta;
1313
}
1414

1515
num _getDirectiveType(String annotationName) {
@@ -30,21 +30,23 @@ num _getDirectiveType(String annotationName) {
3030
/// [RegisterType] object and pulling out [DirectiveMetadata].
3131
class _DirectiveMetadataVisitor extends Object
3232
with RecursiveAstVisitor<Object> {
33-
DirectiveMetadata current;
34-
final List<DirectiveMetadata> directiveMetadata = [];
33+
DirectiveMetadata meta;
3534

3635
@override
3736
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
3837
var directiveType = _getDirectiveType('${node.constructorName.type.name}');
3938
if (directiveType >= 0) {
40-
current = new DirectiveMetadata(
39+
if (meta != null) {
40+
logger.error('Only one Directive is allowed per class. '
41+
'Found "$node" but already processed "$meta".');
42+
}
43+
meta = new DirectiveMetadata(
4144
type: directiveType,
4245
compileChildren: false,
4346
properties: {},
4447
hostListeners: {},
4548
setters: [],
4649
readAttributes: []);
47-
directiveMetadata.add(current);
4850
super.visitInstanceCreationExpression(node);
4951
}
5052
// Annotation we do not recognize - no need to visit.
@@ -91,7 +93,7 @@ class _DirectiveMetadataVisitor extends Object
9193
}
9294

9395
void _populateSelector(Expression selectorValue) {
94-
current.selector = _expressionToString(selectorValue, 'Directive#selector');
96+
meta.selector = _expressionToString(selectorValue, 'Directive#selector');
9597
}
9698

9799
void _populateCompileChildren(Expression compileChildrenValue) {
@@ -102,7 +104,7 @@ class _DirectiveMetadataVisitor extends Object
102104
' Source: ${compileChildrenValue}');
103105
return;
104106
}
105-
current.compileChildren = (compileChildrenValue as BooleanLiteral).value;
107+
meta.compileChildren = (compileChildrenValue as BooleanLiteral).value;
106108
}
107109

108110
void _populateProperties(Expression propertiesValue) {
@@ -115,7 +117,7 @@ class _DirectiveMetadataVisitor extends Object
115117
for (MapLiteralEntry entry in (propertiesValue as MapLiteral).entries) {
116118
var sKey = _expressionToString(entry.key, 'Directive#properties keys');
117119
var sVal = _expressionToString(entry.value, 'Direcive#properties values');
118-
current.properties[sKey] = sVal;
120+
meta.properties[sKey] = sVal;
119121
}
120122
}
121123

@@ -130,7 +132,7 @@ class _DirectiveMetadataVisitor extends Object
130132
var sKey = _expressionToString(entry.key, 'Directive#hostListeners keys');
131133
var sVal =
132134
_expressionToString(entry.value, 'Directive#hostListeners values');
133-
current.hostListeners[sKey] = sVal;
135+
meta.hostListeners[sKey] = sVal;
134136
}
135137
}
136138
}

modules/angular2/test/transform/template_compiler/all_tests.dart

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:barback/barback.dart';
55
import 'package:angular2/src/dom/html_adapter.dart';
66
import 'package:angular2/src/render/api.dart';
77
import 'package:angular2/src/transform/common/asset_reader.dart';
8+
import 'package:angular2/src/transform/common/logging.dart';
89
import 'package:angular2/src/transform/common/parser.dart';
910
import 'package:angular2/src/transform/template_compiler/directive_metadata_reader.dart';
1011
import 'package:angular2/src/transform/template_compiler/generator.dart';
@@ -20,6 +21,8 @@ void allTests() {
2021
AssetReader reader = new TestAssetReader();
2122
var parser = new Parser(reader);
2223

24+
beforeEach(() => setLogger(new PrintLogger()));
25+
2326
it('should parse simple expressions in inline templates.', () async {
2427
var inputPath =
2528
'template_compiler/inline_expression_files/hello.ng_deps.dart';
@@ -54,31 +57,29 @@ void allTests() {
5457
});
5558

5659
describe('DirectiveMetadataReader', () {
57-
Future<DirectiveMetadata> readSingleMetadata(inputPath) async {
60+
Future<DirectiveMetadata> readMetadata(inputPath) async {
5861
var ngDeps = await parser.parse(new AssetId('a', inputPath));
59-
var metadata = readDirectiveMetadata(ngDeps.registeredTypes.first);
60-
expect(metadata.length).toEqual(1);
61-
return metadata.first;
62+
return readDirectiveMetadata(ngDeps.registeredTypes.first);
6263
}
6364

6465
it('should parse selectors', () async {
65-
var metadata = await readSingleMetadata(
66+
var metadata = await readMetadata(
6667
'template_compiler/directive_metadata_files/selector.ng_deps.dart');
6768
expect(metadata.selector).toEqual('hello-app');
6869
});
6970

7071
it('should parse compile children values', () async {
71-
var metadata = await readSingleMetadata('template_compiler/'
72+
var metadata = await readMetadata('template_compiler/'
7273
'directive_metadata_files/compile_children.ng_deps.dart');
7374
expect(metadata.compileChildren).toBeTrue();
7475

75-
metadata = await readSingleMetadata(
76+
metadata = await readMetadata(
7677
'template_compiler/directive_metadata_files/selector.ng_deps.dart');
7778
expect(metadata.compileChildren).toBeFalse();
7879
});
7980

8081
it('should parse properties.', () async {
81-
var metadata = await readSingleMetadata('template_compiler/'
82+
var metadata = await readMetadata('template_compiler/'
8283
'directive_metadata_files/properties.ng_deps.dart');
8384
expect(metadata.properties).toBeNotNull();
8485
expect(metadata.properties.length).toBe(2);
@@ -89,7 +90,7 @@ void allTests() {
8990
});
9091

9192
it('should parse host listeners.', () async {
92-
var metadata = await readSingleMetadata('template_compiler/'
93+
var metadata = await readMetadata('template_compiler/'
9394
'directive_metadata_files/host_listeners.ng_deps.dart');
9495
expect(metadata.hostListeners).toBeNotNull();
9596
expect(metadata.hostListeners.length).toBe(2);
@@ -98,6 +99,14 @@ void allTests() {
9899
expect(metadata.hostListeners).toContain('keyDown');
99100
expect(metadata.hostListeners['keyDown']).toEqual('onKeyDown(\$event)');
100101
});
102+
103+
it('should fail when a class is annotated with multiple Directives.',
104+
() async {
105+
var ngDeps = await parser.parse(new AssetId('a', 'template_compiler/'
106+
'directive_metadata_files/too_many_directives.ng_deps.dart'));
107+
expect(() => readDirectiveMetadata(ngDeps.registeredTypes.first))
108+
.toThrowWith(anInstanceOf: PrintLoggerError);
109+
});
101110
});
102111
}
103112

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
library examples.hello_world.index_common_dart.ng_deps.dart;
2+
3+
import 'hello.dart';
4+
import 'package:angular2/angular2.dart'
5+
show bootstrap, Component, Decorator, View, NgElement;
6+
7+
bool _visited = false;
8+
void initReflector(reflector) {
9+
if (_visited) return;
10+
_visited = true;
11+
reflector
12+
..registerType(HelloCmp, {
13+
'factory': () => new HelloCmp(),
14+
'parameters': const [const []],
15+
'annotations': const [
16+
const Component(selector: 'hello-app'),
17+
const Component(selector: 'goodbye-app')
18+
]
19+
});
20+
}

0 commit comments

Comments
 (0)