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>
This commit is contained in:
Konstantin Shcheglov 2022-10-28 19:10:48 +00:00 committed by Commit Queue
parent bf9c703186
commit ce591144b0
2 changed files with 343 additions and 102 deletions

View file

@ -4113,67 +4113,6 @@ main() {
@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);

View file

@ -9,33 +9,61 @@ import 'context_collection_resolution.dart';
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 @@ void f() {
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 @@ void f() {
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 @@ void f() {
}
''');
}
}
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) {