Skip to content

Commit 9622318

Browse files
vicbmhevery
authored andcommitted
fix(StaticMetadataExtractor): Map members annotations to all annotations
Closes dart-archive#904
1 parent 9fdd208 commit 9622318

7 files changed

+64
-55
lines changed

lib/tools/html_extractor.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class HtmlExpressionExtractor {
7070
visitNodes(List<Node> nodes, NodeVisitor visitor) {
7171
for (Node node in nodes) {
7272
visitor(node);
73-
if (node.nodes.length > 0) {
73+
if (node.nodes.isNotEmpty) {
7474
visitNodes(node.nodes, visitor);
7575
}
7676
}

lib/tools/io.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ library angular.io;
33
typedef FsVisitor(String file);
44

55
/**
6-
* A simple mockabe wrapper around dart:io that can be used without introducing
6+
* A simple mockable wrapper around dart:io that can be used without introducing
77
* direct dependencies on dart:io.
88
*/
99
abstract class IoService {

lib/tools/selector.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ class _SelectorPart {
2222
final String attrName;
2323
final String attrValue;
2424

25-
const _SelectorPart.fromElement(String this.element)
25+
const _SelectorPart.fromElement(this.element)
2626
: className = null, attrName = null, attrValue = null;
2727

28-
const _SelectorPart.fromClass(String this.className)
28+
const _SelectorPart.fromClass(this.className)
2929
: element = null, attrName = null, attrValue = null;
3030

3131

32-
const _SelectorPart.fromAttribute(String this.attrName, String this.attrValue)
32+
const _SelectorPart.fromAttribute(this.attrName, this.attrValue)
3333
: element = null, className = null;
3434

35-
toString() =>
35+
String toString() =>
3636
element == null
3737
? (className == null
3838
? (attrValue == '' ? '[$attrName]' : '[$attrName=$attrValue]')

lib/tools/source_metadata_extractor.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class SourceMetadataExtractor {
9999
dirInfo.expressionAttrs.forEach((String attr) {
100100
if (attr == '.') {
101101
var matches = _ATTR_SELECTOR_REGEXP.allMatches(dirInfo.selector);
102-
if (matches.length > 0) {
102+
if (matches.isNotEmpty) {
103103
reprocessedAttrs.add(matches.last.group(1));
104104
}
105105
} else {

lib/tools/transformer/metadata_extractor.dart

+43-44
Original file line numberDiff line numberDiff line change
@@ -342,53 +342,52 @@ class AnnotationExtractor {
342342
return;
343343
}
344344

345-
// Default to using the first acceptable annotation- not sure if
346-
// more than one should ever occur.
347-
var sourceAnnotation = acceptableAnnotations.first;
348-
349-
// Clone the annotation so we don't modify the one in the persistent AST.
350-
var index = type.annotations.indexOf(sourceAnnotation);
351-
var annotation = new AstCloner().visitAnnotation(sourceAnnotation);
352-
ResolutionCopier.copyResolutionData(sourceAnnotation, annotation);
353-
type.annotations[index] = annotation;
354-
355-
var mapArg = annotation.arguments.arguments.firstWhere((arg) =>
356-
(arg is NamedExpression) && (arg.name.label.name == 'map'),
357-
orElse: () => null);
358-
359-
// If we don't have a 'map' parameter yet, add one.
360-
if (mapArg == null) {
361-
var map = new MapLiteral(null, null, null, [], null);
362-
var label = new Label(new SimpleIdentifier(
363-
new _GeneratedToken(TokenType.STRING, 'map')),
364-
new _GeneratedToken(TokenType.COLON, ':'));
365-
mapArg = new NamedExpression(label, map);
366-
annotation.arguments.arguments.add(mapArg);
367-
}
345+
// Merge attribute annotations in all of the class annotations
346+
acceptableAnnotations.forEach((srcAnnotation) {
347+
// Clone the annotation so we don't modify the one in the persistent AST.
348+
var index = type.annotations.indexOf(srcAnnotation);
349+
var annotation = new AstCloner().visitAnnotation(srcAnnotation);
350+
ResolutionCopier.copyResolutionData(srcAnnotation, annotation);
351+
type.annotations[index] = annotation;
352+
353+
var mapArg = annotation.arguments.arguments.firstWhere(
354+
(arg) => (arg is NamedExpression) && (arg.name.label.name == 'map'),
355+
orElse: () => null);
356+
357+
// If we don't have a 'map' parameter yet, add one.
358+
if (mapArg == null) {
359+
var map = new MapLiteral(null, null, null, [], null);
360+
var label = new Label(new SimpleIdentifier(
361+
new _GeneratedToken(TokenType.STRING, 'map')),
362+
new _GeneratedToken(TokenType.COLON, ':'));
363+
mapArg = new NamedExpression(label, map);
364+
annotation.arguments.arguments.add(mapArg);
365+
}
368366

369-
var map = mapArg.expression;
370-
if (map is! MapLiteral) {
371-
warn('Expected \'map\' argument of $annotation to be a map literal',
372-
type.type);
373-
return;
374-
}
375-
memberAnnotations.forEach((memberName, annotation) {
376-
var key = annotation.arguments.arguments.first;
377-
// If the key already exists then it means we have two annotations for
378-
// same member.
379-
if (map.entries.any((entry) => entry.key.toString() == key.toString())) {
380-
warn('Directive $annotation already contains an entry for $key',
381-
type.type);
367+
var map = mapArg.expression;
368+
if (map is! MapLiteral) {
369+
warn('Expected \'map\' argument of $annotation to be a map literal',
370+
type.type);
382371
return;
383372
}
373+
memberAnnotations.forEach((memberName, annotation) {
374+
var key = annotation.arguments.arguments.first;
375+
// If the key already exists then it means we have two annotations for
376+
// same member.
377+
if (map.entries.any((entry) => entry.key.toString() == key.toString())) {
378+
warn('Directive $annotation already contains an entry for $key',
379+
type.type);
380+
return;
381+
}
384382

385-
var typeName = annotation.element.enclosingElement.name;
386-
var value = '${_annotationToMapping[typeName]}$memberName';
387-
var entry = new MapLiteralEntry(
388-
key,
389-
new _GeneratedToken(TokenType.COLON, ':'),
390-
new SimpleStringLiteral(stringToken(value), value));
391-
map.entries.add(entry);
383+
var typeName = annotation.element.enclosingElement.name;
384+
var value = '${_annotationToMapping[typeName]}$memberName';
385+
var entry = new MapLiteralEntry(
386+
key,
387+
new _GeneratedToken(TokenType.COLON, ':'),
388+
new SimpleStringLiteral(stringToken(value), value));
389+
map.entries.add(entry);
390+
});
392391
});
393392
}
394393

@@ -439,5 +438,5 @@ class _AnnotationVisitor extends GeneralizingAstVisitor {
439438
}
440439

441440
bool get hasAnnotations =>
442-
!classAnnotations.isEmpty || !memberAnnotations.isEmpty;
441+
classAnnotations.isNotEmpty || memberAnnotations.isNotEmpty;
443442
}

test/tools/source_metadata_extractor_spec.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ void main() {
116116
}
117117

118118
flattenList(list, map) => list.map(map).fold([], (prev, exprs) =>
119-
new List.from(prev)..addAll(exprs));
119+
new List.from(prev)..addAll(exprs));
120120

121121
List<DirectiveInfo> extractDirectiveInfo(List<DirectiveMetadata> metadata) {
122122
var sourceCrawler = new MockSourceCrawler();

test/tools/transformer/metadata_generator_spec.dart

+13-3
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,12 @@ main() {
159159
'a|web/main.dart': '''
160160
import 'package:angular/angular.dart';
161161
162-
@Decorator(map: {'another-expression': '=>anotherExpression'})
162+
@Directive(
163+
selector: 'first',
164+
map: {'first-expression': '=>anotherExpression'})
165+
@Directive(
166+
selector: 'second',
167+
map: {'second-expression': '=>anotherExpression'})
163168
class Engine {
164169
set anotherExpression(Function) {}
165170
@@ -176,8 +181,13 @@ main() {
176181
],
177182
classes: {
178183
'import_0.Engine': [
179-
'const import_1.Decorator(map: const {'
180-
'\'another-expression\': \'=>anotherExpression\', '
184+
'const import_1.Directive(selector: \'first\', '
185+
'map: const {'
186+
'\'first-expression\': \'=>anotherExpression\', '
187+
'\'two-way-stuff\': \'<=>twoWayStuff\'})',
188+
'const import_1.Directive(selector: \'second\', '
189+
'map: const {'
190+
'\'second-expression\': \'=>anotherExpression\', '
181191
'\'two-way-stuff\': \'<=>twoWayStuff\'})',
182192
]
183193
});

0 commit comments

Comments
 (0)