blob: b00bbab2d31f82245e6ad05ff766574092e2581a [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../driver_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(FunctionExpressionTest);
defineReflectiveTests(FunctionExpressionWithNnbdTest);
});
}
@reflectiveTest
class FunctionExpressionTest extends DriverResolutionTest {
test_downward_argumentType_Never() async {
await assertNoErrorsInCode(r'''
void foo(void Function(Never) a) {}
main() {
foo((x) {});
}
''');
assertParameterElementType(
findNode.simpleParameter('x) {}'),
typeStringByNullability(
nullable: 'Object?',
legacy: 'Object',
),
);
}
test_downward_argumentType_Null() async {
await resolveTestCode(r'''
void foo(void Function(Null) a) {}
main() {
foo((x) {});
}
''');
assertParameterElementType(
findNode.simpleParameter('x) {}'),
typeStringByNullability(
nullable: 'Object?',
legacy: 'Object',
),
);
}
test_returnType_blockBody_notNullable() async {
await resolveTestCode('''
var v = (bool b) {
if (b) return 0;
return 1.2;
};
''');
var element = findNode.functionExpression('(bool').declaredElement;
assertType(element.returnType, 'num');
}
test_returnType_blockBody_notNullable_switch_onEnum() async {
var expectedErrors = expectedErrorsByNullability(
nullable: [],
legacy: [
error(HintCode.MISSING_RETURN, 28, 102),
],
);
await assertErrorsInCode('''
enum E { a, b }
main() {
(E e) {
switch (e) {
case E.a:
return 0;
case E.b:
return 1;
}
};
}
''', expectedErrors);
var element = findNode.functionExpression('(E e)').declaredElement;
assertType(element.returnType, 'int');
}
test_returnType_blockBody_notNullable_switch_onEnum_imported() async {
newFile('/test/lib/a.dart', content: r'''
enum E { a, b }
''');
var expectedErrors = expectedErrorsByNullability(
nullable: [],
legacy: [
error(HintCode.MISSING_RETURN, 34, 108),
],
);
await assertErrorsInCode('''
import 'a.dart' as p;
main() {
(p.E e) {
switch (e) {
case p.E.a:
return 0;
case p.E.b:
return 1;
}
};
}
''', expectedErrors);
var element = findNode.functionExpression('(p.E e)').declaredElement;
assertType(element.returnType, 'int');
}
test_returnType_blockBody_null_hasReturn() async {
await resolveTestCode('''
var v = (bool b) {
if (b) return;
};
''');
var element = findNode.functionExpression('(bool').declaredElement;
assertType(element.returnType, 'Null');
}
test_returnType_blockBody_null_noReturn() async {
await resolveTestCode('''
var v = () {};
''');
var element = findNode.functionExpression('() {}').declaredElement;
assertType(element.returnType, 'Null');
}
test_returnType_blockBody_nullable() async {
await resolveTestCode('''
var v = (bool b) {
if (b) return 0;
};
''');
var element = findNode.functionExpression('(bool').declaredElement;
assertType(
element.returnType,
typeStringByNullability(nullable: 'int?', legacy: 'int'),
);
}
test_returnType_blockBody_nullable_switch() async {
var expectedErrors = expectedErrorsByNullability(
nullable: [],
legacy: [
error(HintCode.MISSING_RETURN, 11, 68),
],
);
await assertErrorsInCode('''
main() {
(int a) {
switch (a) {
case 0:
return 0;
}
};
}
''', expectedErrors);
var element = findNode.functionExpression('(int a)').declaredElement;
assertType(
element.returnType,
typeStringByNullability(nullable: 'int?', legacy: 'int'),
);
}
test_returnType_expressionBody_Never() async {
await resolveTestCode('''
var v = () => throw 42;
''');
var element = findNode.functionExpression('() =>').declaredElement;
assertType(
element.returnType,
typeStringByNullability(nullable: 'Never', legacy: 'Null'),
);
}
test_returnType_expressionBody_notNullable() async {
await resolveTestCode('''
var v = () => 42;
''');
var element = findNode.functionExpression('() =>').declaredElement;
assertType(element.returnType, 'int');
}
test_returnType_expressionBody_Null() async {
await resolveTestCode('''
var v = () => null;
''');
var element = findNode.functionExpression('() =>').declaredElement;
assertType(element.returnType, 'Null');
}
}
@reflectiveTest
class FunctionExpressionWithNnbdTest extends FunctionExpressionTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
..contextFeatures = FeatureSet.forTesting(
sdkVersion: '2.6.0', additionalFeatures: [Feature.non_nullable]);
@override
bool get typeToStringWithNullability => true;
}