Chromium Code Reviews| 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 unittest.util.dart; | 5 library unittest.util.dart; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 import 'dart:isolate'; | 9 import 'dart:isolate'; |
| 10 | 10 |
| 11 import 'package:analyzer/src/error.dart'; | |
| 12 import 'package:analyzer/src/generated/ast.dart'; | |
| 13 import 'package:analyzer/src/generated/error.dart'; | |
| 14 import 'package:analyzer/src/generated/parser.dart'; | |
| 15 import 'package:analyzer/src/generated/scanner.dart'; | |
| 16 import 'package:analyzer/src/generated/source_io.dart'; | |
| 17 import 'package:analyzer/src/string_source.dart'; | |
| 11 import 'package:path/path.dart' as p; | 18 import 'package:path/path.dart' as p; |
| 12 | 19 |
| 13 import 'io.dart'; | 20 import 'io.dart'; |
| 14 import 'isolate_wrapper.dart'; | 21 import 'isolate_wrapper.dart'; |
| 15 import 'remote_exception.dart'; | 22 import 'remote_exception.dart'; |
| 16 | 23 |
| 17 /// Runs [code] in an isolate. | 24 /// Runs [code] in an isolate. |
| 18 /// | 25 /// |
| 19 /// [code] should be the contents of a Dart entrypoint. It may contain imports; | 26 /// [code] should be the contents of a Dart entrypoint. It may contain imports; |
| 20 /// they will be resolved in the same context as the host isolate. [message] is | 27 /// they will be resolved in the same context as the host isolate. [message] is |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 Isolate.spawnUri(Uri.parse(message['uri']), [], message['message'], | 70 Isolate.spawnUri(Uri.parse(message['uri']), [], message['message'], |
| 64 packageRoot: packageRoot) | 71 packageRoot: packageRoot) |
| 65 .then((_) => replyTo.send({'type': 'success'})) | 72 .then((_) => replyTo.send({'type': 'success'})) |
| 66 .catchError((error, stackTrace) { | 73 .catchError((error, stackTrace) { |
| 67 replyTo.send({ | 74 replyTo.send({ |
| 68 'type': 'error', | 75 'type': 'error', |
| 69 'error': RemoteException.serialize(error, stackTrace) | 76 'error': RemoteException.serialize(error, stackTrace) |
| 70 }); | 77 }); |
| 71 }); | 78 }); |
| 72 } | 79 } |
| 80 | |
| 81 /// Parse all the annotations at the beginning of a Dart file. | |
| 82 /// | |
| 83 /// This will parse annotations until the first non-annotation production is | |
| 84 /// reached. | |
| 85 List<Annotation> parseAnnotations(String path) { | |
| 86 var contents = new File(path).readAsStringSync(); | |
| 87 var sourceFactory = new SourceFactory([new FileUriResolver()]); | |
| 88 | |
| 89 var absolutePath = p.absolute(path); | |
| 90 var source = sourceFactory.forUri(p.toUri(absolutePath).toString()); | |
| 91 if (source == null) { | |
| 92 throw new ArgumentError("Can't get source for path $path"); | |
| 93 } | |
| 94 if (!source.exists()) { | |
| 95 throw new ArgumentError("Source $source doesn't exist"); | |
| 96 } | |
| 97 | |
| 98 var errorCollector = new _ErrorCollector(); | |
| 99 var reader = new CharSequenceReader(contents); | |
| 100 | |
| 101 // TODO(nweiz): Avoid scanning the entire file when issue 22745 is fixed. | |
|
Bob Nystrom
2015/03/11 19:27:17
I'm really surprised performance is an issue here.
nweiz
2015/03/12 19:24:37
I was really trying to avoid spending much time on
| |
| 102 var scanner = new Scanner(source, reader, errorCollector); | |
| 103 var token = scanner.tokenize(); | |
| 104 var parser = new Parser(source, errorCollector); | |
| 105 parser.currentToken = token; | |
| 106 | |
| 107 var annotations = []; | |
| 108 while (token.type == TokenType.AT) { | |
| 109 annotations.add(parser.parseAnnotation()); | |
| 110 | |
| 111 // TODO(nweiz): this is a hack; add something to the analyzer package to | |
| 112 // support this better. | |
| 113 token = parser.getAndAdvance(); | |
| 114 parser.currentToken = token; | |
| 115 } | |
| 116 | |
| 117 if (errorCollector.hasErrors) throw errorCollector.group; | |
| 118 | |
| 119 return annotations; | |
| 120 } | |
| 121 | |
| 122 /// A simple error listener that collects errors into an [AnalysisErrorGroup]. | |
| 123 class _ErrorCollector extends AnalysisErrorListener { | |
| 124 final _errors = <AnalysisError>[]; | |
| 125 | |
| 126 _ErrorCollector(); | |
| 127 | |
| 128 /// The group of errors collected. | |
| 129 AnalyzerErrorGroup get group => | |
| 130 new AnalyzerErrorGroup.fromAnalysisErrors(_errors); | |
| 131 | |
| 132 /// Whether any errors where collected. | |
| 133 bool get hasErrors => !_errors.isEmpty; | |
| 134 | |
| 135 void onError(AnalysisError error) => _errors.add(error); | |
| 136 } | |
| 137 | |
| OLD | NEW |