| Index: pkg/front_end/lib/src/fasta/source/directive_listener.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/source/directive_listener.dart b/pkg/front_end/lib/src/fasta/source/directive_listener.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..278b44a02bb6977e887a4ca222d5a215591b163c
|
| --- /dev/null
|
| +++ b/pkg/front_end/lib/src/fasta/source/directive_listener.dart
|
| @@ -0,0 +1,88 @@
|
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +/// Listener used in combination with `TopLevelParser` to extract the URIs of
|
| +/// import, part, and export directives.
|
| +library front_end.src.fasta.source.directive_listener;
|
| +
|
| +import '../fasta_codes.dart' show FastaMessage, codeExpectedBlockToSkip;
|
| +import '../parser/dart_vm_native.dart' show skipNativeClause;
|
| +import '../parser/listener.dart';
|
| +import '../quote.dart';
|
| +import '../scanner/token.dart';
|
| +
|
| +/// Listener that records the URIs from imports, exports, and part directives.
|
| +///
|
| +/// This is normally used in combination with the `TopLevelParser`, which skips
|
| +/// over the body of declarations like classes and function that are irrelevant
|
| +/// for directives. Note that on correct programs directives cannot occur after
|
| +/// any top-level declaration, but we recommend to continue parsing the entire
|
| +/// file in order to gracefully handle input errors.
|
| +class DirectiveListener extends Listener {
|
| + /// Whether we accept the native-syntax used by the VM patch files.
|
| + final bool acceptsNativeClause;
|
| +
|
| + /// Collects URIs that occur on any import directive.
|
| + final Set<String> imports = new Set<String>();
|
| +
|
| + /// Collects URIs that occur on any export directive.
|
| + final Set<String> exports = new Set<String>();
|
| +
|
| + /// Collects URIs that occur on any part directive.
|
| + final Set<String> parts = new Set<String>();
|
| +
|
| + DirectiveListener({this.acceptsNativeClause: false});
|
| +
|
| + /// Set when entering the context of a directive, null when the parser is not
|
| + /// looking at a directive.
|
| + Set<String> _current = null;
|
| +
|
| + bool get _inDirective => _current != null;
|
| +
|
| + @override
|
| + beginImport(_) {
|
| + _current = imports;
|
| + }
|
| +
|
| + @override
|
| + beginExport(_) {
|
| + _current = exports;
|
| + }
|
| +
|
| + @override
|
| + beginPart(_) {
|
| + _current = parts;
|
| + }
|
| +
|
| + @override
|
| + endExport(export, semicolon) {
|
| + _current = null;
|
| + }
|
| +
|
| + @override
|
| + endImport(import, deferred, asKeyword, semicolon) {
|
| + _current = null;
|
| + }
|
| +
|
| + @override
|
| + endPart(part, semicolon) {
|
| + _current = null;
|
| + }
|
| +
|
| + @override
|
| + void beginLiteralString(Token token) {
|
| + if (_inDirective) {
|
| + _current.add(unescapeString(token.lexeme));
|
| + }
|
| + }
|
| +
|
| + @override
|
| + Token handleUnrecoverableError(Token token, FastaMessage message) {
|
| + if (acceptsNativeClause && message.code == codeExpectedBlockToSkip) {
|
| + Token recover = skipNativeClause(token);
|
| + if (recover != null) return recover;
|
| + }
|
| + return super.handleUnrecoverableError(token, message);
|
| + }
|
| +}
|
|
|