Skip to content

Commit 39b6e0e

Browse files
committed
feat(transformers): collect information for CompileDiDependencyMetadata
1 parent f60fa14 commit 39b6e0e

File tree

7 files changed

+146
-12
lines changed

7 files changed

+146
-12
lines changed

modules/angular2/src/compiler/directive_metadata.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,29 @@ export class CompileDiDependencyMetadata {
120120
}
121121

122122
static fromJson(data: {[key: string]: any}): CompileDiDependencyMetadata {
123-
return new CompileDiDependencyMetadata(
124-
{token: objFromJson(data['token'], CompileIdentifierMetadata.fromJson)});
123+
return new CompileDiDependencyMetadata({
124+
token: objFromJson(data['token'], CompileIdentifierMetadata.fromJson),
125+
query: objFromJson(data['query'], CompileQueryMetadata.fromJson),
126+
viewQuery: objFromJson(data['viewQuery'], CompileQueryMetadata.fromJson),
127+
isAttribute: data['isAttribute'],
128+
isSelf: data['isSelf'],
129+
isHost: data['isHost'],
130+
isSkipSelf: data['isSkipSelf'],
131+
isOptional: data['isOptional']
132+
});
125133
}
126134

127135
toJson(): {[key: string]: any} {
128136
return {
129137
// Note: Runtime type can't be serialized...
130-
'token': objToJson(this.token)
138+
'token': objToJson(this.token),
139+
'query': objToJson(this.query),
140+
'viewQuery': objToJson(this.viewQuery),
141+
'isAttribute': this.isAttribute,
142+
'isSelf': this.isSelf,
143+
'isHost': this.isHost,
144+
'isSkipSelf': this.isSkipSelf,
145+
'isOptional': this.isOptional
131146
};
132147
}
133148
}
@@ -274,9 +289,28 @@ export class CompileQueryMetadata {
274289
} = {}) {
275290
this.selectors = selectors;
276291
this.descendants = descendants;
277-
this.first = first;
292+
this.first = normalizeBool(first);
278293
this.propertyName = propertyName;
279294
}
295+
296+
static fromJson(data: {[key: string]: any}): CompileQueryMetadata {
297+
return new CompileQueryMetadata({
298+
selectors: arrayFromJson(data['selectors'], CompileIdentifierMetadata.fromJson),
299+
descendants: data['descendants'],
300+
first: data['first'],
301+
propertyName: data['propertyName']
302+
});
303+
}
304+
305+
toJson(): {[key: string]: any} {
306+
return {
307+
// Note: Runtime type can't be serialized...
308+
'selectors': arrayToJson(this.selectors),
309+
'descendants': this.descendants,
310+
'first': this.first,
311+
'propertyName': this.propertyName
312+
};
313+
}
280314
}
281315

282316
/**
@@ -581,11 +615,11 @@ var _COMPILE_METADATA_FROM_JSON = {
581615
};
582616

583617
function arrayFromJson(obj: any[], fn: (a: {[key: string]: any}) => any): any {
584-
return isBlank(obj) ? null : obj.map(fn);
618+
return isBlank(obj) ? null : obj.map(o => objFromJson(o, fn));
585619
}
586620

587621
function arrayToJson(obj: any[]): string | {[key: string]: any} {
588-
return isBlank(obj) ? null : obj.map(o => o.toJson());
622+
return isBlank(obj) ? null : obj.map(objToJson);
589623
}
590624

591625
function objFromJson(obj: any, fn: (a: {[key: string]: any}) => any): any {

modules/angular2/test/compiler/directive_metadata_spec.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import {
1616
CompileDirectiveMetadata,
1717
CompileTypeMetadata,
1818
CompileTemplateMetadata,
19-
CompileProviderMetadata
19+
CompileProviderMetadata,
20+
CompileDiDependencyMetadata,
21+
CompileQueryMetadata
2022
} from 'angular2/src/compiler/directive_metadata';
2123
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
2224
import {ChangeDetectionStrategy} from 'angular2/src/core/change_detection';
@@ -29,8 +31,25 @@ export function main() {
2931
var fullDirectiveMeta: CompileDirectiveMetadata;
3032

3133
beforeEach(() => {
32-
fullTypeMeta = new CompileTypeMetadata(
33-
{name: 'SomeType', moduleUrl: 'someUrl', isHost: true, diDeps: []});
34+
fullTypeMeta = new CompileTypeMetadata({
35+
name: 'SomeType',
36+
moduleUrl: 'someUrl',
37+
isHost: true,
38+
diDeps: [
39+
new CompileDiDependencyMetadata({
40+
isAttribute: true,
41+
isSelf: true,
42+
isHost: true,
43+
isSkipSelf: true,
44+
isOptional: true,
45+
token: 'someToken',
46+
query: new CompileQueryMetadata(
47+
{selectors: ['one'], descendants: true, first: true, propertyName: 'one'}),
48+
viewQuery: new CompileQueryMetadata(
49+
{selectors: ['one'], descendants: true, first: true, propertyName: 'one'})
50+
})
51+
]
52+
});
3453
fullTemplateMeta = new CompileTemplateMetadata({
3554
encapsulation: ViewEncapsulation.Emulated,
3655
template: '<a></a>',

modules_dart/transform/lib/src/transform/common/type_metadata_reader.dart

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,34 @@ class _CompileTypeMetadataVisitor extends Object
185185
final typeToken = p is SimpleFormalParameter && p.type != null ? _readIdentifier(p.type.name) : null;
186186
final injectTokens = p.metadata.where((m) => m.name.toString() == "Inject").map((m) => _readIdentifier(m.arguments.arguments[0]));
187187
final token = injectTokens.isNotEmpty ? injectTokens.first : typeToken;
188-
return new CompileDiDependencyMetadata(token: token);
188+
final query = _hasAnnotation(p, "Query") ? _createQueryMetadata(_getAnnotation(p, "Query")) : null;
189+
final viewQuery = _hasAnnotation(p, "ViewQuery") ? _createQueryMetadata(_getAnnotation(p, "ViewQuery")) : null;
190+
191+
return new CompileDiDependencyMetadata(
192+
token: token,
193+
isAttribute: _hasAnnotation(p, "Attribute"),
194+
isSelf: _hasAnnotation(p, "Self"),
195+
isHost: _hasAnnotation(p, "Host"),
196+
isSkipSelf: _hasAnnotation(p, "SkipSelf"),
197+
isOptional: _hasAnnotation(p, "Optional"),
198+
query: query,
199+
viewQuery: viewQuery);
189200
}).toList();
190201
}
202+
203+
_getAnnotation(p, String attrName) => p.metadata.where((m) => m.name.toString() == attrName).first;
204+
_hasAnnotation(p, String attrName) => p.metadata.where((m) => m.name.toString() == attrName).isNotEmpty;
205+
_createQueryMetadata(Annotation a) {
206+
final selector = _readIdentifier(a.arguments.arguments.first);
207+
var descendants = false;
208+
a.arguments.arguments.skip(0).forEach((arg) {
209+
if (arg is NamedExpression && arg.name.toString() == "descendants:")
210+
descendants = naiveEval(arg.expression);
211+
});
212+
213+
final selectors = selector is String ? selector.split(",") : [selector];
214+
return new CompileQueryMetadata(selectors: selectors, descendants: descendants);
215+
}
191216
}
192217

193218

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ class _CompileDataCreator {
174174
if (deps == null) return;
175175
for (var dep in deps) {
176176
dep.token = _resolveIdentifier(ngMetaMap, neededBy, dep.token);
177+
if (dep.query != null) {
178+
dep.query.selectors = dep.query.selectors.map((s) => _resolveIdentifier(ngMetaMap, neededBy, s)).toList();
179+
}
180+
if (dep.viewQuery != null) {
181+
dep.viewQuery.selectors = dep.viewQuery.selectors.map((s) => _resolveIdentifier(ngMetaMap, neededBy, s)).toList();
182+
}
177183
}
178184
}
179185

modules_dart/transform/test/transform/directive_processor/all_tests.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,17 @@ void allTests() {
597597
expect(cmp).toBeNotNull();
598598
var deps = cmp.type.diDeps;
599599
expect(deps).toBeNotNull();
600-
expect(deps.length).toEqual(2);
600+
expect(deps.length).toEqual(8);
601601
expect(deps[0].token.name).toEqual("ServiceDep");
602602
expect(deps[1].token.name).toEqual("ServiceDep");
603+
expect(deps[2].isAttribute).toEqual(true);
604+
expect(deps[3].isSelf).toEqual(true);
605+
expect(deps[4].isSkipSelf).toEqual(true);
606+
expect(deps[5].isOptional).toEqual(true);
607+
expect(deps[6].query.selectors[0].name).toEqual("ServiceDep");
608+
expect(deps[6].query.descendants).toEqual(true);
609+
expect(deps[7].viewQuery.selectors[0]).toEqual("one");
610+
expect(deps[7].viewQuery.selectors[1]).toEqual("two");
603611
});
604612

605613
it('should populate `diDependency` using a string token.',

modules_dart/transform/test/transform/directive_processor/directives_files/components.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,16 @@ class ComponentWithProvidersUseClass {}
115115
selector: 'component-with-di-deps',
116116
template: '')
117117
class ComponentWithDiDeps {
118-
ComponentWithDiDeps(ServiceDep arg1, @Inject(ServiceDep) arg2);
118+
ComponentWithDiDeps(
119+
ServiceDep arg1,
120+
@Inject(ServiceDep) arg2,
121+
@Attribute('one') arg3,
122+
@Self() ServiceDep arg4,
123+
@SkipSelf() ServiceDep arg5,
124+
@Optional() ServiceDep arg6,
125+
@Query(ServiceDep, descendants:true) arg6,
126+
@ViewQuery("one,two") arg7
127+
);
119128
}
120129

121130
@Component(

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,39 @@ void allTests() {
179179
expect(cmp.type.diDeps[0].token.moduleUrl).toEqual("moduleUrl");
180180
});
181181

182+
it('should resolve queries and viewQueries.', () async {
183+
barNgMeta.identifiers['Service'] = new CompileTypeMetadata(name: 'Service', moduleUrl: 'moduleUrl');
184+
185+
fooComponentMeta.template = new CompileTemplateMetadata(template: "import 'bar.dart';");
186+
fooComponentMeta.type.diDeps = [
187+
new CompileDiDependencyMetadata(
188+
token: 'someToken',
189+
query: new CompileQueryMetadata(selectors: [new CompileIdentifierMetadata(name: 'Service')])
190+
),
191+
new CompileDiDependencyMetadata(
192+
token: 'someToken',
193+
viewQuery: new CompileQueryMetadata(selectors: [new CompileIdentifierMetadata(name: 'Service')])
194+
)
195+
];
196+
197+
final viewAnnotation = new AnnotationModel()..name = 'View'..isView = true;
198+
final reflectable = fooNgMeta.ngDeps.reflectables.first;
199+
reflectable.annotations.add(viewAnnotation);
200+
fooNgMeta.ngDeps.imports.add(new ImportModel()..uri = 'package:a/bar.dart');
201+
202+
updateReader();
203+
204+
final viewDefResults = await createCompileData(reader, fooAssetId, [], []);
205+
final cmp = viewDefResults.viewDefinitions.values.first.component;
206+
207+
expect(cmp.type.diDeps.length).toEqual(2);
208+
209+
expect(cmp.type.diDeps[0].query.selectors[0].name).toEqual("Service");
210+
expect(cmp.type.diDeps[0].query.selectors[0].moduleUrl).toEqual("moduleUrl");
211+
expect(cmp.type.diDeps[1].viewQuery.selectors[0].name).toEqual("Service");
212+
expect(cmp.type.diDeps[1].viewQuery.selectors[0].moduleUrl).toEqual("moduleUrl");
213+
});
214+
182215
it('should generate providers from Provider objects (references).', () async {
183216
barNgMeta.identifiers['Service1'] = new CompileTypeMetadata(name: 'Service1', moduleUrl: 'moduleUrl');
184217
barNgMeta.identifiers['Service2'] = new CompileTypeMetadata(name: 'Service2', moduleUrl: 'moduleUrl');

0 commit comments

Comments
 (0)