parent
e7d65ad96f
commit
589ce31dfc
|
@ -2,6 +2,7 @@ library angular2.transform.bind_generator.generator;
|
|||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:angular2/src/transform/common/asset_reader.dart';
|
||||
import 'package:angular2/src/transform/common/ng_deps.dart';
|
||||
import 'package:angular2/src/transform/common/property_utils.dart' as prop;
|
||||
|
@ -9,6 +10,62 @@ import 'package:barback/barback.dart';
|
|||
|
||||
import 'visitor.dart';
|
||||
|
||||
class _ExtractQueryFieldsFromAnnotation extends Object
|
||||
with RecursiveAstVisitor<Object> {
|
||||
final ConstantEvaluator _evaluator = new ConstantEvaluator();
|
||||
final List<String> queryFields = [];
|
||||
|
||||
@override
|
||||
Object visitNamedExpression(NamedExpression node) {
|
||||
if ('${node.name.label}' == "queries") {
|
||||
if (node.expression is! MapLiteral) {
|
||||
throw new FormatException(
|
||||
'Expected a map value for "queries", but got ${node.expression}',
|
||||
node.toSource());
|
||||
}
|
||||
MapLiteral queries = node.expression;
|
||||
queryFields.addAll(queries.entries.map((e) => e.key.accept(_evaluator)));
|
||||
}
|
||||
return super.visitNamedExpression(node);
|
||||
}
|
||||
|
||||
Map asMap() {
|
||||
return new Map.fromIterable(queryFields, value: (_) => 'Object');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class _ExtractQueryFieldsFromPropMetadata extends Object
|
||||
with RecursiveAstVisitor<Object> {
|
||||
final ConstantEvaluator _evaluator = new ConstantEvaluator();
|
||||
final List<String> queryFields = [];
|
||||
|
||||
@override
|
||||
Object visitMapLiteralEntry(MapLiteralEntry node) {
|
||||
if (_hasQueryAnnotation(node.value)) {
|
||||
queryFields.add(node.key.accept(_evaluator));
|
||||
}
|
||||
return super.visitMapLiteralEntry(node);
|
||||
}
|
||||
|
||||
bool _hasQueryAnnotation(list) {
|
||||
var res = false;
|
||||
list.elements.forEach((item) {
|
||||
var n = item.constructorName.toString();
|
||||
if(n == "ContentChild" || n == "ViewChild" || n == "ContentChildren" || n == "ViewChildren") {
|
||||
res = true;
|
||||
}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
asMap() {
|
||||
return new Map.fromIterable(queryFields, value: (_) => 'Object');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<String> createNgSettersAndGetters(
|
||||
AssetReader reader, AssetId entryPoint) async {
|
||||
NgDeps ngDeps = await NgDeps.parse(reader, entryPoint);
|
||||
|
@ -17,6 +74,18 @@ Future<String> createNgSettersAndGetters(
|
|||
var setters = _generateSetters(_createPropertiesMap(ngDeps));
|
||||
var getters = _generateGetters(_createEventPropertiesList(ngDeps));
|
||||
|
||||
ngDeps.registeredTypes.forEach((t) {
|
||||
final fromAnnotation = new _ExtractQueryFieldsFromAnnotation();
|
||||
t.annotations.accept(fromAnnotation);
|
||||
|
||||
final fromPropMetadata = new _ExtractQueryFieldsFromPropMetadata();
|
||||
if (t.propMetadata != null) {
|
||||
t.propMetadata.accept(fromPropMetadata);
|
||||
}
|
||||
setters.addAll(_generateSetters(fromAnnotation.asMap()));
|
||||
setters.addAll(_generateSetters(fromPropMetadata.asMap()));
|
||||
});
|
||||
|
||||
if (setters.isEmpty && getters.isEmpty) return code;
|
||||
var out = new StringBuffer();
|
||||
var codeInjectIdx = ngDeps.registeredTypes.last.registerMethod.end;
|
||||
|
|
|
@ -26,6 +26,9 @@ class RegisteredType {
|
|||
/// The annotations registered.
|
||||
final Expression annotations;
|
||||
|
||||
/// The property metadata registered.
|
||||
final Expression propMetadata;
|
||||
|
||||
RenderDirectiveMetadata _directiveMetadata = null;
|
||||
|
||||
RegisteredType._(
|
||||
|
@ -34,7 +37,8 @@ class RegisteredType {
|
|||
this.reflectionInfoCreate,
|
||||
this.factoryFn,
|
||||
this.parameters,
|
||||
this.annotations);
|
||||
this.annotations,
|
||||
this.propMetadata);
|
||||
|
||||
/// Creates a {@link RegisteredType} given a {@link MethodInvocation} node representing
|
||||
/// a call to `registerType`.
|
||||
|
@ -42,7 +46,7 @@ class RegisteredType {
|
|||
var visitor = new _ParseRegisterTypeVisitor();
|
||||
registerMethod.accept(visitor);
|
||||
return new RegisteredType._(visitor.typeName, registerMethod, visitor.info,
|
||||
visitor.factoryFn, visitor.parameters, visitor.annotations);
|
||||
visitor.factoryFn, visitor.parameters, visitor.annotations, visitor.propMetadata);
|
||||
}
|
||||
|
||||
RenderDirectiveMetadata get directiveMetadata {
|
||||
|
@ -68,6 +72,7 @@ class _ParseRegisterTypeVisitor extends Object
|
|||
Expression factoryFn;
|
||||
Expression parameters;
|
||||
Expression annotations;
|
||||
Expression propMetadata;
|
||||
|
||||
@override
|
||||
Object visitMethodInvocation(MethodInvocation node) {
|
||||
|
@ -90,6 +95,8 @@ class _ParseRegisterTypeVisitor extends Object
|
|||
parameters = arg;
|
||||
} else if (i == 2) {
|
||||
factoryFn = arg;
|
||||
} else if (i == 4) {
|
||||
propMetadata = arg;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,4 +48,26 @@ void allTests() {
|
|||
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
|
||||
expect(output).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should generate setters for queries defined in the class annotation.',
|
||||
() async {
|
||||
var inputPath = 'bind_generator/queries_class_annotation_files/bar.ng_deps.dart';
|
||||
var expected = formatter.format(
|
||||
readFile('bind_generator/queries_class_annotation_files/expected/bar.ng_deps.dart'));
|
||||
|
||||
var output = formatter.format(
|
||||
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
|
||||
expect(output).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should generate setters for queries defined via prop annotations.',
|
||||
() async {
|
||||
var inputPath = 'bind_generator/queries_prop_annotations_files/bar.ng_deps.dart';
|
||||
var expected = formatter.format(
|
||||
readFile('bind_generator/queries_prop_annotations_files/expected/bar.ng_deps.dart'));
|
||||
|
||||
var output = formatter.format(
|
||||
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
|
||||
expect(output).toEqual(expected);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
library bar.ng_deps.dart;
|
||||
|
||||
import 'bar.dart';
|
||||
import 'package:angular2/src/core/metadata.dart';
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(
|
||||
ToolTip,
|
||||
new ReflectionInfo(const [
|
||||
const Directive(
|
||||
selector: '[tool-tip]',
|
||||
queries: const {'queryField': const ContentChild('child')})
|
||||
], const [], () => new ToolTip()));
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
library bar.ng_deps.dart;
|
||||
|
||||
import 'bar.dart';
|
||||
import 'package:angular2/src/core/metadata.dart';
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(
|
||||
ToolTip,
|
||||
new ReflectionInfo(const [
|
||||
const Directive(
|
||||
selector: '[tool-tip]',
|
||||
queries: const {'queryField': const ContentChild('child')})
|
||||
], const [], () => new ToolTip()))
|
||||
..registerSetters({'queryField': (o, v) => o.queryField = v});
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
library bar.ng_deps.dart;
|
||||
|
||||
import 'bar.dart';
|
||||
import 'package:angular2/src/core/metadata.dart';
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(
|
||||
ToolTip,
|
||||
new ReflectionInfo(const [
|
||||
const Directive(
|
||||
selector: '[tool-tip]')
|
||||
], const [], () => new ToolTip(), null, const {'queryField': const [const ContentChild('child')]}));
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
library bar.ng_deps.dart;
|
||||
|
||||
import 'bar.dart';
|
||||
import 'package:angular2/src/core/metadata.dart';
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(
|
||||
ToolTip,
|
||||
new ReflectionInfo(const [
|
||||
const Directive(
|
||||
selector: '[tool-tip]')
|
||||
], const [], () => new ToolTip(), null, const {'queryField': const [const ContentChild('child')]}))
|
||||
..registerSetters({'queryField': (o, v) => o.queryField = v});
|
||||
}
|
Loading…
Reference in New Issue