Chromium Code Reviews| Index: lib/src/util/dart.dart |
| diff --git a/lib/src/util/dart.dart b/lib/src/util/dart.dart |
| index 3ee861b23de6263d9a02f0fc307e65994db758dd..c4c88250f092e2080af54a59734b71baa885b34a 100644 |
| --- a/lib/src/util/dart.dart |
| +++ b/lib/src/util/dart.dart |
| @@ -8,6 +8,13 @@ import 'dart:async'; |
| import 'dart:io'; |
| import 'dart:isolate'; |
| +import 'package:analyzer/src/error.dart'; |
| +import 'package:analyzer/src/generated/ast.dart'; |
| +import 'package:analyzer/src/generated/error.dart'; |
| +import 'package:analyzer/src/generated/parser.dart'; |
| +import 'package:analyzer/src/generated/scanner.dart'; |
| +import 'package:analyzer/src/generated/source_io.dart'; |
| +import 'package:analyzer/src/string_source.dart'; |
| import 'package:path/path.dart' as p; |
| import 'io.dart'; |
| @@ -70,3 +77,61 @@ void _isolateBuffer(message) { |
| }); |
| }); |
| } |
| + |
| +/// Parse all the annotations at the beginning of a Dart file. |
| +/// |
| +/// This will parse annotations until the first non-annotation production is |
| +/// reached. |
| +List<Annotation> parseAnnotations(String path) { |
| + var contents = new File(path).readAsStringSync(); |
| + var sourceFactory = new SourceFactory([new FileUriResolver()]); |
| + |
| + var absolutePath = p.absolute(path); |
| + var source = sourceFactory.forUri(p.toUri(absolutePath).toString()); |
| + if (source == null) { |
| + throw new ArgumentError("Can't get source for path $path"); |
| + } |
| + if (!source.exists()) { |
| + throw new ArgumentError("Source $source doesn't exist"); |
| + } |
| + |
| + var errorCollector = new _ErrorCollector(); |
| + var reader = new CharSequenceReader(contents); |
| + |
| + // 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
|
| + var scanner = new Scanner(source, reader, errorCollector); |
| + var token = scanner.tokenize(); |
| + var parser = new Parser(source, errorCollector); |
| + parser.currentToken = token; |
| + |
| + var annotations = []; |
| + while (token.type == TokenType.AT) { |
| + annotations.add(parser.parseAnnotation()); |
| + |
| + // TODO(nweiz): this is a hack; add something to the analyzer package to |
| + // support this better. |
| + token = parser.getAndAdvance(); |
| + parser.currentToken = token; |
| + } |
| + |
| + if (errorCollector.hasErrors) throw errorCollector.group; |
| + |
| + return annotations; |
| +} |
| + |
| +/// A simple error listener that collects errors into an [AnalysisErrorGroup]. |
| +class _ErrorCollector extends AnalysisErrorListener { |
| + final _errors = <AnalysisError>[]; |
| + |
| + _ErrorCollector(); |
| + |
| + /// The group of errors collected. |
| + AnalyzerErrorGroup get group => |
| + new AnalyzerErrorGroup.fromAnalysisErrors(_errors); |
| + |
| + /// Whether any errors where collected. |
| + bool get hasErrors => !_errors.isEmpty; |
| + |
| + void onError(AnalysisError error) => _errors.add(error); |
| +} |
| + |