parent
e7d65ad96f
commit
589ce31dfc
|
@ -2,6 +2,7 @@ library angular2.transform.bind_generator.generator;
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:analyzer/analyzer.dart';
|
||||||
import 'package:angular2/src/transform/common/asset_reader.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/ng_deps.dart';
|
||||||
import 'package:angular2/src/transform/common/property_utils.dart' as prop;
|
import 'package:angular2/src/transform/common/property_utils.dart' as prop;
|
||||||
|
@ -9,6 +10,62 @@ import 'package:barback/barback.dart';
|
||||||
|
|
||||||
import 'visitor.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(
|
Future<String> createNgSettersAndGetters(
|
||||||
AssetReader reader, AssetId entryPoint) async {
|
AssetReader reader, AssetId entryPoint) async {
|
||||||
NgDeps ngDeps = await NgDeps.parse(reader, entryPoint);
|
NgDeps ngDeps = await NgDeps.parse(reader, entryPoint);
|
||||||
|
@ -17,6 +74,18 @@ Future<String> createNgSettersAndGetters(
|
||||||
var setters = _generateSetters(_createPropertiesMap(ngDeps));
|
var setters = _generateSetters(_createPropertiesMap(ngDeps));
|
||||||
var getters = _generateGetters(_createEventPropertiesList(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;
|
if (setters.isEmpty && getters.isEmpty) return code;
|
||||||
var out = new StringBuffer();
|
var out = new StringBuffer();
|
||||||
var codeInjectIdx = ngDeps.registeredTypes.last.registerMethod.end;
|
var codeInjectIdx = ngDeps.registeredTypes.last.registerMethod.end;
|
||||||
|
|
|
@ -26,6 +26,9 @@ class RegisteredType {
|
||||||
/// The annotations registered.
|
/// The annotations registered.
|
||||||
final Expression annotations;
|
final Expression annotations;
|
||||||
|
|
||||||
|
/// The property metadata registered.
|
||||||
|
final Expression propMetadata;
|
||||||
|
|
||||||
RenderDirectiveMetadata _directiveMetadata = null;
|
RenderDirectiveMetadata _directiveMetadata = null;
|
||||||
|
|
||||||
RegisteredType._(
|
RegisteredType._(
|
||||||
|
@ -34,7 +37,8 @@ class RegisteredType {
|
||||||
this.reflectionInfoCreate,
|
this.reflectionInfoCreate,
|
||||||
this.factoryFn,
|
this.factoryFn,
|
||||||
this.parameters,
|
this.parameters,
|
||||||
this.annotations);
|
this.annotations,
|
||||||
|
this.propMetadata);
|
||||||
|
|
||||||
/// Creates a {@link RegisteredType} given a {@link MethodInvocation} node representing
|
/// Creates a {@link RegisteredType} given a {@link MethodInvocation} node representing
|
||||||
/// a call to `registerType`.
|
/// a call to `registerType`.
|
||||||
|
@ -42,7 +46,7 @@ class RegisteredType {
|
||||||
var visitor = new _ParseRegisterTypeVisitor();
|
var visitor = new _ParseRegisterTypeVisitor();
|
||||||
registerMethod.accept(visitor);
|
registerMethod.accept(visitor);
|
||||||
return new RegisteredType._(visitor.typeName, registerMethod, visitor.info,
|
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 {
|
RenderDirectiveMetadata get directiveMetadata {
|
||||||
|
@ -68,6 +72,7 @@ class _ParseRegisterTypeVisitor extends Object
|
||||||
Expression factoryFn;
|
Expression factoryFn;
|
||||||
Expression parameters;
|
Expression parameters;
|
||||||
Expression annotations;
|
Expression annotations;
|
||||||
|
Expression propMetadata;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Object visitMethodInvocation(MethodInvocation node) {
|
Object visitMethodInvocation(MethodInvocation node) {
|
||||||
|
@ -90,6 +95,8 @@ class _ParseRegisterTypeVisitor extends Object
|
||||||
parameters = arg;
|
parameters = arg;
|
||||||
} else if (i == 2) {
|
} else if (i == 2) {
|
||||||
factoryFn = arg;
|
factoryFn = arg;
|
||||||
|
} else if (i == 4) {
|
||||||
|
propMetadata = arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,4 +48,26 @@ void allTests() {
|
||||||
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
|
await createNgSettersAndGetters(reader, new AssetId('a', inputPath)));
|
||||||
expect(output).toEqual(expected);
|
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