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

View file

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