Separate AugmentationImportDirective from ImportDirective.
Change-Id: I202320513390dbb218ec86fed18fc2943b168dd8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250413
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index a00f66a..5f2d688 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -365,6 +365,8 @@
R? visitAssignmentExpression(AssignmentExpression node);
+ R? visitAugmentationImportDirective(AugmentationImportDirective node);
+
R? visitAwaitExpression(AwaitExpression node);
R? visitBinaryExpression(BinaryExpression node);
@@ -617,6 +619,29 @@
R? visitYieldStatement(YieldStatement node);
}
+/// An augmentation import directive.
+///
+/// importDirective ::=
+/// [Annotation] 'import' 'augment' [StringLiteral] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class AugmentationImportDirective implements UriBasedDirective {
+ /// The token representing the 'augment' keyword.
+ Token get augmentKeyword;
+
+ /// Return the element associated with this directive, or `null` if the AST
+ /// structure has not been resolved.
+ @override
+ AugmentationImportElement? get element;
+
+ /// The token representing the 'import' keyword.
+ Token get importKeyword;
+
+ /// Return the semicolon terminating the directive.
+ Token get semicolon;
+}
+
/// An await expression.
///
/// awaitExpression ::=
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 92ab86a..2c43bc6 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -154,6 +154,10 @@
visitExpression(node);
@override
+ R? visitAugmentationImportDirective(AugmentationImportDirective node) =>
+ visitUriBasedDirective(node);
+
+ @override
R? visitAwaitExpression(AwaitExpression node) => visitExpression(node);
@override
@@ -698,6 +702,12 @@
}
@override
+ R? visitAugmentationImportDirective(AugmentationImportDirective node) {
+ node.visitChildren(this);
+ return null;
+ }
+
+ @override
R? visitAwaitExpression(AwaitExpression node) {
node.visitChildren(this);
return null;
@@ -1481,6 +1491,9 @@
R? visitAssignmentExpression(AssignmentExpression node) => null;
@override
+ R? visitAugmentationImportDirective(AugmentationImportDirective node) => null;
+
+ @override
R? visitAwaitExpression(AwaitExpression node) => null;
@override
@@ -1897,6 +1910,10 @@
R? visitAssignmentExpression(AssignmentExpression node) => _throw(node);
@override
+ R? visitAugmentationImportDirective(AugmentationImportDirective node) =>
+ _throw(node);
+
+ @override
R? visitAwaitExpression(AwaitExpression node) => _throw(node);
@override
@@ -2363,6 +2380,14 @@
}
@override
+ T? visitAugmentationImportDirective(AugmentationImportDirective node) {
+ stopwatch.start();
+ T? result = _baseVisitor.visitAugmentationImportDirective(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
T? visitAwaitExpression(AwaitExpression node) {
stopwatch.start();
T? result = _baseVisitor.visitAwaitExpression(node);
@@ -3401,6 +3426,10 @@
R? visitAssignmentExpression(AssignmentExpression node) => visitNode(node);
@override
+ R? visitAugmentationImportDirective(AugmentationImportDirective node) =>
+ visitNode(node);
+
+ @override
R? visitAwaitExpression(AwaitExpression node) => visitNode(node);
@override
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 65fc403..6c7347f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -931,19 +931,17 @@
if (directive is ExportDirective) {
var builder = _serializeNamespaceDirective(directive);
exports.add(builder);
+ } else if (directive is AugmentationImportDirectiveImpl) {
+ augmentations.add(
+ UnlinkedImportAugmentationDirective(
+ uri: directive.uri.stringValue,
+ ),
+ );
} else if (directive is ImportDirectiveImpl) {
- if (directive.augmentKeyword != null) {
- augmentations.add(
- UnlinkedImportAugmentationDirective(
- uri: directive.uri.stringValue,
- ),
- );
- } else {
- var builder = _serializeNamespaceDirective(directive);
- imports.add(builder);
- if (builder.uri == 'dart:core') {
- hasDartCoreImport = true;
- }
+ var builder = _serializeNamespaceDirective(directive);
+ imports.add(builder);
+ if (builder.uri == 'dart:core') {
+ hasDartCoreImport = true;
}
} else if (directive is LibraryAugmentationDirective) {
final uri = directive.uri;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 998b077..7983d90 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -570,19 +570,17 @@
if (directive is LibraryDirectiveImpl) {
libraryNameNode = directive.name;
directivesToResolve.add(directive);
+ } else if (directive is AugmentationImportDirective) {
+ // TODO(scheglov) implement
+ throw UnimplementedError();
} else if (directive is ImportDirectiveImpl) {
- if (directive.augmentKeyword != null) {
- // TODO(scheglov) implement
- throw UnimplementedError();
- } else {
- _resolveImportDirective(
- directive: directive,
- importElement: _libraryElement.imports[importIndex],
- importState: _library.imports[importIndex],
- libraryErrorReporter: libraryErrorReporter,
- );
- importIndex++;
- }
+ _resolveImportDirective(
+ directive: directive,
+ importElement: _libraryElement.imports[importIndex],
+ importState: _library.imports[importIndex],
+ libraryErrorReporter: libraryErrorReporter,
+ );
+ importIndex++;
} else if (directive is ExportDirectiveImpl) {
_resolveExportDirective(
directive: directive,
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 7a61f73..463df80 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -875,6 +875,64 @@
}
}
+/// An augmentation import directive.
+///
+/// importDirective ::=
+/// [Annotation] 'import' 'augment' [StringLiteral] ';'
+class AugmentationImportDirectiveImpl extends UriBasedDirectiveImpl
+ implements AugmentationImportDirective {
+ @override
+ Token importKeyword;
+
+ @override
+ Token augmentKeyword;
+
+ @override
+ Token semicolon;
+
+ AugmentationImportDirectiveImpl({
+ required CommentImpl? comment,
+ required List<Annotation>? metadata,
+ required this.importKeyword,
+ required this.augmentKeyword,
+ required this.semicolon,
+ required StringLiteralImpl uri,
+ }) : super(comment, metadata, uri) {
+ _becomeParentOf(_uri);
+ }
+
+ @override
+ AugmentationImportElement? get element {
+ return super.element as AugmentationImportElement?;
+ }
+
+ @override
+ Token get endToken => semicolon;
+
+ @override
+ Token get firstTokenAfterCommentAndMetadata => keyword;
+
+ @override
+ Token get keyword => importKeyword;
+
+ @override
+ LibraryAugmentationElement? get uriElement {
+ return element?.augmentation;
+ }
+
+ @override
+ ChildEntities get _childEntities => super._childEntities
+ ..addToken('keyword', keyword)
+ ..addToken('augmentKeyword', augmentKeyword)
+ ..addNode('uri', uri)
+ ..addToken('semicolon', semicolon);
+
+ @override
+ E? accept<E>(AstVisitor<E> visitor) {
+ return visitor.visitAugmentationImportDirective(this);
+ }
+}
+
/// An await expression.
///
/// awaitExpression ::=
@@ -6311,10 +6369,6 @@
// [Combinator]* ';'
class ImportDirectiveImpl extends NamespaceDirectiveImpl
implements ImportDirective {
- /// The token representing the 'augment' keyword, or `null` if the import is
- /// not a library augmentation import.
- Token? augmentKeyword;
-
/// The token representing the 'deferred' keyword, or `null` if the imported
/// is not deferred.
@override
@@ -6339,7 +6393,6 @@
CommentImpl? comment,
List<Annotation>? metadata,
Token keyword,
- this.augmentKeyword,
StringLiteralImpl libraryUri,
List<Configuration>? configurations,
this.deferredKeyword,
@@ -6370,7 +6423,6 @@
@override
ChildEntities get _childEntities => super._childEntities
..addToken('keyword', keyword)
- ..addToken('augmentKeyword', augmentKeyword)
..addNode('uri', uri)
..addToken('deferredKeyword', deferredKeyword)
..addToken('asKeyword', asKeyword)
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 6bade88..0e45fe4 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -735,22 +735,21 @@
typeArgumentTypes: typeArgumentTypes);
ImportDirectiveImpl importDirective(
- Comment? comment,
- List<Annotation>? metadata,
- Token keyword,
- StringLiteral libraryUri,
- List<Configuration>? configurations,
- Token? deferredKeyword,
- Token? asKeyword,
- SimpleIdentifier? prefix,
- List<Combinator>? combinators,
- Token semicolon,
- {Token? augmentKeyword}) =>
+ Comment? comment,
+ List<Annotation>? metadata,
+ Token keyword,
+ StringLiteral libraryUri,
+ List<Configuration>? configurations,
+ Token? deferredKeyword,
+ Token? asKeyword,
+ SimpleIdentifier? prefix,
+ List<Combinator>? combinators,
+ Token semicolon,
+ ) =>
ImportDirectiveImpl(
comment as CommentImpl?,
metadata,
keyword,
- augmentKeyword,
libraryUri as StringLiteralImpl,
configurations,
deferredKeyword,
diff --git a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
index becc0af..5a83d20 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -78,6 +78,14 @@
}
@override
+ void visitAugmentationImportDirective(AugmentationImportDirective node) {
+ _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
+ sink.write('import augment ');
+ _visitNode(node.uri);
+ sink.write(';');
+ }
+
+ @override
void visitAwaitExpression(AwaitExpression node) {
sink.write('await ');
_visitNode(node.expression);
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index f024ba6..46b2fb6 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -162,6 +162,17 @@
}
@override
+ bool visitAugmentationImportDirective(AugmentationImportDirective node) {
+ final other = _other as AugmentationImportDirective;
+ return isEqualNodes(
+ node.documentationComment, other.documentationComment) &&
+ _isEqualNodeLists(node.metadata, other.metadata) &&
+ isEqualTokens(node.keyword, other.keyword) &&
+ isEqualNodes(node.uri, other.uri) &&
+ isEqualTokens(node.semicolon, other.semicolon);
+ }
+
+ @override
bool visitAwaitExpression(AwaitExpression node) {
AwaitExpression other = _other as AwaitExpression;
return isEqualTokens(node.awaitKeyword, other.awaitKeyword) &&
@@ -1698,6 +1709,13 @@
}
@override
+ bool visitAugmentationImportDirective(
+ covariant AugmentationImportDirectiveImpl node,
+ ) {
+ return visitUriBasedDirective(node);
+ }
+
+ @override
bool visitAwaitExpression(covariant AwaitExpressionImpl node) {
if (identical(node.expression, _oldNode)) {
node.expression = _newNode as Expression;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index a84eac9..b40172c 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1824,7 +1824,7 @@
var asKeyword = pop(NullValue.As) as Token?;
var prefix = pop(NullValue.Prefix) as SimpleIdentifier?;
var configurations = pop() as List<Configuration>?;
- var uri = pop() as StringLiteral;
+ var uri = pop() as StringLiteralImpl;
var metadata = pop() as List<Annotation>?;
var comment = _findComment(metadata, importKeyword);
@@ -1839,18 +1839,33 @@
}
}
- directives.add(ast.importDirective(
- comment,
- metadata,
- importKeyword,
- uri,
- configurations,
- deferredKeyword,
- asKeyword,
- prefix,
- combinators,
- semicolon ?? Tokens.semicolon(),
- augmentKeyword: augmentToken));
+ if (augmentToken != null) {
+ directives.add(
+ AugmentationImportDirectiveImpl(
+ comment: comment,
+ uri: uri,
+ importKeyword: importKeyword,
+ augmentKeyword: augmentToken,
+ metadata: metadata,
+ semicolon: semicolon ?? Tokens.semicolon(),
+ ),
+ );
+ } else {
+ directives.add(
+ ast.importDirective(
+ comment,
+ metadata,
+ importKeyword,
+ uri,
+ configurations,
+ deferredKeyword,
+ asKeyword,
+ prefix,
+ combinators,
+ semicolon ?? Tokens.semicolon(),
+ ),
+ );
+ }
}
@override
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 2c0aee8..e933186 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -55,6 +55,10 @@
return _node(search, (n) => n is AssignmentExpression);
}
+ AugmentationImportDirective augmentationImportDirective(String search) {
+ return _node(search, (n) => n is AugmentationImportDirective);
+ }
+
AwaitExpression awaitExpression(String search) {
return _node(search, (n) => n is AwaitExpression);
}
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 4db863b..711e8e8 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -277,6 +277,24 @@
);
}
+ void test_augmentationImportDirective() {
+ var findNode = _parseStringToFindNode(r'''
+@myA1
+@myA2
+import augment 'a.dart';
+import augment 'b.dart';
+''');
+ var node = findNode.augmentationImportDirective('a.dart');
+ _assertAnnotatedNode(node);
+ _assertReplacementForChildren<AugmentationImportDirective>(
+ destination: findNode.augmentationImportDirective('b.dart'),
+ source: node,
+ childAccessors: [
+ (node) => node.uri,
+ ],
+ );
+ }
+
void test_awaitExpression() {
var findNode = _parseStringToFindNode(r'''
void f() async {
diff --git a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
index 9a9a099..9fd743c 100644
--- a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
@@ -105,6 +105,16 @@
TokenType.EQ, AstTestFactory.identifier3("b")));
}
+ void test_visitAugmentationImportDirective() {
+ var findNode = _parseStringToFindNode(r'''
+import augment 'a.dart';
+''');
+ _assertSource(
+ "import augment 'a.dart';",
+ findNode.augmentationImportDirective('import'),
+ );
+ }
+
void test_visitAwaitExpression() {
var findNode = _parseStringToFindNode(r'''
void f() async => await e;