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 |