OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:io'; | 5 import 'dart:io'; |
6 | 6 |
7 import 'package:analyzer/analyzer.dart'; | 7 import 'package:analyzer/analyzer.dart'; |
8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
9 import 'package:path/path.dart' as p; | 9 import 'package:path/path.dart' as p; |
10 import 'package:source_span/source_span.dart'; | 10 import 'package:source_span/source_span.dart'; |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 _Parser(String path) | 35 _Parser(String path) |
36 : _path = path { | 36 : _path = path { |
37 var contents = new File(path).readAsStringSync(); | 37 var contents = new File(path).readAsStringSync(); |
38 var directives = parseDirectives(contents, name: path).directives; | 38 var directives = parseDirectives(contents, name: path).directives; |
39 _annotations = directives.isEmpty ? [] : directives.first.metadata; | 39 _annotations = directives.isEmpty ? [] : directives.first.metadata; |
40 | 40 |
41 // We explicitly *don't* just look for "package:test" imports here, | 41 // We explicitly *don't* just look for "package:test" imports here, |
42 // because it could be re-exported from another library. | 42 // because it could be re-exported from another library. |
43 _prefixes = directives.map((directive) { | 43 _prefixes = directives.map((directive) { |
44 if (directive is! ImportDirective) return null; | 44 if (directive is ImportDirective) { |
45 if (directive.prefix == null) return null; | 45 if (directive.prefix == null) return null; |
46 return directive.prefix.name; | 46 return directive.prefix.name; |
| 47 } else { |
| 48 return null; |
| 49 } |
47 }).where((prefix) => prefix != null).toSet(); | 50 }).where((prefix) => prefix != null).toSet(); |
48 } | 51 } |
49 | 52 |
50 /// Parses the metadata. | 53 /// Parses the metadata. |
51 Metadata parse() { | 54 Metadata parse() { |
52 var timeout; | 55 Timeout timeout; |
53 var testOn; | 56 PlatformSelector testOn; |
54 var skip; | 57 var skip; |
55 var onPlatform; | 58 Map<PlatformSelector, Metadata> onPlatform; |
56 var tags; | 59 Set<String> tags; |
57 | 60 |
58 for (var annotation in _annotations) { | 61 for (var annotation in _annotations) { |
59 var pair = _resolveConstructor( | 62 var pair = _resolveConstructor( |
60 annotation.name, annotation.constructorName); | 63 annotation.name, annotation.constructorName); |
61 var name = pair.first; | 64 var name = pair.first; |
62 var constructorName = pair.last; | 65 var constructorName = pair.last; |
63 | 66 |
64 if (name == 'TestOn') { | 67 if (name == 'TestOn') { |
65 _assertSingle(testOn, 'TestOn', annotation); | 68 _assertSingle(testOn, 'TestOn', annotation); |
66 testOn = _parseTestOn(annotation, constructorName); | 69 testOn = _parseTestOn(annotation, constructorName); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 251 |
249 return new Metadata.parse(timeout: timeout, skip: skip); | 252 return new Metadata.parse(timeout: timeout, skip: skip); |
250 }); | 253 }); |
251 } | 254 } |
252 | 255 |
253 /// Parses a `const Duration` expression. | 256 /// Parses a `const Duration` expression. |
254 Duration _parseDuration(Expression expression) { | 257 Duration _parseDuration(Expression expression) { |
255 _parseConstructor(expression, 'Duration'); | 258 _parseConstructor(expression, 'Duration'); |
256 | 259 |
257 var constructor = expression as InstanceCreationExpression; | 260 var constructor = expression as InstanceCreationExpression; |
258 var values = _assertArguments( | 261 var valueExpressions = _assertArguments( |
259 constructor.argumentList, 'Duration', constructor, named: [ | 262 constructor.argumentList, 'Duration', constructor, named: [ |
260 'days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds' | 263 'days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds' |
261 ]); | 264 ]); |
262 | 265 |
263 for (var key in values.keys.toList()) { | 266 var values = mapMap(valueExpressions, |
264 if (values.containsKey(key)) values[key] = _parseInt(values[key]); | 267 value: (_, value) => _parseInt(value)); |
265 } | |
266 | 268 |
267 return new Duration( | 269 return new Duration( |
268 days: values["days"] == null ? 0 : values["days"], | 270 days: values["days"] == null ? 0 : values["days"], |
269 hours: values["hours"] == null ? 0 : values["hours"], | 271 hours: values["hours"] == null ? 0 : values["hours"], |
270 minutes: values["minutes"] == null ? 0 : values["minutes"], | 272 minutes: values["minutes"] == null ? 0 : values["minutes"], |
271 seconds: values["seconds"] == null ? 0 : values["seconds"], | 273 seconds: values["seconds"] == null ? 0 : values["seconds"], |
272 milliseconds: values["milliseconds"] == null ? 0 : values["milliseconds"
], | 274 milliseconds: values["milliseconds"] == null ? 0 : values["milliseconds"
], |
273 microseconds: | 275 microseconds: |
274 values["microseconds"] == null ? 0 : values["microseconds"]); | 276 values["microseconds"] == null ? 0 : values["microseconds"]); |
275 } | 277 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 if (positional == null) positional = 0; | 388 if (positional == null) positional = 0; |
387 if (optional == null) optional = 0; | 389 if (optional == null) optional = 0; |
388 if (named == null) named = new Set(); | 390 if (named == null) named = new Set(); |
389 | 391 |
390 if (arguments == null) { | 392 if (arguments == null) { |
391 throw new SourceSpanFormatException( | 393 throw new SourceSpanFormatException( |
392 '$name takes arguments.', _spanFor(node)); | 394 '$name takes arguments.', _spanFor(node)); |
393 } | 395 } |
394 | 396 |
395 var actualNamed = arguments.arguments | 397 var actualNamed = arguments.arguments |
396 .where((arg) => arg is NamedExpression).toList(); | 398 .where((arg) => arg is NamedExpression) |
| 399 .map((arg) => arg as NamedExpression) |
| 400 .toList(); |
397 if (!actualNamed.isEmpty && named.isEmpty) { | 401 if (!actualNamed.isEmpty && named.isEmpty) { |
398 throw new SourceSpanFormatException( | 402 throw new SourceSpanFormatException( |
399 "$name doesn't take named arguments.", _spanFor(actualNamed.first)); | 403 "$name doesn't take named arguments.", _spanFor(actualNamed.first)); |
400 } | 404 } |
401 | 405 |
402 var namedValues = {}; | 406 var namedValues = <String, Expression>{}; |
403 for (var argument in actualNamed) { | 407 for (var argument in actualNamed) { |
404 var argumentName = argument.name.label.name; | 408 var argumentName = argument.name.label.name; |
405 if (!named.contains(argumentName)) { | 409 if (!named.contains(argumentName)) { |
406 throw new SourceSpanFormatException( | 410 throw new SourceSpanFormatException( |
407 '$name doesn\'t take an argument named "$argumentName".', | 411 '$name doesn\'t take an argument named "$argumentName".', |
408 _spanFor(argument)); | 412 _spanFor(argument)); |
409 } else if (namedValues.containsKey(argumentName)) { | 413 } else if (namedValues.containsKey(argumentName)) { |
410 throw new SourceSpanFormatException( | 414 throw new SourceSpanFormatException( |
411 'An argument named "$argumentName" was already passed.', | 415 'An argument named "$argumentName" was already passed.', |
412 _spanFor(argument)); | 416 _spanFor(argument)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 void _assertNoArguments(Annotation annotation, String name) { | 455 void _assertNoArguments(Annotation annotation, String name) { |
452 if (annotation.arguments == null) return; | 456 if (annotation.arguments == null) return; |
453 throw new SourceSpanFormatException( | 457 throw new SourceSpanFormatException( |
454 "$name doesn't take arguments.", _spanFor(annotation)); | 458 "$name doesn't take arguments.", _spanFor(annotation)); |
455 } | 459 } |
456 | 460 |
457 /// Parses a Map literal. | 461 /// Parses a Map literal. |
458 /// | 462 /// |
459 /// By default, returns [Expression] keys and values. These can be overridden | 463 /// By default, returns [Expression] keys and values. These can be overridden |
460 /// with the [key] and [value] parameters. | 464 /// with the [key] and [value] parameters. |
461 Map _parseMap(Expression expression, {key(Expression expression), | 465 Map/*<K, V>*/ _parseMap/*<K, V>*/(Expression expression, |
462 value(Expression expression)}) { | 466 {/*=K*/ key(Expression expression), |
463 if (key == null) key = (expression) => expression; | 467 /*=V*/ value(Expression expression)}) { |
464 if (value == null) value = (expression) => expression; | 468 if (key == null) key = (expression) => expression as dynamic/*=K*/; |
| 469 if (value == null) value = (expression) => expression as dynamic/*=V*/; |
465 | 470 |
466 if (expression is! MapLiteral) { | 471 if (expression is! MapLiteral) { |
467 throw new SourceSpanFormatException( | 472 throw new SourceSpanFormatException( |
468 "Expected a Map.", _spanFor(expression)); | 473 "Expected a Map.", _spanFor(expression)); |
469 } | 474 } |
470 | 475 |
471 var map = expression as MapLiteral; | 476 var map = expression as MapLiteral; |
472 if (map.constKeyword == null) { | 477 if (map.constKeyword == null) { |
473 throw new SourceSpanFormatException( | 478 throw new SourceSpanFormatException( |
474 "Map literals must be const.", _spanFor(map)); | 479 "Map literals must be const.", _spanFor(map)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 return fn(); | 538 return fn(); |
534 } on SourceSpanFormatException catch (error) { | 539 } on SourceSpanFormatException catch (error) { |
535 var file = new SourceFile(new File(_path).readAsStringSync(), | 540 var file = new SourceFile(new File(_path).readAsStringSync(), |
536 url: p.toUri(_path)); | 541 url: p.toUri(_path)); |
537 var span = contextualizeSpan(error.span, literal, file); | 542 var span = contextualizeSpan(error.span, literal, file); |
538 if (span == null) rethrow; | 543 if (span == null) rethrow; |
539 throw new SourceSpanFormatException(error.message, span); | 544 throw new SourceSpanFormatException(error.message, span); |
540 } | 545 } |
541 } | 546 } |
542 } | 547 } |
OLD | NEW |