Move a few ForStatement tests.
Change-Id: I972f9162d456c1a62c6bf9a7b5e645a52a214ae7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/266444
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 2dc19b0..80629df 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -4113,67 +4113,6 @@
@reflectiveTest
class StrongModeTypePropagationTest extends PubPackageResolutionTest {
- test_foreachInference_dynamic_disabled() async {
- await resolveTestCode(r'''
-main() {
- var list = <int>[];
- for (dynamic v in list) {
- v; // marker
- }
-}''');
- assertTypeDynamic(findElement.localVar('v').type);
- assertTypeDynamic(findNode.simple('v; // marker'));
- }
-
- test_foreachInference_reusedVar_disabled() async {
- await resolveTestCode(r'''
-main() {
- var list = <int>[];
- var v;
- for (v in list) {
- v; // marker
- }
-}''');
- assertTypeDynamic(findNode.simple('v in'));
- assertTypeDynamic(findNode.simple('v; // marker'));
- }
-
- test_foreachInference_var() async {
- await resolveTestCode(r'''
-main() {
- var list = <int>[];
- for (var v in list) {
- v; // marker
- }
-}''');
- assertType(findElement.localVar('v').type, 'int');
- assertType(findNode.simple('v; // marker'), 'int');
- }
-
- test_foreachInference_var_iterable() async {
- await resolveTestCode(r'''
-main() {
- Iterable<int> list = <int>[];
- for (var v in list) {
- v; // marker
- }
-}''');
- assertType(findElement.localVar('v').type, 'int');
- assertType(findNode.simple('v; // marker'), 'int');
- }
-
- test_foreachInference_var_stream() async {
- await resolveTestCode(r'''
-main() async {
- Stream<int> stream = null;
- await for (var v in stream) {
- v; // marker
- }
-}''');
- assertType(findElement.localVar('v').type, 'int');
- assertType(findNode.simple('v; // marker'), 'int');
- }
-
test_inconsistentMethodInheritance_inferFunctionTypeFromTypedef() async {
await assertNoErrorsInCode(r'''
typedef bool F<E>(E argument);
diff --git a/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart b/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart
index 447418d..874a2d3 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart
@@ -9,33 +9,61 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(ForEachStatementResolutionTest);
- defineReflectiveTests(ForLoopStatementResolutionTest);
+ defineReflectiveTests(
+ ForStatement_ForEachPartsWithDeclaration_ResolutionTest);
+ defineReflectiveTests(
+ ForStatement_ForEachPartsWithIdentifier_ResolutionTest);
+ defineReflectiveTests(ForStatement_ForParts_ResolutionTest);
});
}
/// TODO(scheglov) Move other for-in tests here.
@reflectiveTest
-class ForEachStatementResolutionTest extends PubPackageResolutionTest {
- test_forIn_variable() async {
- var code = r'''
-T f<T>() => null;
-
-void test(Iterable<num> iter) {
- for (var w in f()) {} // 1
- for (var x in iter) {} // 2
- for (num y in f()) {} // 3
+class ForStatement_ForEachPartsWithDeclaration_ResolutionTest
+ extends PubPackageResolutionTest {
+ test_iterable_contextType() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ for (int v in g()) {}
}
-''';
- await resolveTestCode(code);
- assertType(findElement.localVar('w').type, 'Object?');
- assertType(findNode.methodInvocation('f()) {} // 1'), 'Iterable<Object?>');
+T g<T>() => throw 0;
+''');
- assertType(findElement.localVar('x').type, 'num');
-
- assertType(findElement.localVar('y').type, 'num');
- assertType(findNode.methodInvocation('f()) {} // 3'), 'Iterable<num>');
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ type: NamedType
+ name: SimpleIdentifier
+ token: int
+ staticElement: dart:core::@class::int
+ staticType: null
+ type: int
+ name: v
+ declaredElement: v@56
+ inKeyword: in
+ iterable: MethodInvocation
+ methodName: SimpleIdentifier
+ token: g
+ staticElement: self::@function::g
+ staticType: T Function<T>()
+ argumentList: ArgumentList
+ leftParenthesis: (
+ rightParenthesis: )
+ staticInvokeType: Iterable<int> Function()
+ staticType: Iterable<int>
+ typeArgumentTypes
+ Iterable<int>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ rightBracket: }
+''');
}
test_iterable_missing() async {
@@ -49,8 +77,225 @@
error(ParserErrorCode.MISSING_IDENTIFIER, 26, 1),
]);
- assertType(findElement.localVar('v').type, 'dynamic');
- assertType(findNode.simple('v;'), 'dynamic');
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ keyword: var
+ name: v
+ declaredElement: v@22
+ inKeyword: in
+ iterable: SimpleIdentifier
+ token: <empty> <synthetic>
+ staticElement: <null>
+ staticType: dynamic
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ statements
+ ExpressionStatement
+ expression: SimpleIdentifier
+ token: v
+ staticElement: v@22
+ staticType: dynamic
+ semicolon: ;
+ rightBracket: }
+''');
+ }
+
+ test_loopVariable_dynamic() async {
+ await resolveTestCode(r'''
+void f(List<int> values) {
+ for (dynamic v in values) {
+ v;
+ }
+}''');
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ type: NamedType
+ name: SimpleIdentifier
+ token: dynamic
+ staticElement: dynamic@-1
+ staticType: null
+ type: dynamic
+ name: v
+ declaredElement: v@42
+ inKeyword: in
+ iterable: SimpleIdentifier
+ token: values
+ staticElement: self::@function::f::@parameter::values
+ staticType: List<int>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ statements
+ ExpressionStatement
+ expression: SimpleIdentifier
+ token: v
+ staticElement: v@42
+ staticType: dynamic
+ semicolon: ;
+ rightBracket: }
+''');
+ }
+
+ test_loopVariable_var_genericFunction() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ for (var v in g()) {}
+}
+
+T g<T>() => throw 0;
+''');
+
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ keyword: var
+ name: v
+ declaredElement: v@56
+ inKeyword: in
+ iterable: MethodInvocation
+ methodName: SimpleIdentifier
+ token: g
+ staticElement: self::@function::g
+ staticType: T Function<T>()
+ argumentList: ArgumentList
+ leftParenthesis: (
+ rightParenthesis: )
+ staticInvokeType: Iterable<Object?> Function()
+ staticType: Iterable<Object?>
+ typeArgumentTypes
+ Iterable<Object?>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ rightBracket: }
+''');
+ }
+
+ test_loopVariable_var_iterable() async {
+ await resolveTestCode(r'''
+void f(Iterable<int> values) {
+ for (var v in values) {
+ v;
+ }
+}
+''');
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ keyword: var
+ name: v
+ declaredElement: v@42
+ inKeyword: in
+ iterable: SimpleIdentifier
+ token: values
+ staticElement: self::@function::f::@parameter::values
+ staticType: Iterable<int>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ statements
+ ExpressionStatement
+ expression: SimpleIdentifier
+ token: v
+ staticElement: v@42
+ staticType: int
+ semicolon: ;
+ rightBracket: }
+''');
+ }
+
+ test_loopVariable_var_list() async {
+ await resolveTestCode(r'''
+void f(List<int> values) {
+ for (var v in values) {
+ v;
+ }
+}
+''');
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ keyword: var
+ name: v
+ declaredElement: v@38
+ inKeyword: in
+ iterable: SimpleIdentifier
+ token: values
+ staticElement: self::@function::f::@parameter::values
+ staticType: List<int>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ statements
+ ExpressionStatement
+ expression: SimpleIdentifier
+ token: v
+ staticElement: v@38
+ staticType: int
+ semicolon: ;
+ rightBracket: }
+''');
+ }
+
+ test_loopVariable_var_stream() async {
+ await resolveTestCode(r'''
+void f(Stream<int> values) async {
+ await for (var v in values) {
+ v;
+ }
+}''');
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ awaitKeyword: await
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ keyword: var
+ name: v
+ declaredElement: v@52
+ inKeyword: in
+ iterable: SimpleIdentifier
+ token: values
+ staticElement: self::@function::f::@parameter::values
+ staticType: Stream<int>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ statements
+ ExpressionStatement
+ expression: SimpleIdentifier
+ token: v
+ staticElement: v@52
+ staticType: int
+ semicolon: ;
+ rightBracket: }
+''');
}
/// Test that the parameter `x` is in the scope of the iterable.
@@ -58,21 +303,50 @@
test_scope() async {
await assertNoErrorsInCode('''
void f(List<List<int>> x) {
- for (int x in x.first) {
- x.isEven;
+ for (var x in x.first) {
+ x;
}
}
''');
-
- assertElement(
- findNode.simpleFormalParameter('x) {'),
- findElement.parameter('x'),
- );
-
- assertElement(
- findNode.simple('x.isEven'),
- findElement.localVar('x'),
- );
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithDeclaration
+ loopVariable: DeclaredIdentifier
+ keyword: var
+ name: x
+ declaredElement: x@39
+ inKeyword: in
+ iterable: PrefixedIdentifier
+ prefix: SimpleIdentifier
+ token: x
+ staticElement: self::@function::f::@parameter::x
+ staticType: List<List<int>>
+ period: .
+ identifier: SimpleIdentifier
+ token: first
+ staticElement: PropertyAccessorMember
+ base: dart:core::@class::Iterable::@getter::first
+ substitution: {E: List<int>, E: List<int>}
+ staticType: List<int>
+ staticElement: PropertyAccessorMember
+ base: dart:core::@class::Iterable::@getter::first
+ substitution: {E: List<int>, E: List<int>}
+ staticType: List<int>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ statements
+ ExpressionStatement
+ expression: SimpleIdentifier
+ token: x
+ staticElement: x@39
+ staticType: int
+ semicolon: ;
+ rightBracket: }
+''');
}
test_type_genericFunctionType() async {
@@ -84,23 +358,51 @@
}
''');
}
+}
- test_type_inferred() async {
- await assertNoErrorsInCode(r'''
-void f(List<int> a) {
- for (var v in a) {
+@reflectiveTest
+class ForStatement_ForEachPartsWithIdentifier_ResolutionTest
+ extends PubPackageResolutionTest {
+ test_identifier_dynamic() async {
+ await resolveTestCode(r'''
+void f(var v, List<int> values) {
+ for (v in values) {
v;
}
}
''');
-
- assertType(findElement.localVar('v').type, 'int');
- assertType(findNode.simple('v;'), 'int');
+ var node = findNode.forStatement('for');
+ assertResolvedNodeText(node, r'''
+ForStatement
+ forKeyword: for
+ leftParenthesis: (
+ forLoopParts: ForEachPartsWithIdentifier
+ identifier: SimpleIdentifier
+ token: v
+ staticElement: self::@function::f::@parameter::v
+ staticType: dynamic
+ inKeyword: in
+ iterable: SimpleIdentifier
+ token: values
+ staticElement: self::@function::f::@parameter::values
+ staticType: List<int>
+ rightParenthesis: )
+ body: Block
+ leftBracket: {
+ statements
+ ExpressionStatement
+ expression: SimpleIdentifier
+ token: v
+ staticElement: self::@function::f::@parameter::v
+ staticType: dynamic
+ semicolon: ;
+ rightBracket: }
+''');
}
}
@reflectiveTest
-class ForLoopStatementResolutionTest extends PubPackageResolutionTest {
+class ForStatement_ForParts_ResolutionTest extends PubPackageResolutionTest {
test_condition_rewrite() async {
await assertNoErrorsInCode(r'''
f(bool Function() b) {