refactor(_DirectiveMetadataVisitor): simplify the code

fixes #2493
This commit is contained in:
Victor Berchet 2015-06-12 09:14:59 +02:00
parent a6e7123995
commit db3d5d4941
2 changed files with 90 additions and 71 deletions

View File

@ -211,31 +211,6 @@ export class DirectiveMetadata {
changeDetection?: string, changeDetection?: string,
exportAs?: string exportAs?: string
}) { }) {
let hostConfig = DirectiveMetadata.parseHostConfig(host);
return new DirectiveMetadata({
id: id,
selector: selector,
compileChildren: compileChildren,
events: events,
hostListeners: StringMapWrapper.get(hostConfig, 'hostListeners'),
hostProperties: StringMapWrapper.get(hostConfig, 'hostProperties'),
hostAttributes: StringMapWrapper.get(hostConfig, 'hostAttributes'),
hostActions: StringMapWrapper.get(hostConfig, 'hostActions'),
properties: properties,
readAttributes: readAttributes,
type: type,
callOnDestroy: callOnDestroy,
callOnChange: callOnChange,
callOnCheck: callOnCheck,
callOnInit: callOnInit,
callOnAllChangesDone: callOnAllChangesDone,
changeDetection: changeDetection,
exportAs: exportAs
});
}
static parseHostConfig(host?: Map<string, string>): StringMap<string, Map<string, string>> {
let hostListeners = MapWrapper.create(); let hostListeners = MapWrapper.create();
let hostProperties = MapWrapper.create(); let hostProperties = MapWrapper.create();
let hostAttributes = MapWrapper.create(); let hostAttributes = MapWrapper.create();
@ -256,10 +231,26 @@ export class DirectiveMetadata {
}); });
} }
return { return new DirectiveMetadata({
hostListeners: hostListeners, hostProperties: hostProperties, hostAttributes: hostAttributes, id: id,
hostActions: hostActions selector: selector,
} compileChildren: compileChildren,
events: events,
hostListeners: hostListeners,
hostProperties: hostProperties,
hostAttributes: hostAttributes,
hostActions: hostActions,
properties: properties,
readAttributes: readAttributes,
type: type,
callOnDestroy: callOnDestroy,
callOnChange: callOnChange,
callOnCheck: callOnCheck,
callOnInit: callOnInit,
callOnAllChangesDone: callOnAllChangesDone,
changeDetection: changeDetection,
exportAs: exportAs
});
} }
} }

View File

@ -48,35 +48,71 @@ num _getDirectiveType(String annotationName, Element element) {
/// [RegisterType] object and pulling out [DirectiveMetadata]. /// [RegisterType] object and pulling out [DirectiveMetadata].
class _DirectiveMetadataVisitor extends Object class _DirectiveMetadataVisitor extends Object
with RecursiveAstVisitor<Object> { with RecursiveAstVisitor<Object> {
DirectiveMetadata meta; bool get _hasMeta => _type != null;
// Annotation fields
num _type;
String _selector;
bool _compileChildren;
List<String> _properties;
Map<String, String> _host;
List<String> _readAttributes;
String _exportAs;
bool _callOnDestroy;
bool _callOnChange;
bool _callOnCheck;
bool _callOnInit;
bool _callOnAllChangesDone;
String changeDetection;
List<String> events;
final ConstantEvaluator _evaluator = new ConstantEvaluator(); final ConstantEvaluator _evaluator = new ConstantEvaluator();
void _createEmptyMetadata(num type) { void _initializeMetadata(num directiveType) {
assert(type >= 0); assert(directiveType >= 0);
meta = DirectiveMetadata.create(
type: type, _type = directiveType;
compileChildren: true, _selector = '';
properties: [], _compileChildren = true;
host: {}, _properties = [];
readAttributes: [], _host = {};
exportAs: null, _readAttributes = [];
callOnDestroy: false, _exportAs = null;
callOnChange: false, _callOnDestroy = false;
callOnCheck: false, _callOnChange = false;
callOnInit: false, _callOnCheck = false;
callOnAllChangesDone: false); _callOnInit = false;
_callOnAllChangesDone = false;
changeDetection = null;
events = [];
} }
DirectiveMetadata get meta => DirectiveMetadata.create(
type: _type,
selector: _selector,
compileChildren: _compileChildren,
properties: _properties,
host: _host,
readAttributes: _readAttributes,
exportAs: _exportAs,
callOnDestroy: _callOnDestroy,
callOnChange: _callOnChange,
callOnCheck: _callOnCheck,
callOnInit: _callOnInit,
callOnAllChangesDone: _callOnAllChangesDone,
changeDetection: changeDetection,
events: events);
@override @override
Object visitAnnotation(Annotation node) { Object visitAnnotation(Annotation node) {
var directiveType = _getDirectiveType('${node.name}', node.element); var directiveType = _getDirectiveType('${node.name}', node.element);
if (directiveType >= 0) { if (directiveType >= 0) {
if (meta != null) { if (_hasMeta) {
throw new FormatException('Only one Directive is allowed per class. ' throw new FormatException('Only one Directive is allowed per class. '
'Found "$node" but already processed "$meta".', 'Found "$node" but already processed "$meta".',
'$node' /* source */); '$node' /* source */);
} }
_createEmptyMetadata(directiveType); _initializeMetadata(directiveType);
super.visitAnnotation(node); super.visitAnnotation(node);
} }
// Annotation we do not recognize - no need to visit. // Annotation we do not recognize - no need to visit.
@ -88,12 +124,12 @@ class _DirectiveMetadataVisitor extends Object
var directiveType = _getDirectiveType( var directiveType = _getDirectiveType(
'${node.constructorName.type.name}', node.staticElement); '${node.constructorName.type.name}', node.staticElement);
if (directiveType >= 0) { if (directiveType >= 0) {
if (meta != null) { if (_hasMeta) {
throw new FormatException('Only one Directive is allowed per class. ' throw new FormatException('Only one Directive is allowed per class. '
'Found "$node" but already processed "$meta".', 'Found "$node" but already processed "$meta".',
'$node' /* source */); '$node' /* source */);
} }
_createEmptyMetadata(directiveType); _initializeMetadata(directiveType);
super.visitInstanceCreationExpression(node); super.visitInstanceCreationExpression(node);
} }
// Annotation we do not recognize - no need to visit. // Annotation we do not recognize - no need to visit.
@ -109,9 +145,7 @@ class _DirectiveMetadataVisitor extends Object
'$node' /* source */); '$node' /* source */);
} }
var keyString = '${node.name.label}'; var keyString = '${node.name.label}';
// TODO(kegluneq): Populate the other values in [DirectiveMetadata] once // TODO(kegluneq): Populate the other values in [DirectiveMetadata]
// they are specified as `hostAttributes` and `hostSetters`.
// See [https://github.com/angular/angular/issues/1244]
switch (keyString) { switch (keyString) {
case 'selector': case 'selector':
_populateSelector(node.expression); _populateSelector(node.expression);
@ -145,14 +179,16 @@ class _DirectiveMetadataVisitor extends Object
} }
void _populateSelector(Expression selectorValue) { void _populateSelector(Expression selectorValue) {
meta.selector = _expressionToString(selectorValue, 'Directive#selector'); _checkMeta();
_selector = _expressionToString(selectorValue, 'Directive#selector');
} }
void _checkMeta() { void _checkMeta() {
if (meta == null) { if (!_hasMeta) {
throw new ArgumentError( throw new ArgumentError(
'Incorrect value passed to readDirectiveMetadata. ' 'Incorrect value passed to readDirectiveMetadata. '
'Expected types are Annotation and InstanceCreationExpression'); 'Expected types are Annotation, InstanceCreationExpression, '
'NodeList or ListLiteral');
} }
} }
@ -164,7 +200,7 @@ class _DirectiveMetadataVisitor extends Object
'Angular 2 expects a bool but could not understand the value for ' 'Angular 2 expects a bool but could not understand the value for '
'Directive#compileChildren.', '$compileChildrenValue' /* source */); 'Directive#compileChildren.', '$compileChildrenValue' /* source */);
} }
meta.compileChildren = evaluated; _compileChildren = evaluated;
} }
/// Evaluates the [Map] represented by `expression` and adds all `key`, /// Evaluates the [Map] represented by `expression` and adds all `key`,
@ -199,25 +235,17 @@ class _DirectiveMetadataVisitor extends Object
void _populateProperties(Expression propertiesValue) { void _populateProperties(Expression propertiesValue) {
_checkMeta(); _checkMeta();
_populateList(propertiesValue, meta.properties, 'Directive#properties'); _populateList(propertiesValue, _properties, 'Directive#properties');
} }
void _populateHost(Expression hostValue) { void _populateHost(Expression hostValue) {
_checkMeta(); _checkMeta();
var host = new Map(); _populateMap(hostValue, _host, 'Directive#host');
_populateMap(hostValue, host, 'Directive#host');
var hostConfig = DirectiveMetadata.parseHostConfig(host);
meta.hostListeners = hostConfig['hostListeners'];
meta.hostProperties = hostConfig['hostProperties'];
meta.hostActions = hostConfig['hostActions'];
meta.hostAttributes = hostConfig['hostAttributes'];
} }
void _populateExportAs(Expression exportAsValue) { void _populateExportAs(Expression exportAsValue) {
_checkMeta(); _checkMeta();
meta.exportAs = _expressionToString(exportAsValue, 'Directive#exportAs'); _exportAs = _expressionToString(exportAsValue, 'Directive#exportAs');
} }
void _populateLifecycle(Expression lifecycleValue) { void _populateLifecycle(Expression lifecycleValue) {
@ -229,10 +257,10 @@ class _DirectiveMetadataVisitor extends Object
} }
ListLiteral l = lifecycleValue; ListLiteral l = lifecycleValue;
var lifecycleEvents = l.elements.map((s) => s.toSource()); var lifecycleEvents = l.elements.map((s) => s.toSource());
meta.callOnDestroy = lifecycleEvents.contains("onDestroy"); _callOnDestroy = lifecycleEvents.contains("onDestroy");
meta.callOnChange = lifecycleEvents.contains("onChange"); _callOnChange = lifecycleEvents.contains("onChange");
meta.callOnCheck = lifecycleEvents.contains("onCheck"); _callOnCheck = lifecycleEvents.contains("onCheck");
meta.callOnInit = lifecycleEvents.contains("onInit"); _callOnInit = lifecycleEvents.contains("onInit");
meta.callOnAllChangesDone = lifecycleEvents.contains("onAllChangesDone"); _callOnAllChangesDone = lifecycleEvents.contains("onAllChangesDone");
} }
} }