Simplify implementation of FindNode.singleX getters.

Change-Id: I434cf2371dee4269747b21413d6d15cbd4fa4e3c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/287672
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-03-09 17:00:48 +00:00 committed by Commit Queue
parent b16acf4f35
commit 04f7a2a910
3 changed files with 37 additions and 133 deletions

View file

@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/test_utilities/function_ast_visitor.dart';
@ -13,11 +14,6 @@ class FindNode {
FindNode(this.content, this.unit);
LibraryDirective get libraryDirective {
return unit.directives.singleWhere((d) => d is LibraryDirective)
as LibraryDirective;
}
List<MethodInvocation> get methodInvocations {
var result = <MethodInvocation>[];
unit.accept(
@ -28,143 +24,30 @@ class FindNode {
return result;
}
/// Returns the [Block], there must be only one.
Block get singleBlock {
var nodes = <Block>[];
unit.accept(
FunctionAstVisitor(
block: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
Block get singleBlock => _single();
/// Returns the [ForElement], there must be only one.
ForElement get singleForElement {
var nodes = <ForElement>[];
unit.accept(
FunctionAstVisitor(
forElement: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
ForElement get singleForElement => _single();
/// Returns the [ForStatement], there must be only one.
ForStatement get singleForStatement {
var nodes = <ForStatement>[];
unit.accept(
FunctionAstVisitor(
forStatement: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
ForStatement get singleForStatement => _single();
/// Returns the [GuardedPattern], there must be only one.
GuardedPattern get singleGuardedPattern {
var nodes = <GuardedPattern>[];
unit.accept(
FunctionAstVisitor(
guardedPattern: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
GuardedPattern get singleGuardedPattern => _single();
/// Returns the [IfElement], there must be only one.
IfElement get singleIfElement {
var nodes = <IfElement>[];
unit.accept(
FunctionAstVisitor(
ifElement: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
IfElement get singleIfElement => _single();
/// Returns the [IfStatement], there must be only one.
IfStatement get singleIfStatement {
var nodes = <IfStatement>[];
unit.accept(
FunctionAstVisitor(
ifStatement: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
IfStatement get singleIfStatement => _single();
/// Returns the [PatternAssignment], there must be only one.
PatternAssignment get singlePatternAssignment {
var nodes = <PatternAssignment>[];
unit.accept(
FunctionAstVisitor(
patternAssignment: nodes.add,
),
);
return nodes.single;
}
LibraryDirective get singleLibraryDirective => _single();
/// Returns the [PatternVariableDeclaration], there must be only one.
PatternVariableDeclaration get singlePatternVariableDeclaration {
var nodes = <PatternVariableDeclaration>[];
unit.accept(
FunctionAstVisitor(
patternVariableDeclaration: nodes.add,
),
);
return nodes.single;
}
PatternAssignment get singlePatternAssignment => _single();
PatternVariableDeclaration get singlePatternVariableDeclaration => _single();
/// Returns the [PatternVariableDeclarationStatement], there must be only one.
PatternVariableDeclarationStatement
get singlePatternVariableDeclarationStatement {
var nodes = <PatternVariableDeclarationStatement>[];
unit.accept(
FunctionAstVisitor(
patternVariableDeclarationStatement: nodes.add,
),
);
return nodes.single;
}
get singlePatternVariableDeclarationStatement => _single();
/// Returns the [SwitchExpression], there must be only one.
SwitchExpression get singleSwitchExpression {
var nodes = <SwitchExpression>[];
unit.accept(
FunctionAstVisitor(
switchExpression: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
SwitchExpression get singleSwitchExpression => _single();
/// Returns the [SwitchPatternCase], there must be only one.
SwitchPatternCase get singleSwitchPatternCase {
var nodes = <SwitchPatternCase>[];
unit.accept(
FunctionAstVisitor(
switchPatternCase: (node) {
nodes.add(node);
},
),
);
return nodes.single;
}
SwitchPatternCase get singleSwitchPatternCase => _single();
AdjacentStrings adjacentStrings(String search) {
return _node(search, (n) => n is AdjacentStrings);
@ -889,4 +772,25 @@ class FindNode {
}
return result as T;
}
/// If [unit] has exactly one node of type [T], returns it.
/// Otherwise, throws.
T _single<T extends AstNode>() {
final visitor = _TypedNodeVisitor<T>();
unit.accept(visitor);
return visitor.nodes.single;
}
}
class _TypedNodeVisitor<T extends AstNode>
extends GeneralizingAstVisitor<void> {
final List<T> nodes = [];
@override
void visitNode(AstNode node) {
if (node is T) {
nodes.add(node);
}
super.visitNode(node);
}
}

View file

@ -1266,7 +1266,7 @@ void f() {
@myA2
library foo;
''');
var node = findNode.libraryDirective;
var node = findNode.singleLibraryDirective;
_assertAnnotatedNode(node);
_assertReplacementForChildren<LibraryDirective>(
destination: node,

View file

@ -230,7 +230,7 @@ const a = 1;
''');
await resolveTestFile();
var directive = findNode.libraryDirective;
var directive = findNode.singleLibraryDirective;
expect(directive.metadata, hasLength(1));
Annotation annotation = directive.metadata[0];