Skip to content

Commit ee696f2

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
In flow analysis tests, annotate doesNotComplete on functions rather than bodies.
Change-Id: I40476db016fd153ea4a013bcaa452775bcd960d6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108266 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent c1ca599 commit ee696f2

File tree

4 files changed

+64
-27
lines changed

4 files changed

+64
-27
lines changed

pkg/analyzer/lib/src/util/ast_data_extractor.dart

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
import 'package:analyzer/dart/ast/ast.dart';
66
import 'package:analyzer/dart/ast/visitor.dart';
7+
import 'package:analyzer/dart/element/element.dart';
78
import 'package:front_end/src/testing/id.dart'
8-
show ActualData, DataRegistry, Id, IdKind, NodeId;
9+
show ActualData, DataRegistry, Id, IdKind, MemberId, NodeId;
910

1011
/// Abstract IR visitor for computing data corresponding to a node or element,
1112
/// and record it with a generic [Id]
@@ -29,7 +30,7 @@ abstract class AstDataExtractor<T> extends GeneralizingAstVisitor<dynamic>
2930
registerValue(uri, node.offset, id, value, node);
3031
}
3132

32-
void computeForFunctionBody(FunctionBody node, NodeId id) {
33+
void computeForMember(Declaration node, Id id) {
3334
if (id == null) return;
3435
T value = computeNodeValue(id, node);
3536
registerValue(uri, node.offset, id, value, node);
@@ -46,8 +47,18 @@ abstract class AstDataExtractor<T> extends GeneralizingAstVisitor<dynamic>
4647
/// If `null` is returned, [node] has no associated data.
4748
T computeNodeValue(Id id, AstNode node);
4849

49-
NodeId createFunctionBodyId(FunctionBody node) =>
50-
NodeId(_nodeOffset(node), IdKind.functionBody);
50+
Id createMemberId(Declaration node) {
51+
var element = node.declaredElement;
52+
if (element.enclosingElement is CompilationUnitElement) {
53+
var memberName = element.name;
54+
if (element is PropertyAccessorElement && element.isSetter) {
55+
memberName += '=';
56+
}
57+
return MemberId.internal(memberName);
58+
}
59+
throw UnimplementedError(
60+
'TODO(paulberry): $element (${element.runtimeType})');
61+
}
5162

5263
NodeId createStatementId(Statement node) =>
5364
NodeId(_nodeOffset(node), IdKind.statement);
@@ -74,9 +85,11 @@ abstract class AstDataExtractor<T> extends GeneralizingAstVisitor<dynamic>
7485
}
7586

7687
@override
77-
visitFunctionBody(FunctionBody node) {
78-
computeForFunctionBody(node, createFunctionBodyId(node));
79-
super.visitFunctionBody(node);
88+
visitFunctionDeclaration(FunctionDeclaration node) {
89+
if (node.parent is CompilationUnit) {
90+
computeForMember(node, createMemberId(node));
91+
}
92+
return super.visitFunctionDeclaration(node);
8093
}
8194

8295
@override

pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,8 @@ void f() {
352352

353353
test_do_true() async {
354354
await trackCode(r'''
355-
void f() /*functionBody: doesNotComplete*/ {
355+
/*member: f:doesNotComplete*/
356+
void f() {
356357
do {
357358
1;
358359
} while (true);
@@ -363,7 +364,8 @@ void f() /*functionBody: doesNotComplete*/ {
363364

364365
test_exit_beforeSplitStatement() async {
365366
await trackCode(r'''
366-
void f(bool b, int i) /*functionBody: doesNotComplete*/ {
367+
/*member: f:doesNotComplete*/
368+
void f(bool b, int i) {
367369
return;
368370
/*statement: unreachable*/ Object _;
369371
/*statement: unreachable*/ do {} while (b);
@@ -379,7 +381,8 @@ void f(bool b, int i) /*functionBody: doesNotComplete*/ {
379381

380382
test_for_condition_true() async {
381383
await trackCode(r'''
382-
void f() /*functionBody: doesNotComplete*/ {
384+
/*member: f:doesNotComplete*/
385+
void f() {
383386
for (; true;) {
384387
1;
385388
}
@@ -390,7 +393,8 @@ void f() /*functionBody: doesNotComplete*/ {
390393

391394
test_for_condition_true_implicit() async {
392395
await trackCode(r'''
393-
void f() /*functionBody: doesNotComplete*/ {
396+
/*member: f:doesNotComplete*/
397+
void f() {
394398
for (;;) {
395399
1;
396400
}
@@ -414,7 +418,8 @@ void f() {
414418

415419
test_functionBody_hasReturn() async {
416420
await trackCode(r'''
417-
int f() /*functionBody: doesNotComplete*/ {
421+
/*member: f:doesNotComplete*/
422+
int f() {
418423
return 42;
419424
}
420425
''');
@@ -455,7 +460,8 @@ void f() {
455460

456461
test_if_true_return() async {
457462
await trackCode(r'''
458-
void f() /*functionBody: doesNotComplete*/ {
463+
/*member: f:doesNotComplete*/
464+
void f() {
459465
1;
460466
if (true) {
461467
return;
@@ -572,7 +578,8 @@ void f() {
572578

573579
test_tryCatchFinally_return_bodyCatch() async {
574580
await trackCode(r'''
575-
void f() /*functionBody: doesNotComplete*/ {
581+
/*member: f:doesNotComplete*/
582+
void f() {
576583
try {
577584
1;
578585
return;
@@ -605,7 +612,8 @@ void f() {
605612

606613
test_tryFinally_return_body() async {
607614
await trackCode(r'''
608-
void f() /*functionBody: doesNotComplete*/ {
615+
/*member: f:doesNotComplete*/
616+
void f() {
609617
try {
610618
1;
611619
return;
@@ -630,7 +638,8 @@ void f() {
630638

631639
test_while_true() async {
632640
await trackCode(r'''
633-
void f() /*functionBody: doesNotComplete*/ {
641+
/*member: f:doesNotComplete*/
642+
void f() {
634643
while (true) {
635644
1;
636645
}
@@ -668,7 +677,8 @@ void f(bool b) {
668677

669678
test_while_true_continue() async {
670679
await trackCode(r'''
671-
void f() /*functionBody: doesNotComplete*/ {
680+
/*member: f:doesNotComplete*/
681+
void f() {
672682
while (true) {
673683
1;
674684
continue;
@@ -724,8 +734,12 @@ class _FlowAnalysisDataExtractor extends AstDataExtractor<Set<_FlowAssertion>> {
724734
if (_flowResult.unreachableNodes.contains(node)) {
725735
result.add(_FlowAssertion.unreachable);
726736
}
727-
if (_flowResult.functionBodiesThatDontComplete.contains(node)) {
728-
result.add(_FlowAssertion.doesNotComplete);
737+
if (node is FunctionDeclaration) {
738+
var body = node.functionExpression.body;
739+
if (body != null &&
740+
_flowResult.functionBodiesThatDontComplete.contains(body)) {
741+
result.add(_FlowAssertion.doesNotComplete);
742+
}
729743
}
730744
return result.isEmpty ? null : result;
731745
}

pkg/analyzer/test/util/id_equivalence_helper.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
// dart2js.
1010

1111
import 'package:analyzer/dart/analysis/results.dart';
12+
import 'package:analyzer/dart/analysis/utilities.dart';
1213
import 'package:analyzer/dart/ast/ast.dart' hide Annotation;
1314
import 'package:front_end/src/testing/id.dart'
14-
show ActualData, Id, IdValue, NodeId;
15+
show ActualData, Id, IdValue, MemberId, NodeId;
1516
import 'package:sourcemap_testing/src/annotated_code_helper.dart';
1617

1718
/// Checks [compiledData] against the expected data in [expectedMap] derived
@@ -395,6 +396,22 @@ class IdData<T> {
395396
int getOffsetFromId(Id id, Uri uri) {
396397
if (id is NodeId) {
397398
return id.value;
399+
} else if (id is MemberId) {
400+
if (id.className != null) {
401+
throw UnimplementedError('TODO(paulberry): handle class members');
402+
}
403+
var name = id.memberName;
404+
var unit =
405+
parseString(content: code[uri].sourceCode, throwIfDiagnostics: false)
406+
.unit;
407+
for (var declaration in unit.declarations) {
408+
if (declaration is FunctionDeclaration) {
409+
if (declaration.name.name == name) {
410+
return declaration.offset;
411+
}
412+
}
413+
}
414+
throw StateError('Member not found: $name');
398415
} else {
399416
throw StateError('Unexpected id ${id.runtimeType}');
400417
}

pkg/front_end/lib/src/testing/id.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ enum IdKind {
1212
current,
1313
moveNext,
1414
statement,
15-
functionBody,
1615
}
1716

1817
/// Id for a code point or element.
@@ -65,8 +64,6 @@ class IdValue {
6564
return '$moveNextPrefix$value';
6665
case IdKind.statement:
6766
return '$statementPrefix$value';
68-
case IdKind.functionBody:
69-
return '$functionBodyPrefix$value';
7067
}
7168
throw new UnsupportedError("Unexpected id kind: ${id.kind}");
7269
}
@@ -80,7 +77,6 @@ class IdValue {
8077
static const String currentPrefix = "current: ";
8178
static const String moveNextPrefix = "moveNext: ";
8279
static const String statementPrefix = "statement: ";
83-
static const String functionBodyPrefix = "functionBody: ";
8480

8581
static IdValue decode(int offset, String text) {
8682
Id id;
@@ -125,9 +121,6 @@ class IdValue {
125121
} else if (text.startsWith(statementPrefix)) {
126122
id = new NodeId(offset, IdKind.statement);
127123
expected = text.substring(statementPrefix.length);
128-
} else if (text.startsWith(functionBodyPrefix)) {
129-
id = new NodeId(offset, IdKind.functionBody);
130-
expected = text.substring(functionBodyPrefix.length);
131124
} else {
132125
id = new NodeId(offset, IdKind.node);
133126
expected = text;

0 commit comments

Comments
 (0)