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); |
+} |
+ |