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 library test.runner.parse_metadata; | 5 library test.runner.parse_metadata; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 return _contextualize(literal, | 96 return _contextualize(literal, |
97 () => new PlatformSelector.parse(literal.stringValue)); | 97 () => new PlatformSelector.parse(literal.stringValue)); |
98 } | 98 } |
99 | 99 |
100 /// Parses a `@Timeout` annotation. | 100 /// Parses a `@Timeout` annotation. |
101 /// | 101 /// |
102 /// [annotation] is the annotation. [constructorName] is the name of the named | 102 /// [annotation] is the annotation. [constructorName] is the name of the named |
103 /// constructor for the annotation, if any. | 103 /// constructor for the annotation, if any. |
104 Timeout _parseTimeout(Annotation annotation, String constructorName) { | 104 Timeout _parseTimeout(Annotation annotation, String constructorName) { |
105 _assertConstructorName(constructorName, 'Timeout', annotation, | 105 _assertConstructorName(constructorName, 'Timeout', annotation, |
106 validNames: [null, 'factor']); | 106 validNames: [null, 'factor', 'none']); |
107 | 107 |
108 var description = 'Timeout'; | 108 var description = 'Timeout'; |
109 if (constructorName != null) description += '.$constructorName'; | 109 if (constructorName != null) description += '.$constructorName'; |
110 | 110 |
| 111 if (constructorName == 'none') { |
| 112 _assertNoArguments(annotation, description); |
| 113 return Timeout.none; |
| 114 } |
| 115 |
111 _assertArguments(annotation.arguments, description, annotation, | 116 _assertArguments(annotation.arguments, description, annotation, |
112 positional: 1); | 117 positional: 1); |
113 | 118 |
114 var args = annotation.arguments.arguments; | 119 var args = annotation.arguments.arguments; |
115 if (constructorName == null) return new Timeout(_parseDuration(args.first)); | 120 if (constructorName == null) return new Timeout(_parseDuration(args.first)); |
116 return new Timeout.factor(_parseNum(args.first)); | 121 return new Timeout.factor(_parseNum(args.first)); |
117 } | 122 } |
118 | 123 |
119 /// Parses a `Timeout` constructor. | 124 /// Parses a `Timeout` constructor. |
120 Timeout _parseTimeoutConstructor(InstanceCreationExpression constructor) { | 125 Timeout _parseTimeoutConstructor(InstanceCreationExpression constructor) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 positional: 1); | 174 positional: 1); |
170 | 175 |
171 return _parseMap(annotation.arguments.arguments.first, key: (key) { | 176 return _parseMap(annotation.arguments.arguments.first, key: (key) { |
172 var selector = _parseString(key); | 177 var selector = _parseString(key); |
173 return _contextualize(selector, | 178 return _contextualize(selector, |
174 () => new PlatformSelector.parse(selector.stringValue)); | 179 () => new PlatformSelector.parse(selector.stringValue)); |
175 }, value: (value) { | 180 }, value: (value) { |
176 var expressions = []; | 181 var expressions = []; |
177 if (value is ListLiteral) { | 182 if (value is ListLiteral) { |
178 expressions = _parseList(value); | 183 expressions = _parseList(value); |
179 } else if (value is InstanceCreationExpression) { | 184 } else if (value is InstanceCreationExpression || |
| 185 value is PrefixedIdentifier) { |
180 expressions = [value]; | 186 expressions = [value]; |
181 } else { | 187 } else { |
182 throw new SourceSpanFormatException( | 188 throw new SourceSpanFormatException( |
183 'Expected a Timeout, Skip, or List of those.', | 189 'Expected a Timeout, Skip, or List of those.', |
184 _spanFor(value)); | 190 _spanFor(value)); |
185 } | 191 } |
186 | 192 |
187 var timeout; | 193 var timeout; |
188 var skip; | 194 var skip; |
189 for (var expression in expressions) { | 195 for (var expression in expressions) { |
190 var className = expression is InstanceCreationExpression | 196 if (expression is InstanceCreationExpression) { |
191 ? _resolveConstructor( | 197 var className = _resolveConstructor( |
192 expression.constructorName.type.name, | 198 expression.constructorName.type.name, |
193 expression.constructorName.name).first | 199 expression.constructorName.name).first; |
194 : null; | |
195 | 200 |
196 if (className == 'Timeout') { | 201 if (className == 'Timeout') { |
| 202 _assertSingle(timeout, 'Timeout', expression); |
| 203 timeout = _parseTimeoutConstructor(expression); |
| 204 continue; |
| 205 } else if (className == 'Skip') { |
| 206 _assertSingle(skip, 'Skip', expression); |
| 207 skip = _parseSkipConstructor(expression); |
| 208 continue; |
| 209 } |
| 210 } else if (expression is PrefixedIdentifier && |
| 211 expression.prefix.name == 'Timeout') { |
| 212 if (expression.identifier.name != 'none') { |
| 213 throw new SourceSpanFormatException( |
| 214 'Undefined value.', _spanFor(expression)); |
| 215 } |
| 216 |
197 _assertSingle(timeout, 'Timeout', expression); | 217 _assertSingle(timeout, 'Timeout', expression); |
198 timeout = _parseTimeoutConstructor(expression); | 218 timeout = Timeout.none; |
199 } else if (className == 'Skip') { | 219 continue; |
200 _assertSingle(skip, 'Skip', expression); | |
201 skip = _parseSkipConstructor(expression); | |
202 } else { | |
203 throw new SourceSpanFormatException( | |
204 'Expected a Timeout or Skip.', | |
205 _spanFor(expression)); | |
206 } | 220 } |
| 221 |
| 222 throw new SourceSpanFormatException( |
| 223 'Expected a Timeout or Skip.', |
| 224 _spanFor(expression)); |
207 } | 225 } |
208 | 226 |
209 return new Metadata.parse(timeout: timeout, skip: skip); | 227 return new Metadata.parse(timeout: timeout, skip: skip); |
210 }); | 228 }); |
211 } | 229 } |
212 | 230 |
213 /// Parses a `const Duration` expression. | 231 /// Parses a `const Duration` expression. |
214 Duration _parseDuration(Expression expression) { | 232 Duration _parseDuration(Expression expression) { |
215 _parseConstructor(expression, 'Duration'); | 233 _parseConstructor(expression, 'Duration'); |
216 | 234 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 buffer.write("${positional + optional} argument"); | 418 buffer.write("${positional + optional} argument"); |
401 if (positional > 1) buffer.write("s"); | 419 if (positional > 1) buffer.write("s"); |
402 buffer.write("."); | 420 buffer.write("."); |
403 throw new SourceSpanFormatException( | 421 throw new SourceSpanFormatException( |
404 buffer.toString(), _spanFor(arguments)); | 422 buffer.toString(), _spanFor(arguments)); |
405 } | 423 } |
406 | 424 |
407 return namedValues; | 425 return namedValues; |
408 } | 426 } |
409 | 427 |
| 428 /// Assert that [annotation] (described by [name]) has no argument list. |
| 429 void _assertNoArguments(Annotation annotation, String name) { |
| 430 if (annotation.arguments == null) return; |
| 431 throw new SourceSpanFormatException( |
| 432 "$name doesn't take arguments.", _spanFor(annotation)); |
| 433 } |
| 434 |
410 /// Parses a Map literal. | 435 /// Parses a Map literal. |
411 /// | 436 /// |
412 /// By default, returns [Expression] keys and values. These can be overridden | 437 /// By default, returns [Expression] keys and values. These can be overridden |
413 /// with the [key] and [value] parameters. | 438 /// with the [key] and [value] parameters. |
414 Map _parseMap(Expression expression, {key(Expression expression), | 439 Map _parseMap(Expression expression, {key(Expression expression), |
415 value(Expression expression)}) { | 440 value(Expression expression)}) { |
416 if (key == null) key = (expression) => expression; | 441 if (key == null) key = (expression) => expression; |
417 if (value == null) value = (expression) => expression; | 442 if (value == null) value = (expression) => expression; |
418 | 443 |
419 if (expression is! MapLiteral) { | 444 if (expression is! MapLiteral) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 return fn(); | 511 return fn(); |
487 } on SourceSpanFormatException catch (error) { | 512 } on SourceSpanFormatException catch (error) { |
488 var file = new SourceFile(new File(_path).readAsStringSync(), | 513 var file = new SourceFile(new File(_path).readAsStringSync(), |
489 url: p.toUri(_path)); | 514 url: p.toUri(_path)); |
490 var span = contextualizeSpan(error.span, literal, file); | 515 var span = contextualizeSpan(error.span, literal, file); |
491 if (span == null) rethrow; | 516 if (span == null) rethrow; |
492 throw new SourceSpanFormatException(error.message, span); | 517 throw new SourceSpanFormatException(error.message, span); |
493 } | 518 } |
494 } | 519 } |
495 } | 520 } |
OLD | NEW |