X Tutup
Skip to content

Commit 589ce31

Browse files
committed
feat(transformers): record setters for query fields
Closes #4344
1 parent e7d65ad commit 589ce31

File tree

7 files changed

+172
-2
lines changed

7 files changed

+172
-2
lines changed

modules_dart/transform/lib/src/transform/bind_generator/generator.dart

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,70 @@ library angular2.transform.bind_generator.generator;
22

33
import 'dart:async';
44

5+
import 'package:analyzer/analyzer.dart';
56
import 'package:angular2/src/transform/common/asset_reader.dart';
67
import 'package:angular2/src/transform/common/ng_deps.dart';
78
import 'package:angular2/src/transform/common/property_utils.dart' as prop;
89
import 'package:barback/barback.dart';
910

1011
import 'visitor.dart';
1112

13+
class _ExtractQueryFieldsFromAnnotation extends Object
14+
with RecursiveAstVisitor<Object> {
15+
final ConstantEvaluator _evaluator = new ConstantEvaluator();
16+
final List<String> queryFields = [];
17+
18+
@override
19+
Object visitNamedExpression(NamedExpression node) {
20+
if ('${node.name.label}' == "queries") {
21+
if (node.expression is! MapLiteral) {
22+
throw new FormatException(
23+
'Expected a map value for "queries", but got ${node.expression}',
24+
node.toSource());
25+
}
26+
MapLiteral queries = node.expression;
27+
queryFields.addAll(queries.entries.map((e) => e.key.accept(_evaluator)));
28+
}
29+
return super.visitNamedExpression(node);
30+
}
31+
32+
Map asMap() {
33+
return new Map.fromIterable(queryFields, value: (_) => 'Object');
34+
}
35+
}
36+
37+
38+
class _ExtractQueryFieldsFromPropMetadata extends Object
39+
with RecursiveAstVisitor<Object> {
40+
final ConstantEvaluator _evaluator = new ConstantEvaluator();
41+
final List<String> queryFields = [];
42+
43+
@override
44+
Object visitMapLiteralEntry(MapLiteralEntry node) {
45+
if (_hasQueryAnnotation(node.value)) {
46+
queryFields.add(node.key.accept(_evaluator));
47+
}
48+
return super.visitMapLiteralEntry(node);
49+
}
50+
51+
bool _hasQueryAnnotation(list) {
52+
var res = false;
53+
list.elements.forEach((item) {
54+
var n = item.constructorName.toString();
55+
if(n == "ContentChild" || n == "ViewChild" || n == "ContentChildren" || n == "ViewChildren") {
56+
res = true;
57+
}
58+
});
59+
60+
return res;
61+
}
62+
63+
asMap() {
64+
return new Map.fromIterable(queryFields, value: (_) => 'Object');
65+
}
66+
}
67+
68+
1269
Future<String> createNgSettersAndGetters(
1370
AssetReader reader, AssetId entryPoint) async {
1471
NgDeps ngDeps = await NgDeps.parse(reader, entryPoint);
@@ -17,6 +74,18 @@ Future<String> createNgSettersAndGetters(
1774
var setters = _generateSetters(_createPropertiesMap(ngDeps));
1875
var getters = _generateGetters(_createEventPropertiesList(ngDeps));
1976

77+
ngDeps.registeredTypes.forEach((t) {
78+
final fromAnnotation = new _ExtractQueryFieldsFromAnnotation();
79+
t.annotations.accept(fromAnnotation);
80+
81+
final fromPropMetadata = new _ExtractQueryFieldsFromPropMetadata();
82+
if (t.propMetadata != null) {
83+
t.propMetadata.accept(fromPropMetadata);
84+
}
85+
setters.addAll(_generateSetters(fromAnnotation.asMap()));
86+
setters.addAll(_generateSetters(fromPropMetadata.asMap()));
87+
});
88+
2089
if (setters.isEmpty && getters.isEmpty) return code;
2190
var out = new StringBuffer();
2291
var codeInjectIdx = ngDeps.registeredTypes.last.registerMethod.end;

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class RegisteredType {
2626
/// The annotations registered.
2727
final Expression annotations;
2828

29+
/// The property metadata registered.
30+
final Expression propMetadata;
31+
2932
RenderDirectiveMetadata _directiveMetadata = null;
3033

3134
RegisteredType._(
@@ -34,15 +37,16 @@ class RegisteredType {
3437
this.reflectionInfoCreate,
3538
this.factoryFn,
3639
this.parameters,
37-
this.annotations);
40+
this.annotations,
41+
this.propMetadata);
3842

3943
/// Creates a {@link RegisteredType} given a {@link MethodInvocation} node representing
4044
/// a call to `registerType`.
4145
factory RegisteredType.fromMethodInvocation(MethodInvocation registerMethod) {
4246
var visitor = new _ParseRegisterTypeVisitor();
4347
registerMethod.accept(visitor);
4448
return new RegisteredType._(visitor.typeName, registerMethod, visitor.info,
45-
visitor.factoryFn, visitor.parameters, visitor.annotations);
49+
visitor.factoryFn, visitor.parameters, visitor.annotations, visitor.propMetadata);
4650
}
4751

4852
RenderDirectiveMetadata get directiveMetadata {
@@ -68,6 +72,7 @@ class _ParseRegisterTypeVisitor extends Object
6872
Expression factoryFn;
6973
Expression parameters;
7074
Expression annotations;
75+
Expression propMetadata;
7176

7277
@override
7378
Object visitMethodInvocation(MethodInvocation node) {
@@ -90,6 +95,8 @@ class _ParseRegisterTypeVisitor extends Object
9095
parameters = arg;
9196
} else if (i == 2) {
9297
factoryFn = arg;
98+
} else if (i == 4) {
99+
propMetadata = arg;
93100
}
94101
}
95102

modules_dart/transform/test/transform/bind_generator/all_tests.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,26 @@ void allTests() {
4848
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
4949
expect(output).toEqual(expected);
5050
});
51+
52+
it('should generate setters for queries defined in the class annotation.',
53+
() async {
54+
var inputPath = 'bind_generator/queries_class_annotation_files/bar.ng_deps.dart';
55+
var expected = formatter.format(
56+
readFile('bind_generator/queries_class_annotation_files/expected/bar.ng_deps.dart'));
57+
58+
var output = formatter.format(
59+
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
60+
expect(output).toEqual(expected);
61+
});
62+
63+
it('should generate setters for queries defined via prop annotations.',
64+
() async {
65+
var inputPath = 'bind_generator/queries_prop_annotations_files/bar.ng_deps.dart';
66+
var expected = formatter.format(
67+
readFile('bind_generator/queries_prop_annotations_files/expected/bar.ng_deps.dart'));
68+
69+
var output = formatter.format(
70+
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
71+
expect(output).toEqual(expected);
72+
});
5173
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
library bar.ng_deps.dart;
2+
3+
import 'bar.dart';
4+
import 'package:angular2/src/core/metadata.dart';
5+
6+
var _visited = false;
7+
void initReflector(reflector) {
8+
if (_visited) return;
9+
_visited = true;
10+
reflector
11+
..registerType(
12+
ToolTip,
13+
new ReflectionInfo(const [
14+
const Directive(
15+
selector: '[tool-tip]',
16+
queries: const {'queryField': const ContentChild('child')})
17+
], const [], () => new ToolTip()));
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
library bar.ng_deps.dart;
2+
3+
import 'bar.dart';
4+
import 'package:angular2/src/core/metadata.dart';
5+
6+
var _visited = false;
7+
void initReflector(reflector) {
8+
if (_visited) return;
9+
_visited = true;
10+
reflector
11+
..registerType(
12+
ToolTip,
13+
new ReflectionInfo(const [
14+
const Directive(
15+
selector: '[tool-tip]',
16+
queries: const {'queryField': const ContentChild('child')})
17+
], const [], () => new ToolTip()))
18+
..registerSetters({'queryField': (o, v) => o.queryField = v});
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library bar.ng_deps.dart;
2+
3+
import 'bar.dart';
4+
import 'package:angular2/src/core/metadata.dart';
5+
6+
var _visited = false;
7+
void initReflector(reflector) {
8+
if (_visited) return;
9+
_visited = true;
10+
reflector
11+
..registerType(
12+
ToolTip,
13+
new ReflectionInfo(const [
14+
const Directive(
15+
selector: '[tool-tip]')
16+
], const [], () => new ToolTip(), null, const {'queryField': const [const ContentChild('child')]}));
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
library bar.ng_deps.dart;
2+
3+
import 'bar.dart';
4+
import 'package:angular2/src/core/metadata.dart';
5+
6+
var _visited = false;
7+
void initReflector(reflector) {
8+
if (_visited) return;
9+
_visited = true;
10+
reflector
11+
..registerType(
12+
ToolTip,
13+
new ReflectionInfo(const [
14+
const Directive(
15+
selector: '[tool-tip]')
16+
], const [], () => new ToolTip(), null, const {'queryField': const [const ContentChild('child')]}))
17+
..registerSetters({'queryField': (o, v) => o.queryField = v});
18+
}

0 commit comments

Comments
 (0)
X Tutup