From 119eed6f933f8d1719b4acfad04904bd22fdd33f Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 10 Feb 2022 04:21:11 +0000 Subject: [PATCH 1/4] Make top-level accessors static. Change-Id: I28449a218b7613e920c38de57d7eb6d18f8c6176 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232231 Reviewed-by: Samuel Rawlins Commit-Queue: Konstantin Shcheglov --- .../lib/src/dart/element/element.dart | 49 +++-------- .../error/getter_setter_types_verifier.dart | 5 +- .../lib/src/summary2/element_builder.dart | 3 + .../lib/src/summary2/element_flags.dart | 3 + .../test/src/summary/element_text.dart | 2 + .../test/src/summary/resynthesize_common.dart | 82 +++++++++---------- .../src/summary/top_level_inference_test.dart | 2 +- 7 files changed, 64 insertions(+), 82 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 681ae4453b932..7179b6099b22b 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -1364,9 +1364,6 @@ class ConstructorElementImpl extends ExecutableElementImpl setModifier(Modifier.FACTORY, isFactory); } - @override - bool get isStatic => false; - @override ElementKind get kind => ElementKind.CONSTRUCTOR; @@ -2879,6 +2876,15 @@ abstract class ExecutableElementImpl extends _ExistingElementImpl @override bool get isOperator => false; + @override + bool get isStatic { + return hasModifier(Modifier.STATIC); + } + + set isStatic(bool isStatic) { + setModifier(Modifier.STATIC, isStatic); + } + @override bool get isSynchronous => !isAsynchronous; @@ -3250,16 +3256,6 @@ class FieldElementImpl extends PropertyInducingElementImpl return hasModifier(Modifier.EXTERNAL); } - @override - bool get isStatic { - return hasModifier(Modifier.STATIC); - } - - /// Set whether this field is static. - set isStatic(bool isStatic) { - setModifier(Modifier.STATIC, isStatic); - } - /// Return `true` if this element is a synthetic enum field. /// /// It is synthetic because it is not written explicitly in code, but it @@ -3352,9 +3348,6 @@ class FunctionElementImpl extends ExecutableElementImpl return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME; } - @override - bool get isStatic => enclosingElement is CompilationUnitElement; - @override ElementKind get kind => ElementKind.FUNCTION; @@ -4208,16 +4201,6 @@ class MethodElementImpl extends ExecutableElementImpl implements MethodElement { first == 0x24); } - @override - bool get isStatic { - return hasModifier(Modifier.STATIC); - } - - /// Set whether this method is static. - set isStatic(bool isStatic) { - setModifier(Modifier.STATIC, isStatic); - } - @override ElementKind get kind => ElementKind.METHOD; @@ -5047,16 +5030,6 @@ class PropertyAccessorElementImpl extends ExecutableElementImpl setModifier(Modifier.SETTER, isSetter); } - @override - bool get isStatic { - return hasModifier(Modifier.STATIC); - } - - /// Set whether this accessor is static. - set isStatic(bool isStatic) { - setModifier(Modifier.STATIC, isStatic); - } - @override ElementKind get kind { if (isGetter) { @@ -5931,6 +5904,10 @@ abstract class VariableElementImpl extends ElementImpl @override bool get isStatic => hasModifier(Modifier.STATIC); + set isStatic(bool isStatic) { + setModifier(Modifier.STATIC, isStatic); + } + @override String get name => super.name!; diff --git a/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart b/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart index e0e84d6c22187..f8354146a3314 100644 --- a/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart +++ b/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart @@ -86,10 +86,7 @@ class GetterSetterTypesVerifier { void checkStaticAccessors(List accessors) { for (var getter in accessors) { - // TODO(scheglov) Update `isStatic` instead - if ((getter.isStatic || - getter.enclosingElement is CompilationUnitElement) && - getter.isGetter) { + if (getter.isStatic && getter.isGetter) { _checkLocalGetter(getter); } } diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart index 892c2fb335c81..33303078621de 100644 --- a/pkg/analyzer/lib/src/summary2/element_builder.dart +++ b/pkg/analyzer/lib/src/summary2/element_builder.dart @@ -564,6 +564,7 @@ class ElementBuilder extends ThrowingAstVisitor { if (node.isGetter) { var element = PropertyAccessorElementImpl(name, nameOffset); element.isGetter = true; + element.isStatic = true; reference = _enclosingContext.addGetter(name, element); executableElement = element; @@ -572,6 +573,7 @@ class ElementBuilder extends ThrowingAstVisitor { } else if (node.isSetter) { var element = PropertyAccessorElementImpl(name, nameOffset); element.isSetter = true; + element.isStatic = true; reference = _enclosingContext.addSetter(name, element); executableElement = element; @@ -579,6 +581,7 @@ class ElementBuilder extends ThrowingAstVisitor { _buildSyntheticVariable(name: name, accessorElement: element); } else { var element = FunctionElementImpl(name, nameOffset); + element.isStatic = true; reference = _enclosingContext.addFunction(name, element); executableElement = element; } diff --git a/pkg/analyzer/lib/src/summary2/element_flags.dart b/pkg/analyzer/lib/src/summary2/element_flags.dart index ff4cdbc94d1e8..201c671871249 100644 --- a/pkg/analyzer/lib/src/summary2/element_flags.dart +++ b/pkg/analyzer/lib/src/summary2/element_flags.dart @@ -119,6 +119,7 @@ class FunctionElementFlags { static const int _isAsynchronous = 1 << 1; static const int _isExternal = 1 << 2; static const int _isGenerator = 1 << 3; + static const int _isStatic = 1 << 4; static void read(SummaryDataReader reader, FunctionElementImpl element) { var byte = reader.readByte(); @@ -126,6 +127,7 @@ class FunctionElementFlags { element.isAsynchronous = (byte & _isAsynchronous) != 0; element.isExternal = (byte & _isExternal) != 0; element.isGenerator = (byte & _isGenerator) != 0; + element.isStatic = (byte & _isStatic) != 0; } static void write(BufferedSink sink, FunctionElementImpl element) { @@ -134,6 +136,7 @@ class FunctionElementFlags { result |= element.isAsynchronous ? _isAsynchronous : 0; result |= element.isExternal ? _isExternal : 0; result |= element.isGenerator ? _isGenerator : 0; + result |= element.isStatic ? _isStatic : 0; sink.writeByte(result); } } diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart index 09f2671fd0db8..4fda1a5f9b66b 100644 --- a/pkg/analyzer/test/src/summary/element_text.dart +++ b/pkg/analyzer/test/src/summary/element_text.dart @@ -508,6 +508,8 @@ class _ElementWriter { } void _writeFunctionElement(FunctionElement e) { + expect(e.isStatic, isTrue); + _writeIndentedLine(() { _writeIf(e.isExternal, 'external '); _writeName(e); diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart index 7ca014530d017..7b0908228d276 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_common.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart @@ -22411,7 +22411,7 @@ library synthetic static foo @-1 type: Future accessors - get foo @16 async + static get foo @16 async returnType: Future '''); } @@ -22430,7 +22430,7 @@ library synthetic static foo @-1 type: Stream accessors - get foo @37 async* + static get foo @37 async* returnType: Stream '''); } @@ -22449,7 +22449,7 @@ library synthetic static x @-1 type: dynamic accessors - get x @64 + static get x @64 documentationComment: /**\n * Docs\n */ returnType: dynamic '''); @@ -22464,7 +22464,7 @@ library synthetic static x @-1 type: int accessors - external get x @17 + static external get x @17 returnType: int '''); } @@ -22510,7 +22510,7 @@ library synthetic static foo @-1 type: Iterator accessors - get foo @18 sync* + static get foo @18 sync* returnType: Iterator '''); } @@ -22526,9 +22526,9 @@ library synthetic static y @-1 type: dynamic accessors - get x @8 + static get x @8 returnType: int - get y @23 + static get y @23 returnType: dynamic '''); } @@ -22659,9 +22659,9 @@ library synthetic static x @-1 type: int accessors - get x @8 + static get x @8 returnType: int - set x @25 + static set x @25 parameters requiredPositional value @31 type: int @@ -22679,12 +22679,12 @@ library synthetic static x @-1 type: int accessors - set x @9 + static set x @9 parameters requiredPositional value @15 type: int returnType: void - get x @33 + static get x @33 returnType: int '''); } @@ -25701,7 +25701,7 @@ library synthetic static g @-1 type: dynamic accessors - get g @4 + static get g @4 returnType: dynamic '''); } @@ -25845,7 +25845,7 @@ library synthetic static main @-1 type: dynamic accessors - get main @4 + static get main @4 returnType: dynamic '''); } @@ -27709,7 +27709,7 @@ library accessors synthetic static get a @-1 returnType: dynamic - get f @23 + static get f @23 metadata Annotation atSign: @ @16 @@ -27739,7 +27739,7 @@ library accessors synthetic static get a @-1 returnType: dynamic - set f @23 + static set f @23 metadata Annotation atSign: @ @16 @@ -29441,7 +29441,7 @@ library accessors synthetic static get foo @-1 returnType: int - get getter @29 + static get getter @29 metadata Annotation atSign: @ @16 @@ -29476,7 +29476,7 @@ library accessors synthetic static get foo @-1 returnType: int - set setter @25 + static set setter @25 metadata Annotation atSign: @ @16 @@ -29737,7 +29737,7 @@ library accessors synthetic static get a @-1 returnType: dynamic - set foo @21 + static set foo @21 parameters requiredPositional x @32 type: int @@ -31285,7 +31285,7 @@ library synthetic static foo @-1 type: int accessors - get foo @8 + static get foo @8 returnType: int '''); } @@ -31890,7 +31890,7 @@ library type: int nonSynthetic: self::@getter::foo accessors - get foo @8 + static get foo @8 returnType: int nonSynthetic: self::@getter::foo ''', @@ -31912,10 +31912,10 @@ library type: int nonSynthetic: self::@getter::foo accessors - get foo @8 + static get foo @8 returnType: int nonSynthetic: self::@getter::foo - set foo @22 + static set foo @22 parameters requiredPositional value @30 type: int @@ -31940,7 +31940,7 @@ library type: int nonSynthetic: self::@setter::foo accessors - set foo @4 + static set foo @4 parameters requiredPositional value @12 type: int @@ -32508,7 +32508,7 @@ library synthetic static x @-1 type: dynamic accessors - set x @69 + static set x @69 documentationComment: /**\n * Docs\n */ parameters requiredPositional value @71 @@ -32526,7 +32526,7 @@ library synthetic static x @-1 type: int accessors - external set x @18 + static external set x @18 parameters requiredPositional value @24 type: int @@ -32543,7 +32543,7 @@ library synthetic static f @-1 type: int accessors - set f @4 + static set f @4 parameters requiredPositional value @10 type: int @@ -32563,12 +32563,12 @@ library synthetic static y @-1 type: dynamic accessors - set x @9 + static set x @9 parameters requiredPositional value @15 type: int returnType: void - set y @29 + static set y @29 parameters requiredPositional value @31 type: dynamic @@ -36957,9 +36957,9 @@ library synthetic static x @-1 type: int accessors - get x @8 + static get x @8 returnType: int - set x @25 + static set x @25 parameters requiredPositional value @31 type: int @@ -36979,12 +36979,12 @@ library synthetic static x @-1 type: int accessors - set x @9 + static set x @9 parameters requiredPositional value @15 type: int returnType: void - get x @33 + static get x @33 returnType: int '''); } @@ -37003,7 +37003,7 @@ library accessors synthetic static get foo @-1 returnType: int - set foo @23 + static set foo @23 parameters requiredPositional newValue @31 type: int @@ -37660,7 +37660,7 @@ library synthetic static x @-1 type: int accessors - get x @39 + static get x @39 returnType: int parts a.dart @@ -37668,7 +37668,7 @@ library synthetic static x @-1 type: int accessors - set x @25 + static set x @25 parameters requiredPositional _ @31 type: int @@ -37695,7 +37695,7 @@ library synthetic static x @-1 type: int accessors - set x @40 + static set x @40 parameters requiredPositional _ @46 type: int @@ -37706,7 +37706,7 @@ library synthetic static x @-1 type: int accessors - get x @24 + static get x @24 returnType: int '''); } @@ -37727,14 +37727,14 @@ library synthetic static x @-1 type: int accessors - get x @24 + static get x @24 returnType: int b.dart topLevelVariables synthetic static x @-1 type: int accessors - set x @25 + static set x @25 parameters requiredPositional _ @31 type: int @@ -38058,7 +38058,7 @@ library synthetic static x @-1 type: int accessors - set x @25 + static set x @25 parameters requiredPositional _ @31 type: int @@ -38068,7 +38068,7 @@ library synthetic static x @-1 type: int accessors - get x @24 + static get x @24 returnType: int '''); } diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart index f2133b041c1e8..3974511ab2d12 100644 --- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart +++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart @@ -1999,7 +1999,7 @@ library requiredPositional _r_instanceClassMethod @-1 type: String Function(int) returnType: void - get topLevelGetter @74 + static get topLevelGetter @74 returnType: int functions topLevelFunction @7 From 09d3beb5abd0a5138ae900ebf85fde6600ee918b Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 10 Feb 2022 04:21:59 +0000 Subject: [PATCH 2/4] Rename analyzer/ tests to WithoutNullSafety. Change-Id: Id9d500b4970ec84ebaad6c2e4000464f95896d1f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232234 Reviewed-by: Samuel Rawlins Commit-Queue: Konstantin Shcheglov --- .../test/generated/invalid_code_test.dart | 136 +- .../element/inheritance_manager3_test.dart | 1357 ++--- .../resolution/await_expression_test.dart | 41 +- .../src/dart/resolution/constant_test.dart | 354 +- .../function_expression_invocation_test.dart | 77 +- .../resolution/method_invocation_test.dart | 4347 +++++++++-------- .../collection_elements_test.dart | 12 +- .../resolution/type_inference/throw_test.dart | 4 +- .../assignment_to_final_local_test.dart | 61 +- ...xpression_type_implements_equals_test.dart | 15 +- ...crete_class_with_abstract_member_test.dart | 58 +- .../src/diagnostics/could_not_infer_test.dart | 142 +- .../deprecated_member_use_test.dart | 13 +- ...override_argument_not_assignable_test.dart | 61 +- .../final_not_initialized_test.dart | 156 +- ...consistent_case_expression_types_test.dart | 53 +- ...e_different_default_values_named_test.dart | 82 +- ...ferent_default_values_positional_test.dart | 86 +- .../diagnostics/invalid_override_test.dart | 1386 +++--- ..._first_positional_parameter_type_test.dart | 44 +- ...in_has_required_named_parameters_test.dart | 24 +- ...y_required_positional_parameters_test.dart | 42 +- .../main_is_not_function_test.dart | 8 +- .../missing_required_param_test.dart | 458 +- .../src/diagnostics/missing_return_test.dart | 104 +- ...ference_no_possible_substitution_test.dart | 48 +- .../no_default_super_constructor_test.dart | 169 +- ...t_class_inherits_abstract_member_test.dart | 969 ++-- .../diagnostics/non_bool_condition_test.dart | 142 +- .../non_bool_negation_expression_test.dart | 33 +- .../diagnostics/non_bool_operand_test.dart | 54 +- .../null_safety_read_write_test.dart | 4 +- ...ype_argument_not_matching_bounds_test.dart | 952 ++-- .../diagnostics/undefined_getter_test.dart | 344 +- .../diagnostics/undefined_setter_test.dart | 258 +- .../src/diagnostics/unused_element_test.dart | 2306 ++++----- 36 files changed, 7205 insertions(+), 7195 deletions(-) diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart index 54794d786226a..51d910d646d62 100644 --- a/pkg/analyzer/test/generated/invalid_code_test.dart +++ b/pkg/analyzer/test/generated/invalid_code_test.dart @@ -10,16 +10,82 @@ import '../src/dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(InvalidCodeTest); - defineReflectiveTests(InvalidCodeWithNullSafetyTest); + defineReflectiveTests(InvalidCodeWithoutNullSafetyTest); }); } +@reflectiveTest +class InvalidCodeTest extends PubPackageResolutionTest { + test_functionExpression_emptyBody() async { + await _assertCanBeAnalyzed(r''' +var v = (); +'''); + } + + test_functionExpressionInvocation_mustBeNullShortingTerminated() async { + // It looks like MethodInvocation, but because `8` is not SimpleIdentifier, + // we parse it as FunctionExpressionInvocation. + await _assertCanBeAnalyzed(r''' +var v = a?.8(b); +'''); + } + + test_inAnnotation_noFlow_labeledStatement() async { + await _assertCanBeAnalyzed(''' +@A(() { label: }) +typedef F = void Function(); +'''); + } + + test_inDefaultValue_noFlow_ifExpression() async { + await _assertCanBeAnalyzed(''' +typedef void F({a = [if (true) 0]}); +'''); + } + + test_inDefaultValue_noFlow_ifStatement() async { + await _assertCanBeAnalyzed(''' +typedef void F([a = () { if (true) 0; }]); +'''); + } + + test_issue_40837() async { + await _assertCanBeAnalyzed(''' +class A { + const A(_); +} + +@A(() => 0) +class B {} +'''); + } + + test_methodInvocation_ofGenericClass_generic_static_fromLegacy() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + static void foo() {} +} +'''); + await _assertCanBeAnalyzed(''' +// @dart = 2.9 +import 'a.dart'; + +const bar = A.foo(); +'''); + } + + Future _assertCanBeAnalyzed(String text) async { + await resolveTestCode(text); + assertHasTestErrors(); + } +} + /// Tests for various end-to-end cases when invalid code caused exceptions /// in one or another Analyzer subsystem. We are not interested not in specific /// errors generated, but we want to make sure that there is at least one, /// and analysis finishes without exceptions. @reflectiveTest -class InvalidCodeTest extends PubPackageResolutionTest +class InvalidCodeWithoutNullSafetyTest extends PubPackageResolutionTest with WithoutNullSafetyMixin { // TODO(https://github.com/dart-lang/sdk/issues/44666): Use null safety in // test cases. @@ -409,69 +475,3 @@ class B { assertHasTestErrors(); } } - -@reflectiveTest -class InvalidCodeWithNullSafetyTest extends PubPackageResolutionTest { - test_functionExpression_emptyBody() async { - await _assertCanBeAnalyzed(r''' -var v = (); -'''); - } - - test_functionExpressionInvocation_mustBeNullShortingTerminated() async { - // It looks like MethodInvocation, but because `8` is not SimpleIdentifier, - // we parse it as FunctionExpressionInvocation. - await _assertCanBeAnalyzed(r''' -var v = a?.8(b); -'''); - } - - test_inAnnotation_noFlow_labeledStatement() async { - await _assertCanBeAnalyzed(''' -@A(() { label: }) -typedef F = void Function(); -'''); - } - - test_inDefaultValue_noFlow_ifExpression() async { - await _assertCanBeAnalyzed(''' -typedef void F({a = [if (true) 0]}); -'''); - } - - test_inDefaultValue_noFlow_ifStatement() async { - await _assertCanBeAnalyzed(''' -typedef void F([a = () { if (true) 0; }]); -'''); - } - - test_issue_40837() async { - await _assertCanBeAnalyzed(''' -class A { - const A(_); -} - -@A(() => 0) -class B {} -'''); - } - - test_methodInvocation_ofGenericClass_generic_static_fromLegacy() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - static void foo() {} -} -'''); - await _assertCanBeAnalyzed(''' -// @dart = 2.9 -import 'a.dart'; - -const bar = A.foo(); -'''); - } - - Future _assertCanBeAnalyzed(String text) async { - await resolveTestCode(text); - assertHasTestErrors(); - } -} diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart index 73da833913852..704c6ed75a76c 100644 --- a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart +++ b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart @@ -12,209 +12,492 @@ import '../resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(InheritanceManager3Test); - defineReflectiveTests(InheritanceManager3WithNullSafetyTest); + defineReflectiveTests(InheritanceManager3WithoutNullSafetyTest); }); } @reflectiveTest class InheritanceManager3Test extends _InheritanceManager3Base { - test_getInherited_closestSuper() async { - await resolveTestCode(''' + test_getInheritedMap_topMerge_method() async { + newFile('$testPackageLibPath/a.dart', content: r''' +// @dart = 2.6 class A { - void foo() {} + void foo({int a}) {} } +'''); -class B extends A { - void foo() {} + await resolveTestCode(''' +import 'a.dart'; + +class B { + void foo({required int? a}) {} } -class X extends B { - void foo() {} +class C implements A, B { + void foo({int? a}) {} } '''); - _assertGetInherited( - className: 'X', - name: 'foo', - expected: 'B.foo: void Function()', - ); + + _assertInheritedMap('C', r''' +A.foo: void Function({int a}) +'''); } - test_getInherited_interfaces() async { + test_getMember_mixin_notMerge_replace() async { await resolveTestCode(''' -abstract class I { - void foo(); +class A { + T foo() => throw 0; } -abstract class J { - void foo(); +mixin M { + T foo() => throw 1; } -class X implements I, J { - void foo() {} -} +class X extends A with M {} +class Y extends A with M {} '''); - _assertGetInherited( + _assertGetMember2( className: 'X', name: 'foo', - expected: 'I.foo: void Function()', + expected: 'M.foo: Object? Function()', + ); + _assertGetMember2( + className: 'Y', + name: 'foo', + expected: 'M.foo: dynamic Function()', ); } - test_getInherited_mixin() async { - await resolveTestCode(''' + test_getMember_optIn_inheritsOptIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' class A { - void foo() {} + int foo(int a, int? b) => 0; } - -mixin M { - void foo() {} +'''); + await resolveTestCode(''' +import 'a.dart'; +class B extends A { + int? bar(int a) => 0; } +'''); + _assertGetMember( + className: 'B', + name: 'foo', + expected: 'A.foo: int Function(int, int?)', + ); + _assertGetMember( + className: 'B', + name: 'bar', + expected: 'B.bar: int? Function(int)', + ); + } -class X extends A with M { - void foo() {} + test_getMember_optIn_inheritsOptOut() async { + newFile('$testPackageLibPath/a.dart', content: r''' +// @dart = 2.6 +class A { + int foo(int a, int b) => 0; } '''); - _assertGetInherited( - className: 'X', + await resolveTestCode(''' +import 'a.dart'; +class B extends A { + int? bar(int a) => 0; +} +'''); + _assertGetMember( + className: 'B', name: 'foo', - expected: 'M.foo: void Function()', + expected: 'A.foo: int* Function(int*, int*)*', + ); + _assertGetMember( + className: 'B', + name: 'bar', + expected: 'B.bar: int? Function(int)', ); } - test_getInherited_preferImplemented() async { + test_getMember_optIn_topMerge_getter_existing() async { await resolveTestCode(''' class A { - void foo() {} + dynamic get foo => 0; } -class I { - void foo() {} +class B { + Object? get foo => 0; } -class X extends A implements I { - void foo() {} -} +class X extends A implements B {} '''); - _assertGetInherited( + + _assertGetMember( className: 'X', name: 'foo', - expected: 'A.foo: void Function()', + expected: 'B.foo: Object? Function()', ); } - test_getInheritedConcreteMap_accessor_extends() async { + test_getMember_optIn_topMerge_getter_synthetic() async { await resolveTestCode(''' -class A { - int get foo => 0; +abstract class A { + Future get foo; } -class B extends A {} -'''); - _assertInheritedConcreteMap('B', r''' -A.foo: int Function() +abstract class B { + Future get foo; +} + +abstract class X extends A implements B {} '''); + + _assertGetMember( + className: 'X', + name: 'foo', + expected: 'X.foo: Future Function()', + ); } - test_getInheritedConcreteMap_accessor_implements() async { + test_getMember_optIn_topMerge_method() async { await resolveTestCode(''' class A { - int get foo => 0; + Object? foo(dynamic x) {} } -abstract class B implements A {} -'''); - _assertInheritedConcreteMap('B', ''); - } - - test_getInheritedConcreteMap_accessor_with() async { - await resolveTestCode(''' -mixin A { - int get foo => 0; +class B { + dynamic foo(Object? x) {} } -class B extends Object with A {} -'''); - _assertInheritedConcreteMap('B', r''' -A.foo: int Function() +class X extends A implements B {} '''); - } - test_getInheritedConcreteMap_implicitExtends() async { - await resolveTestCode(''' -class A {} -'''); - _assertInheritedConcreteMap('A', ''); + _assertGetMember( + className: 'X', + name: 'foo', + expected: 'X.foo: Object? Function(Object?)', + ); } - test_getInheritedConcreteMap_method_extends() async { + test_getMember_optIn_topMerge_setter_existing() async { await resolveTestCode(''' class A { - void foo() {} + set foo(dynamic _) {} } -class B extends A {} -'''); - _assertInheritedConcreteMap('B', r''' -A.foo: void Function() -'''); - } - - test_getInheritedConcreteMap_method_extends_abstract() async { - await resolveTestCode(''' -abstract class A { - void foo(); +class B { + set foo(Object? _) {} } -class B extends A {} +class X extends A implements B {} '''); - _assertInheritedConcreteMap('B', ''); + + _assertGetMember( + className: 'X', + name: 'foo=', + expected: 'B.foo=: void Function(Object?)', + ); } - test_getInheritedConcreteMap_method_extends_invalidForImplements() async { + test_getMember_optIn_topMerge_setter_synthetic() async { await resolveTestCode(''' -abstract class I { - void foo(int x, {int y}); - void bar(String s); +abstract class A { + set foo(Future _); } -class A { - void foo(int x) {} +abstract class B { + set foo(Future _); } -class C extends A implements I {} -'''); - _assertInheritedConcreteMap('C', r''' -A.foo: void Function(int) +abstract class X extends A implements B {} '''); + + _assertGetMember( + className: 'X', + name: 'foo=', + expected: 'X.foo=: void Function(Future)', + ); } - test_getInheritedConcreteMap_method_implements() async { - await resolveTestCode(''' + test_getMember_optOut_inheritsOptIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' class A { - void foo() {} + int foo(int a, int? b) => 0; } - -abstract class B implements A {} '''); - _assertInheritedConcreteMap('B', ''); - } - - test_getInheritedConcreteMap_method_with() async { await resolveTestCode(''' -mixin A { - void foo() {} +// @dart = 2.6 +import 'a.dart'; +class B extends A { + int bar(int a) => 0; } - -class B extends Object with A {} -'''); - _assertInheritedConcreteMap('B', r''' -A.foo: void Function() '''); + _assertGetMember2( + className: 'B', + name: 'foo', + expected: 'A.foo: int* Function(int*, int*)*', + ); + + _assertGetMember2( + className: 'B', + name: 'bar', + expected: 'B.bar: int* Function(int*)*', + ); } - test_getInheritedConcreteMap_method_with2() async { - await resolveTestCode(''' -mixin A { + test_getMember_optOut_mixesOptIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + int foo(int a, int? b) => 0; +} +'''); + await resolveTestCode(''' +// @dart = 2.6 +import 'a.dart'; +class B with A { + int bar(int a) => 0; +} +'''); + _assertGetMember2( + className: 'B', + name: 'foo', + expected: 'A.foo: int* Function(int*, int*)*', + ); + _assertGetMember2( + className: 'B', + name: 'bar', + expected: 'B.bar: int* Function(int*)*', + ); + } + + test_getMember_optOut_passOptIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + int foo(int a, int? b) => 0; +} +'''); + newFile('$testPackageLibPath/b.dart', content: r''' +// @dart = 2.6 +import 'a.dart'; +class B extends A { + int bar(int a) => 0; +} +'''); + await resolveTestCode(''' +import 'b.dart'; +class C extends B {} +'''); + _assertGetMember( + className: 'C', + name: 'foo', + expected: 'A.foo: int* Function(int*, int*)*', + ); + _assertGetMember( + className: 'C', + name: 'bar', + expected: 'B.bar: int* Function(int*)*', + ); + } +} + +@reflectiveTest +class InheritanceManager3WithoutNullSafetyTest + extends _InheritanceManager3Base { + test_getInherited_closestSuper() async { + await resolveTestCode(''' +class A { + void foo() {} +} + +class B extends A { + void foo() {} +} + +class X extends B { + void foo() {} +} +'''); + _assertGetInherited( + className: 'X', + name: 'foo', + expected: 'B.foo: void Function()', + ); + } + + test_getInherited_interfaces() async { + await resolveTestCode(''' +abstract class I { + void foo(); +} + +abstract class J { + void foo(); +} + +class X implements I, J { + void foo() {} +} +'''); + _assertGetInherited( + className: 'X', + name: 'foo', + expected: 'I.foo: void Function()', + ); + } + + test_getInherited_mixin() async { + await resolveTestCode(''' +class A { + void foo() {} +} + +mixin M { + void foo() {} +} + +class X extends A with M { + void foo() {} +} +'''); + _assertGetInherited( + className: 'X', + name: 'foo', + expected: 'M.foo: void Function()', + ); + } + + test_getInherited_preferImplemented() async { + await resolveTestCode(''' +class A { + void foo() {} +} + +class I { + void foo() {} +} + +class X extends A implements I { + void foo() {} +} +'''); + _assertGetInherited( + className: 'X', + name: 'foo', + expected: 'A.foo: void Function()', + ); + } + + test_getInheritedConcreteMap_accessor_extends() async { + await resolveTestCode(''' +class A { + int get foo => 0; +} + +class B extends A {} +'''); + _assertInheritedConcreteMap('B', r''' +A.foo: int Function() +'''); + } + + test_getInheritedConcreteMap_accessor_implements() async { + await resolveTestCode(''' +class A { + int get foo => 0; +} + +abstract class B implements A {} +'''); + _assertInheritedConcreteMap('B', ''); + } + + test_getInheritedConcreteMap_accessor_with() async { + await resolveTestCode(''' +mixin A { + int get foo => 0; +} + +class B extends Object with A {} +'''); + _assertInheritedConcreteMap('B', r''' +A.foo: int Function() +'''); + } + + test_getInheritedConcreteMap_implicitExtends() async { + await resolveTestCode(''' +class A {} +'''); + _assertInheritedConcreteMap('A', ''); + } + + test_getInheritedConcreteMap_method_extends() async { + await resolveTestCode(''' +class A { + void foo() {} +} + +class B extends A {} +'''); + _assertInheritedConcreteMap('B', r''' +A.foo: void Function() +'''); + } + + test_getInheritedConcreteMap_method_extends_abstract() async { + await resolveTestCode(''' +abstract class A { + void foo(); +} + +class B extends A {} +'''); + _assertInheritedConcreteMap('B', ''); + } + + test_getInheritedConcreteMap_method_extends_invalidForImplements() async { + await resolveTestCode(''' +abstract class I { + void foo(int x, {int y}); + void bar(String s); +} + +class A { + void foo(int x) {} +} + +class C extends A implements I {} +'''); + _assertInheritedConcreteMap('C', r''' +A.foo: void Function(int) +'''); + } + + test_getInheritedConcreteMap_method_implements() async { + await resolveTestCode(''' +class A { + void foo() {} +} + +abstract class B implements A {} +'''); + _assertInheritedConcreteMap('B', ''); + } + + test_getInheritedConcreteMap_method_with() async { + await resolveTestCode(''' +mixin A { + void foo() {} +} + +class B extends Object with A {} +'''); + _assertInheritedConcreteMap('B', r''' +A.foo: void Function() +'''); + } + + test_getInheritedConcreteMap_method_with2() async { + await resolveTestCode(''' +mixin A { void foo() {} } @@ -626,780 +909,498 @@ abstract class I1 { void f(int i); } -abstract class I2 { - void f(Object o); -} - -abstract class C implements I1, I2 {} -'''); - _assertGetMember( - className: 'C', - name: 'f', - expected: 'I2.f: void Function(Object)', - ); - } - - test_getMember_concrete() async { - await resolveTestCode(''' -class A { - void foo() {} -} -'''); - _assertGetMember( - className: 'A', - name: 'foo', - concrete: true, - expected: 'A.foo: void Function()', - ); - } - - test_getMember_concrete_abstract() async { - await resolveTestCode(''' -abstract class A { - void foo(); -} -'''); - _assertGetMember( - className: 'A', - name: 'foo', - concrete: true, - ); - } - - test_getMember_concrete_fromMixedClass() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -class X with A {} -'''); - _assertGetMember( - className: 'X', - name: 'foo', - concrete: true, - expected: 'A.foo: void Function()', - ); - } - - test_getMember_concrete_fromMixedClass2() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -class B = Object with A; - -class X with B {} -'''); - _assertGetMember( - className: 'X', - name: 'foo', - concrete: true, - expected: 'A.foo: void Function()', - ); - } - - test_getMember_concrete_fromMixedClass_skipObject() async { - await resolveTestCode(''' -class A { - String toString() => 'A'; -} - -class B {} - -class X extends A with B {} -'''); - _assertGetMember( - className: 'X', - name: 'toString', - concrete: true, - expected: 'A.toString: String Function()', - ); - } - - test_getMember_concrete_fromMixin() async { - await resolveTestCode(''' -mixin M { - void foo() {} -} - -class X with M {} -'''); - _assertGetMember( - className: 'X', - name: 'foo', - concrete: true, - expected: 'M.foo: void Function()', - ); - } - - test_getMember_concrete_fromSuper() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -class B extends A {} - -abstract class C extends B {} -'''); - _assertGetMember( - className: 'B', - name: 'foo', - concrete: true, - expected: 'A.foo: void Function()', - ); - - _assertGetMember( - className: 'C', - name: 'foo', - concrete: true, - expected: 'A.foo: void Function()', - ); - } - - test_getMember_concrete_missing() async { - await resolveTestCode(''' -abstract class A {} -'''); - _assertGetMember( - className: 'A', - name: 'foo', - concrete: true, - ); - } - - test_getMember_concrete_noSuchMethod() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -class B implements A { - noSuchMethod(_) {} -} - -abstract class C extends B {} -'''); - _assertGetMember( - className: 'B', - name: 'foo', - concrete: true, - expected: 'A.foo: void Function()', - ); - - _assertGetMember( - className: 'C', - name: 'foo', - concrete: true, - expected: 'A.foo: void Function()', - ); - } - - test_getMember_concrete_noSuchMethod_mixin() async { - await resolveTestCode(''' -class A { - void foo(); - - noSuchMethod(_) {} -} - -abstract class B extends Object with A {} -'''); -// noSuchMethod forwarders are not mixed-in. - // https://github.com/dart-lang/sdk/issues/33553#issuecomment-424638320 - _assertGetMember( - className: 'B', - name: 'foo', - concrete: true, - ); - } - - test_getMember_concrete_noSuchMethod_moreSpecificSignature() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -class B implements A { - noSuchMethod(_) {} -} - -class C extends B { - void foo([int a]); -} -'''); - _assertGetMember( - className: 'C', - name: 'foo', - concrete: true, - expected: 'C.foo: void Function([int])', - ); - } - - test_getMember_method_covariantByDeclaration_inherited() async { - await resolveTestCode(''' -abstract class A { - void foo(covariant num a); -} - -abstract class B extends A { - void foo(int a); -} -'''); - var member = manager.getMember2( - findElement.classOrMixin('B'), - Name(null, 'foo'), - )!; - // TODO(scheglov) It would be nice to use `_assertGetMember`. - // But we need a way to check covariance. - // Maybe check the element display string, not the type. - expect(member.parameters[0].isCovariant, isTrue); - } - - test_getMember_method_covariantByDeclaration_merged() async { - await resolveTestCode(''' -class A { - void foo(covariant num a) {} -} - -class B { - void foo(int a) {} -} - -class C extends B implements A {} -'''); - var member = manager.getMember2( - findElement.classOrMixin('C'), - Name(null, 'foo'), - concrete: true, - )!; - // TODO(scheglov) It would be nice to use `_assertGetMember`. - expect(member.declaration, same(findElement.method('foo', of: 'B'))); - expect(member.parameters[0].isCovariant, isTrue); - } - - test_getMember_preferLatest_mixin() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -mixin M1 { - void foo() {} -} - -mixin M2 { - void foo() {} -} - -abstract class I { - void foo(); -} - -class X extends A with M1, M2 implements I {} -'''); - _assertGetMember( - className: 'X', - name: 'foo', - expected: 'M2.foo: void Function()', - ); - } - - test_getMember_preferLatest_superclass() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -class B extends A { - void foo() {} -} - -abstract class I { - void foo(); -} - -class X extends B implements I {} -'''); - _assertGetMember( - className: 'X', - name: 'foo', - expected: 'B.foo: void Function()', - ); - } - - test_getMember_preferLatest_this() async { - await resolveTestCode(''' -class A { - void foo() {} -} - -abstract class I { - void foo(); -} - -class X extends A implements I { - void foo() {} -} -'''); - _assertGetMember( - className: 'X', - name: 'foo', - expected: 'X.foo: void Function()', - ); - } - - test_getMember_setter_covariantByDeclaration_inherited() async { - await resolveTestCode(''' -abstract class A { - set foo(covariant num a); -} - -abstract class B extends A { - set foo(int a); +abstract class I2 { + void f(Object o); } + +abstract class C implements I1, I2 {} '''); - var member = manager.getMember2( - findElement.classOrMixin('B'), - Name(null, 'foo='), - )!; - // TODO(scheglov) It would be nice to use `_assertGetMember`. - // But we need a way to check covariance. - // Maybe check the element display string, not the type. - expect(member.parameters[0].isCovariant, isTrue); + _assertGetMember( + className: 'C', + name: 'f', + expected: 'I2.f: void Function(Object)', + ); } - test_getMember_setter_covariantByDeclaration_merged() async { + test_getMember_concrete() async { await resolveTestCode(''' class A { - set foo(covariant num a) {} -} - -class B { - set foo(int a) {} + void foo() {} } - -class C extends B implements A {} '''); - var member = manager.getMember2( - findElement.classOrMixin('C'), - Name(null, 'foo='), + _assertGetMember( + className: 'A', + name: 'foo', concrete: true, - )!; - // TODO(scheglov) It would be nice to use `_assertGetMember`. - expect(member.declaration, same(findElement.setter('foo', of: 'B'))); - expect(member.parameters[0].isCovariant, isTrue); + expected: 'A.foo: void Function()', + ); } - test_getMember_super_abstract() async { + test_getMember_concrete_abstract() async { await resolveTestCode(''' abstract class A { void foo(); } - -class B extends A { - noSuchMethod(_) {} -} '''); _assertGetMember( - className: 'B', + className: 'A', name: 'foo', - forSuper: true, + concrete: true, ); } - test_getMember_super_forMixin_interface() async { + test_getMember_concrete_fromMixedClass() async { await resolveTestCode(''' -abstract class A { - void foo(); +class A { + void foo() {} } -mixin M implements A {} +class X with A {} '''); _assertGetMember( - className: 'M', + className: 'X', name: 'foo', - forSuper: true, + concrete: true, + expected: 'A.foo: void Function()', ); } - test_getMember_super_forMixin_superclassConstraint() async { + test_getMember_concrete_fromMixedClass2() async { await resolveTestCode(''' -abstract class A { - void foo(); +class A { + void foo() {} } -mixin M on A {} +class B = Object with A; + +class X with B {} '''); _assertGetMember( - className: 'M', + className: 'X', name: 'foo', - forSuper: true, + concrete: true, expected: 'A.foo: void Function()', ); } - test_getMember_super_forObject() async { + test_getMember_concrete_fromMixedClass_skipObject() async { await resolveTestCode(''' -class A {} +class A { + String toString() => 'A'; +} + +class B {} + +class X extends A with B {} '''); - var member = manager.getMember2( - typeProvider.objectType.element, - Name(null, 'hashCode'), - forSuper: true, + _assertGetMember( + className: 'X', + name: 'toString', + concrete: true, + expected: 'A.toString: String Function()', ); - expect(member, isNull); } - test_getMember_super_fromMixin() async { + test_getMember_concrete_fromMixin() async { await resolveTestCode(''' mixin M { void foo() {} } -class X extends Object with M { - void foo() {} -} +class X with M {} '''); _assertGetMember( className: 'X', name: 'foo', - forSuper: true, + concrete: true, expected: 'M.foo: void Function()', ); } - test_getMember_super_fromSuper() async { + test_getMember_concrete_fromSuper() async { await resolveTestCode(''' class A { void foo() {} } -class B extends A { - void foo() {} -} +class B extends A {} + +abstract class C extends B {} '''); _assertGetMember( className: 'B', name: 'foo', - forSuper: true, + concrete: true, + expected: 'A.foo: void Function()', + ); + + _assertGetMember( + className: 'C', + name: 'foo', + concrete: true, expected: 'A.foo: void Function()', ); } - test_getMember_super_missing() async { + test_getMember_concrete_missing() async { await resolveTestCode(''' -class A {} - -class B extends A {} +abstract class A {} '''); _assertGetMember( - className: 'B', + className: 'A', name: 'foo', - forSuper: true, + concrete: true, ); } - test_getMember_super_noSuchMember() async { + test_getMember_concrete_noSuchMethod() async { await resolveTestCode(''' class A { - void foo(); - noSuchMethod(_) {} + void foo() {} } -class B extends A { - void foo() {} +class B implements A { + noSuchMethod(_) {} } + +abstract class C extends B {} '''); _assertGetMember( className: 'B', name: 'foo', - forSuper: true, + concrete: true, + expected: 'A.foo: void Function()', + ); + + _assertGetMember( + className: 'C', + name: 'foo', + concrete: true, expected: 'A.foo: void Function()', ); } -} -@reflectiveTest -class InheritanceManager3WithNullSafetyTest extends _InheritanceManager3Base { - test_getInheritedMap_topMerge_method() async { - newFile('$testPackageLibPath/a.dart', content: r''' -// @dart = 2.6 + test_getMember_concrete_noSuchMethod_mixin() async { + await resolveTestCode(''' class A { - void foo({int a}) {} + void foo(); + + noSuchMethod(_) {} } + +abstract class B extends Object with A {} '''); +// noSuchMethod forwarders are not mixed-in. + // https://github.com/dart-lang/sdk/issues/33553#issuecomment-424638320 + _assertGetMember( + className: 'B', + name: 'foo', + concrete: true, + ); + } + test_getMember_concrete_noSuchMethod_moreSpecificSignature() async { await resolveTestCode(''' -import 'a.dart'; +class A { + void foo() {} +} -class B { - void foo({required int? a}) {} +class B implements A { + noSuchMethod(_) {} } -class C implements A, B { - void foo({int? a}) {} +class C extends B { + void foo([int a]); } '''); + _assertGetMember( + className: 'C', + name: 'foo', + concrete: true, + expected: 'C.foo: void Function([int])', + ); + } - _assertInheritedMap('C', r''' -A.foo: void Function({int a}) + test_getMember_method_covariantByDeclaration_inherited() async { + await resolveTestCode(''' +abstract class A { + void foo(covariant num a); +} + +abstract class B extends A { + void foo(int a); +} '''); + var member = manager.getMember2( + findElement.classOrMixin('B'), + Name(null, 'foo'), + )!; + // TODO(scheglov) It would be nice to use `_assertGetMember`. + // But we need a way to check covariance. + // Maybe check the element display string, not the type. + expect(member.parameters[0].isCovariant, isTrue); } - test_getMember_mixin_notMerge_replace() async { + test_getMember_method_covariantByDeclaration_merged() async { await resolveTestCode(''' -class A { - T foo() => throw 0; +class A { + void foo(covariant num a) {} } -mixin M { - T foo() => throw 1; +class B { + void foo(int a) {} } -class X extends A with M {} -class Y extends A with M {} +class C extends B implements A {} '''); - _assertGetMember2( - className: 'X', - name: 'foo', - expected: 'M.foo: Object? Function()', - ); - _assertGetMember2( - className: 'Y', - name: 'foo', - expected: 'M.foo: dynamic Function()', - ); + var member = manager.getMember2( + findElement.classOrMixin('C'), + Name(null, 'foo'), + concrete: true, + )!; + // TODO(scheglov) It would be nice to use `_assertGetMember`. + expect(member.declaration, same(findElement.method('foo', of: 'B'))); + expect(member.parameters[0].isCovariant, isTrue); } - test_getMember_optIn_inheritsOptIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' + test_getMember_preferLatest_mixin() async { + await resolveTestCode(''' class A { - int foo(int a, int? b) => 0; + void foo() {} +} + +mixin M1 { + void foo() {} +} + +mixin M2 { + void foo() {} } -'''); - await resolveTestCode(''' -import 'a.dart'; -class B extends A { - int? bar(int a) => 0; + +abstract class I { + void foo(); } + +class X extends A with M1, M2 implements I {} '''); _assertGetMember( - className: 'B', + className: 'X', name: 'foo', - expected: 'A.foo: int Function(int, int?)', - ); - _assertGetMember( - className: 'B', - name: 'bar', - expected: 'B.bar: int? Function(int)', + expected: 'M2.foo: void Function()', ); } - test_getMember_optIn_inheritsOptOut() async { - newFile('$testPackageLibPath/a.dart', content: r''' -// @dart = 2.6 + test_getMember_preferLatest_superclass() async { + await resolveTestCode(''' class A { - int foo(int a, int b) => 0; + void foo() {} } -'''); - await resolveTestCode(''' -import 'a.dart'; + class B extends A { - int? bar(int a) => 0; + void foo() {} +} + +abstract class I { + void foo(); } + +class X extends B implements I {} '''); _assertGetMember( - className: 'B', + className: 'X', name: 'foo', - expected: 'A.foo: int* Function(int*, int*)*', - ); - _assertGetMember( - className: 'B', - name: 'bar', - expected: 'B.bar: int? Function(int)', + expected: 'B.foo: void Function()', ); } - test_getMember_optIn_topMerge_getter_existing() async { + test_getMember_preferLatest_this() async { await resolveTestCode(''' class A { - dynamic get foo => 0; + void foo() {} } -class B { - Object? get foo => 0; +abstract class I { + void foo(); } -class X extends A implements B {} +class X extends A implements I { + void foo() {} +} '''); - _assertGetMember( className: 'X', name: 'foo', - expected: 'B.foo: Object? Function()', + expected: 'X.foo: void Function()', ); } - test_getMember_optIn_topMerge_getter_synthetic() async { + test_getMember_setter_covariantByDeclaration_inherited() async { await resolveTestCode(''' abstract class A { - Future get foo; + set foo(covariant num a); } -abstract class B { - Future get foo; +abstract class B extends A { + set foo(int a); } - -abstract class X extends A implements B {} '''); - - _assertGetMember( - className: 'X', - name: 'foo', - expected: 'X.foo: Future Function()', - ); + var member = manager.getMember2( + findElement.classOrMixin('B'), + Name(null, 'foo='), + )!; + // TODO(scheglov) It would be nice to use `_assertGetMember`. + // But we need a way to check covariance. + // Maybe check the element display string, not the type. + expect(member.parameters[0].isCovariant, isTrue); } - test_getMember_optIn_topMerge_method() async { + test_getMember_setter_covariantByDeclaration_merged() async { await resolveTestCode(''' class A { - Object? foo(dynamic x) {} + set foo(covariant num a) {} } class B { - dynamic foo(Object? x) {} + set foo(int a) {} } -class X extends A implements B {} +class C extends B implements A {} '''); + var member = manager.getMember2( + findElement.classOrMixin('C'), + Name(null, 'foo='), + concrete: true, + )!; + // TODO(scheglov) It would be nice to use `_assertGetMember`. + expect(member.declaration, same(findElement.setter('foo', of: 'B'))); + expect(member.parameters[0].isCovariant, isTrue); + } + + test_getMember_super_abstract() async { + await resolveTestCode(''' +abstract class A { + void foo(); +} +class B extends A { + noSuchMethod(_) {} +} +'''); _assertGetMember( - className: 'X', + className: 'B', name: 'foo', - expected: 'X.foo: Object? Function(Object?)', + forSuper: true, ); } - test_getMember_optIn_topMerge_setter_existing() async { + test_getMember_super_forMixin_interface() async { await resolveTestCode(''' -class A { - set foo(dynamic _) {} -} - -class B { - set foo(Object? _) {} +abstract class A { + void foo(); } -class X extends A implements B {} +mixin M implements A {} '''); - _assertGetMember( - className: 'X', - name: 'foo=', - expected: 'B.foo=: void Function(Object?)', + className: 'M', + name: 'foo', + forSuper: true, ); } - test_getMember_optIn_topMerge_setter_synthetic() async { + test_getMember_super_forMixin_superclassConstraint() async { await resolveTestCode(''' abstract class A { - set foo(Future _); + void foo(); } -abstract class B { - set foo(Future _); -} +mixin M on A {} +'''); + _assertGetMember( + className: 'M', + name: 'foo', + forSuper: true, + expected: 'A.foo: void Function()', + ); + } -abstract class X extends A implements B {} + test_getMember_super_forObject() async { + await resolveTestCode(''' +class A {} '''); + var member = manager.getMember2( + typeProvider.objectType.element, + Name(null, 'hashCode'), + forSuper: true, + ); + expect(member, isNull); + } + + test_getMember_super_fromMixin() async { + await resolveTestCode(''' +mixin M { + void foo() {} +} +class X extends Object with M { + void foo() {} +} +'''); _assertGetMember( className: 'X', - name: 'foo=', - expected: 'X.foo=: void Function(Future)', + name: 'foo', + forSuper: true, + expected: 'M.foo: void Function()', ); } - test_getMember_optOut_inheritsOptIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' + test_getMember_super_fromSuper() async { + await resolveTestCode(''' class A { - int foo(int a, int? b) => 0; + void foo() {} } -'''); - await resolveTestCode(''' -// @dart = 2.6 -import 'a.dart'; + class B extends A { - int bar(int a) => 0; + void foo() {} } '''); - _assertGetMember2( + _assertGetMember( className: 'B', name: 'foo', - expected: 'A.foo: int* Function(int*, int*)*', - ); - - _assertGetMember2( - className: 'B', - name: 'bar', - expected: 'B.bar: int* Function(int*)*', + forSuper: true, + expected: 'A.foo: void Function()', ); } - test_getMember_optOut_mixesOptIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - int foo(int a, int? b) => 0; -} -'''); + test_getMember_super_missing() async { await resolveTestCode(''' -// @dart = 2.6 -import 'a.dart'; -class B with A { - int bar(int a) => 0; -} +class A {} + +class B extends A {} '''); - _assertGetMember2( + _assertGetMember( className: 'B', name: 'foo', - expected: 'A.foo: int* Function(int*, int*)*', - ); - _assertGetMember2( - className: 'B', - name: 'bar', - expected: 'B.bar: int* Function(int*)*', + forSuper: true, ); } - test_getMember_optOut_passOptIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' + test_getMember_super_noSuchMember() async { + await resolveTestCode(''' class A { - int foo(int a, int? b) => 0; + void foo(); + noSuchMethod(_) {} } -'''); - newFile('$testPackageLibPath/b.dart', content: r''' -// @dart = 2.6 -import 'a.dart'; + class B extends A { - int bar(int a) => 0; + void foo() {} } -'''); - await resolveTestCode(''' -import 'b.dart'; -class C extends B {} '''); _assertGetMember( - className: 'C', + className: 'B', name: 'foo', - expected: 'A.foo: int* Function(int*, int*)*', - ); - _assertGetMember( - className: 'C', - name: 'bar', - expected: 'B.bar: int* Function(int*)*', + forSuper: true, + expected: 'A.foo: void Function()', ); } } diff --git a/pkg/analyzer/test/src/dart/resolution/await_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/await_expression_test.dart index cd5dd249c3470..8a3ba860e2faa 100644 --- a/pkg/analyzer/test/src/dart/resolution/await_expression_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/await_expression_test.dart @@ -9,58 +9,57 @@ import 'context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(AwaitExpressionResolutionTest); - defineReflectiveTests(AwaitExpressionResolutionWithNullSafetyTest); + defineReflectiveTests(AwaitExpressionResolutionWithoutNullSafetyTest); }); } @reflectiveTest -class AwaitExpressionResolutionTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { - test_future() async { +class AwaitExpressionResolutionTest extends PubPackageResolutionTest { + test_futureOrQ() async { await assertNoErrorsInCode(r''' -f(Future a) async { +import 'dart:async'; + +f(FutureOr? a) async { await a; } '''); - assertType(findNode.awaitExpression('await a'), 'int'); + assertType(findNode.awaitExpression('await a'), 'int?'); } - test_futureOr() async { + test_futureQ() async { await assertNoErrorsInCode(r''' -import 'dart:async'; - -f(FutureOr a) async { +f(Future? a) async { await a; } '''); - assertType(findNode.awaitExpression('await a'), 'int'); + assertType(findNode.awaitExpression('await a'), 'int?'); } } @reflectiveTest -class AwaitExpressionResolutionWithNullSafetyTest - extends PubPackageResolutionTest { - test_futureOrQ() async { +class AwaitExpressionResolutionWithoutNullSafetyTest + extends PubPackageResolutionTest with WithoutNullSafetyMixin { + test_future() async { await assertNoErrorsInCode(r''' -import 'dart:async'; - -f(FutureOr? a) async { +f(Future a) async { await a; } '''); - assertType(findNode.awaitExpression('await a'), 'int?'); + assertType(findNode.awaitExpression('await a'), 'int'); } - test_futureQ() async { + test_futureOr() async { await assertNoErrorsInCode(r''' -f(Future? a) async { +import 'dart:async'; + +f(FutureOr a) async { await a; } '''); - assertType(findNode.awaitExpression('await a'), 'int?'); + assertType(findNode.awaitExpression('await a'), 'int'); } } diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart index 2e49834ce4b21..286ec22fa1802 100644 --- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart @@ -16,12 +16,187 @@ import 'context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(ConstantResolutionTest); - defineReflectiveTests(ConstantResolutionWithNullSafetyTest); + defineReflectiveTests(ConstantResolutionWithoutNullSafetyTest); }); } @reflectiveTest -class ConstantResolutionTest extends PubPackageResolutionTest +class ConstantResolutionTest extends PubPackageResolutionTest { + test_constructor_nullSafe_fromLegacy_super() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + const A(List a); +} + +class B extends A { + const B(List a) : super(a); +} +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.8 +import 'a.dart'; + +const a = []; +const b = B(a); +'''); + + var b = findElement.topVar('b'); + assertType(b.computeConstantValue()!.type, 'B*'); + } + + test_constructor_nullSafe_fromLegacy_this() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + const A(List a) : this(a); + const A.second(List a); +} +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.8 +import 'a.dart'; + +const a = []; +const b = A(a); +'''); + + var b = findElement.topVar('b'); + assertType(b.computeConstantValue()!.type, 'A*'); + } + + test_context_eliminateTypeVariables() async { + await assertNoErrorsInCode(r''' +class A { + const A({List a = const []}); +} +'''); + assertType(findNode.listLiteral('const []'), 'List'); + } + + test_context_eliminateTypeVariables_functionType() async { + await assertNoErrorsInCode(r''' +class A { + const A({List a = const []}); +} +'''); + assertType( + findNode.listLiteral('const []'), + 'List', + ); + } + + test_field_optIn_fromOptOut() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + static const foo = 42; +} +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.5 +import 'a.dart'; + +const bar = A.foo; +'''); + + var bar = findElement.topVar('bar'); + _assertIntValue(bar, 42); + } + + test_fromEnvironment_optOut_fromOptIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' +// @dart = 2.5 + +const cBool = const bool.fromEnvironment('foo', defaultValue: false); +const cInt = const int.fromEnvironment('foo', defaultValue: 1); +const cString = const String.fromEnvironment('foo', defaultValue: 'bar'); +'''); + + await assertErrorsInCode(r''' +import 'a.dart'; + +const vBool = cBool; +const vInt = cInt; +const vString = cString; +''', [ + error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), + ]); + + DartObjectImpl evaluate(String name) { + return findElement.topVar(name).computeConstantValue() as DartObjectImpl; + } + + expect(evaluate('vBool').toBoolValue(), false); + expect(evaluate('vInt').toIntValue(), 1); + expect(evaluate('vString').toStringValue(), 'bar'); + } + + test_topLevelVariable_optIn_fromOptOut() async { + newFile('$testPackageLibPath/a.dart', content: r''' +const foo = 42; +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.5 +import 'a.dart'; + +const bar = foo; +'''); + + var bar = findElement.topVar('bar'); + assertType(bar.type, 'int*'); + _assertIntValue(bar, 42); + } + + test_topLevelVariable_optOut2() async { + newFile('$testPackageLibPath/a.dart', content: r''' +const a = 42; +'''); + + newFile('$testPackageLibPath/b.dart', content: r''' +import 'a.dart'; + +const b = a; +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.5 +import 'b.dart'; + +const c = b; +'''); + + var c = findElement.topVar('c'); + assertType(c.type, 'int*'); + _assertIntValue(c, 42); + } + + test_topLevelVariable_optOut3() async { + newFile('$testPackageLibPath/a.dart', content: r''' +// @dart = 2.7 +const a = int.fromEnvironment('a', defaultValue: 42); +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.7 +import 'a.dart'; + +const b = a; +'''); + + var c = findElement.topVar('b'); + assertType(c.type, 'int*'); + _assertIntValue(c, 42); + } + + void _assertIntValue(VariableElement element, int value) { + expect(element.computeConstantValue()!.toIntValue(), value); + } +} + +@reflectiveTest +class ConstantResolutionWithoutNullSafetyTest extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_constantValue_defaultParameter_noDefaultValue() async { newFile('$testPackageLibPath/a.dart', content: r''' @@ -251,178 +426,3 @@ void f() { '''); } } - -@reflectiveTest -class ConstantResolutionWithNullSafetyTest extends PubPackageResolutionTest { - test_constructor_nullSafe_fromLegacy_super() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - const A(List a); -} - -class B extends A { - const B(List a) : super(a); -} -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.8 -import 'a.dart'; - -const a = []; -const b = B(a); -'''); - - var b = findElement.topVar('b'); - assertType(b.computeConstantValue()!.type, 'B*'); - } - - test_constructor_nullSafe_fromLegacy_this() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - const A(List a) : this(a); - const A.second(List a); -} -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.8 -import 'a.dart'; - -const a = []; -const b = A(a); -'''); - - var b = findElement.topVar('b'); - assertType(b.computeConstantValue()!.type, 'A*'); - } - - test_context_eliminateTypeVariables() async { - await assertNoErrorsInCode(r''' -class A { - const A({List a = const []}); -} -'''); - assertType(findNode.listLiteral('const []'), 'List'); - } - - test_context_eliminateTypeVariables_functionType() async { - await assertNoErrorsInCode(r''' -class A { - const A({List a = const []}); -} -'''); - assertType( - findNode.listLiteral('const []'), - 'List', - ); - } - - test_field_optIn_fromOptOut() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - static const foo = 42; -} -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.5 -import 'a.dart'; - -const bar = A.foo; -'''); - - var bar = findElement.topVar('bar'); - _assertIntValue(bar, 42); - } - - test_fromEnvironment_optOut_fromOptIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' -// @dart = 2.5 - -const cBool = const bool.fromEnvironment('foo', defaultValue: false); -const cInt = const int.fromEnvironment('foo', defaultValue: 1); -const cString = const String.fromEnvironment('foo', defaultValue: 'bar'); -'''); - - await assertErrorsInCode(r''' -import 'a.dart'; - -const vBool = cBool; -const vInt = cInt; -const vString = cString; -''', [ - error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), - ]); - - DartObjectImpl evaluate(String name) { - return findElement.topVar(name).computeConstantValue() as DartObjectImpl; - } - - expect(evaluate('vBool').toBoolValue(), false); - expect(evaluate('vInt').toIntValue(), 1); - expect(evaluate('vString').toStringValue(), 'bar'); - } - - test_topLevelVariable_optIn_fromOptOut() async { - newFile('$testPackageLibPath/a.dart', content: r''' -const foo = 42; -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.5 -import 'a.dart'; - -const bar = foo; -'''); - - var bar = findElement.topVar('bar'); - assertType(bar.type, 'int*'); - _assertIntValue(bar, 42); - } - - test_topLevelVariable_optOut2() async { - newFile('$testPackageLibPath/a.dart', content: r''' -const a = 42; -'''); - - newFile('$testPackageLibPath/b.dart', content: r''' -import 'a.dart'; - -const b = a; -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.5 -import 'b.dart'; - -const c = b; -'''); - - var c = findElement.topVar('c'); - assertType(c.type, 'int*'); - _assertIntValue(c, 42); - } - - test_topLevelVariable_optOut3() async { - newFile('$testPackageLibPath/a.dart', content: r''' -// @dart = 2.7 -const a = int.fromEnvironment('a', defaultValue: 42); -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.7 -import 'a.dart'; - -const b = a; -'''); - - var c = findElement.topVar('b'); - assertType(c.type, 'int*'); - _assertIntValue(c, 42); - } - - void _assertIntValue(VariableElement element, int value) { - expect(element.computeConstantValue()!.toIntValue(), value); - } -} diff --git a/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart index 031eb7ed60318..0ed4d13735439 100644 --- a/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart @@ -10,49 +10,12 @@ import 'context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(FunctionExpressionInvocationTest); - defineReflectiveTests(FunctionExpressionInvocationWithNullSafetyTest); + defineReflectiveTests(FunctionExpressionInvocationWithoutNullSafetyTest); }); } @reflectiveTest -class FunctionExpressionInvocationTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { - test_dynamic_withoutTypeArguments() async { - await assertNoErrorsInCode(r''' -main() { - (main as dynamic)(0); -} -'''); - - assertFunctionExpressionInvocation( - findNode.functionExpressionInvocation('(0)'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); - } - - test_dynamic_withTypeArguments() async { - await assertNoErrorsInCode(r''' -main() { - (main as dynamic)(0); -} -'''); - - assertFunctionExpressionInvocation( - findNode.functionExpressionInvocation('(0)'), - element: null, - typeArgumentTypes: ['bool', 'int'], - invokeType: 'dynamic', - type: 'dynamic', - ); - } -} - -@reflectiveTest -class FunctionExpressionInvocationWithNullSafetyTest - extends PubPackageResolutionTest { +class FunctionExpressionInvocationTest extends PubPackageResolutionTest { test_call_infer_fromArguments() async { await assertNoErrorsInCode(r''' class A { @@ -230,3 +193,39 @@ class B { ); } } + +@reflectiveTest +class FunctionExpressionInvocationWithoutNullSafetyTest + extends PubPackageResolutionTest with WithoutNullSafetyMixin { + test_dynamic_withoutTypeArguments() async { + await assertNoErrorsInCode(r''' +main() { + (main as dynamic)(0); +} +'''); + + assertFunctionExpressionInvocation( + findNode.functionExpressionInvocation('(0)'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', + ); + } + + test_dynamic_withTypeArguments() async { + await assertNoErrorsInCode(r''' +main() { + (main as dynamic)(0); +} +'''); + + assertFunctionExpressionInvocation( + findNode.functionExpressionInvocation('(0)'), + element: null, + typeArgumentTypes: ['bool', 'int'], + invokeType: 'dynamic', + type: 'dynamic', + ); + } +} diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart index eb3fbbc3f5c15..e843e9ceecfc1 100644 --- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart @@ -13,1828 +13,1820 @@ import 'context_collection_resolution.dart'; main() { defineReflectiveSuite(() { + defineReflectiveTests(MethodInvocationResolutionWithoutNullSafetyTest); defineReflectiveTests(MethodInvocationResolutionTest); - defineReflectiveTests(MethodInvocationResolutionWithNullSafetyTest); }); } @reflectiveTest class MethodInvocationResolutionTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, MethodInvocationResolutionTestCases {} - -mixin MethodInvocationResolutionTestCases on PubPackageResolutionTest { - test_clamp_double_context_double() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(double a) { - h(a.clamp(f(), f())); -} -h(double x) {} + with MethodInvocationResolutionTestCases { + test_hasReceiver_deferredImportPrefix_loadLibrary_optIn_fromOptOut() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A {} '''); - assertTypeArgumentTypes(findNode.methodInvocation('f(),'), - [typeStringByNullability(nullable: 'double', legacy: 'num')]); - assertTypeArgumentTypes(findNode.methodInvocation('f())'), - [typeStringByNullability(nullable: 'double', legacy: 'num')]); - } + await assertErrorsInCode(r''' +// @dart = 2.7 +import 'a.dart' deferred as a; - test_clamp_double_context_int() async { - await assertErrorsInCode( - ''' -T f() => throw Error(); -g(double a) { - h(a.clamp(f(), f())); +main() { + a.loadLibrary(); } -h(int x) {} -''', - expectedErrorsByNullability(nullable: [ - error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 45, 17), - ], legacy: [])); +''', [ + error(HintCode.UNUSED_IMPORT, 22, 8), + ]); - assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); - assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); - } + var import = findElement.importFind('package:test/a.dart'); - test_clamp_double_context_none() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(double a) { - a.clamp(f(), f()); -} -'''); + var invocation = findNode.methodInvocation('loadLibrary()'); + assertImportPrefix(invocation.target, import.prefix); - assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); - assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); + assertMethodInvocation( + invocation, + import.importedLibrary.loadLibraryFunction, + 'Future* Function()*', + ); } - test_clamp_double_double_double() async { - await assertNoErrorsInCode(''' -f(double a, double b, double c) { - a.clamp(b, c); + test_hasReceiver_interfaceQ_Function_call_checked() async { + await assertNoErrorsInCode(r''' +void f(Function? foo) { + foo?.call(); } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: - typeStringByNullability(nullable: 'double', legacy: 'num')); + assertMethodInvocation2( + findNode.methodInvocation('foo?.call()'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', + ); } - test_clamp_double_double_int() async { - await assertNoErrorsInCode(''' -f(double a, double b, int c) { - a.clamp(b, c); + test_hasReceiver_interfaceQ_Function_call_unchecked() async { + await assertErrorsInCode(r''' +void f(Function? foo) { + foo.call(); } -'''); +''', [ + error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, + 30, 4), + ]); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); + assertMethodInvocation2( + findNode.methodInvocation('foo.call()'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', + ); } - test_clamp_double_int_double() async { - await assertNoErrorsInCode(''' -f(double a, int b, double c) { - a.clamp(b, c); + test_hasReceiver_interfaceQ_nullShorting() async { + await assertNoErrorsInCode(r''' +class C { + C foo() => throw 0; + C bar() => throw 0; } -'''); - - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); - } - test_clamp_double_int_int() async { - await assertNoErrorsInCode(''' -f(double a, int b, int c) { - a.clamp(b, c); +void testShort(C? c) { + c?.foo().bar(); } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); + assertMethodInvocation2( + findNode.methodInvocation('c?.foo()'), + element: findElement.method('foo'), + typeArgumentTypes: [], + invokeType: 'C Function()', + type: 'C', + ); + + assertMethodInvocation2( + findNode.methodInvocation('bar();'), + element: findElement.method('bar'), + typeArgumentTypes: [], + invokeType: 'C Function()', + type: 'C?', + ); } - test_clamp_int_context_double() async { - await assertErrorsInCode( - ''' -T f() => throw Error(); -g(int a) { - h(a.clamp(f(), f())); + test_hasReceiver_interfaceQ_nullShorting_getter() async { + await assertNoErrorsInCode(r''' +abstract class C { + void Function(C) get foo; } -h(double x) {} -''', - expectedErrorsByNullability(nullable: [ - error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 42, 17), - ], legacy: [])); - - assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); - assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); - } - test_clamp_int_context_int() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(int a) { - h(a.clamp(f(), f())); +void f(C? c) { + c?.foo(c); // 1 } -h(int x) {} '''); - assertTypeArgumentTypes(findNode.methodInvocation('f(),'), - [typeStringByNullability(nullable: 'int', legacy: 'num')]); - assertTypeArgumentTypes(findNode.methodInvocation('f())'), - [typeStringByNullability(nullable: 'int', legacy: 'num')]); - } + var invocation = findNode.functionExpressionInvocation('foo(c);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'void Function(C)'); + assertType(invocation, 'void'); - test_clamp_int_context_none() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(int a) { - a.clamp(f(), f()); -} -'''); + var foo = invocation.function as PropertyAccess; + assertType(foo, 'void Function(C)'); + assertElement(foo.propertyName, findElement.getter('foo')); + assertType(foo.propertyName, 'void Function(C)'); - assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); - assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); + assertSimpleIdentifier( + findNode.simple('c); // 1'), + element: findElement.parameter('c'), + type: 'C', + ); } - test_clamp_int_double_double() async { - await assertNoErrorsInCode(''' -f(int a, double b, double c) { - a.clamp(b, c); + test_hasReceiver_interfaceType_enum() async { + await assertNoErrorsInCode(r''' +enum E { + v; + void foo() {} +} + +void f(E e) { + e.foo(); } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); + assertMethodInvocation2( + findNode.methodInvocation('e.foo()'), + element: findElement.method('foo', of: 'E'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', + ); } - test_clamp_int_double_dynamic() async { - await assertNoErrorsInCode(''' -f(int a, double b, dynamic c) { - a.clamp(b, c); + test_hasReceiver_interfaceType_enum_fromMixin() async { + await assertNoErrorsInCode(r''' +mixin M on Enum { + void foo() {} } -'''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); - } +enum E with M { + v; +} - test_clamp_int_double_int() async { - await assertNoErrorsInCode(''' -f(int a, double b, int c) { - a.clamp(b, c); +void f(E e) { + e.foo(); } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); + assertMethodInvocation2( + findNode.methodInvocation('e.foo()'), + element: findElement.method('foo', of: 'M'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', + ); } - test_clamp_int_dynamic_double() async { - await assertNoErrorsInCode(''' -f(int a, dynamic b, double c) { - a.clamp(b, c); + test_hasReceiver_interfaceTypeQ_defined() async { + await assertErrorsInCode(r''' +class A { + void foo() {} } -'''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); +void f(A? a) { + a.foo(); +} +''', [ + error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, + 48, 3), + ]); + + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: findElement.method('foo', of: 'A'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', + ); } - test_clamp_int_dynamic_int() async { - await assertNoErrorsInCode(''' -f(int a, dynamic b, int c) { - a.clamp(b, c); + test_hasReceiver_interfaceTypeQ_defined_extension() async { + await assertErrorsInCode(r''' +class A { + void foo() {} } -'''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); - } +extension E on A { + void foo() {} +} - test_clamp_int_int_double() async { - await assertNoErrorsInCode(''' -f(int a, int b, double c) { - a.clamp(b, c); +void f(A? a) { + a.foo(); } -'''); +''', [ + error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, + 86, 3), + ]); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: findElement.method('foo', of: 'A'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', + ); } - test_clamp_int_int_dynamic() async { - await assertNoErrorsInCode(''' -f(int a, int b, dynamic c) { - a.clamp(b, c); + test_hasReceiver_interfaceTypeQ_defined_extensionQ() async { + await assertNoErrorsInCode(r''' +class A { + void foo() {} +} + +extension E on A? { + void foo() {} +} + +void f(A? a) { + a.foo(); } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: findElement.method('foo', of: 'E'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', + ); } - test_clamp_int_int_int() async { - await assertNoErrorsInCode(''' -f(int a, int b, int c) { - a.clamp(b, c); + test_hasReceiver_interfaceTypeQ_defined_extensionQ2() async { + await assertNoErrorsInCode(r''' +extension E on T? { + T foo() => throw 0; +} + +void f(int? a) { + a.foo(); } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: elementMatcher( + findElement.method('foo', of: 'E'), + substitution: {'T': 'int'}, + ), + typeArgumentTypes: [], + invokeType: 'int Function()', + type: 'int', + ); } - test_clamp_int_int_int_from_cascade() async { - await assertErrorsInCode( - ''' -f(int a, int b, int c) { - a..clamp(b, c).isEven; + test_hasReceiver_interfaceTypeQ_notDefined() async { + await assertErrorsInCode(r''' +class A {} + +void f(A? a) { + a.foo(); } -''', - expectedErrorsByNullability(nullable: [], legacy: [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 42, 6), - ])); +''', [ + error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, + 31, 3), + ]); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', + ); } - test_clamp_int_int_int_via_extension_explicit() async { - await assertNoErrorsInCode(''' -extension E on int { - String clamp(int x, int y) => ''; + test_hasReceiver_interfaceTypeQ_notDefined_extension() async { + await assertErrorsInCode(r''' +class A {} + +extension E on A { + void foo() {} } -f(int a, int b, int c) { - E(a).clamp(b, c); + +void f(A? a) { + a.foo(); } -'''); +''', [ + error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, + 69, 3), + ]); - assertMethodInvocation( - findNode.methodInvocation('clamp(b'), - elementMatcher(findElement.extension_('E').getMethod('clamp')), - 'String Function(int, int)', - expectedType: 'String'); + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', + ); } - test_clamp_int_int_never() async { - await assertNoErrorsInCode(''' -f(int a, int b, Never c) { - a.clamp(b, c); + test_hasReceiver_interfaceTypeQ_notDefined_extensionQ() async { + await assertNoErrorsInCode(r''' +class A {} + +extension E on A? { + void foo() {} +} + +void f(A? a) { + a.foo(); } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: findElement.method('foo', of: 'E'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', + ); } - test_clamp_int_never_int() async { - await assertErrorsInCode( - ''' -f(int a, Never b, int c) { - a.clamp(b, c); + test_hasReceiver_typeAlias_staticMethod() async { + await assertNoErrorsInCode(r''' +class A { + static void foo(int _) {} } -''', - expectedErrorsByNullability(nullable: [ - error(HintCode.DEAD_CODE, 40, 3), - ], legacy: [])); - assertMethodInvocation( - findNode.methodInvocation('clamp'), - elementMatcher(numElement.getMethod('clamp'), - isLegacy: isLegacyLibrary), - 'num Function(num, num)', - expectedType: 'num'); - } +typedef B = A; - test_clamp_never_int_int() async { - await assertErrorsInCode( - ''' -f(Never a, int b, int c) { - a.clamp(b, c); +void f() { + B.foo(0); } -''', - expectedErrorsByNullability(nullable: [ - error(HintCode.RECEIVER_OF_TYPE_NEVER, 29, 1), - error(HintCode.DEAD_CODE, 36, 7), - ], legacy: [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 31, 5), - ])); +'''); assertMethodInvocation( - findNode.methodInvocation('clamp'), isNull, 'dynamic', - expectedType: - typeStringByNullability(nullable: 'Never', legacy: 'dynamic')); + findNode.methodInvocation('foo(0)'), + findElement.method('foo'), + 'void Function(int)', + ); + + assertTypeAliasRef( + findNode.simple('B.foo'), + findElement.typeAlias('B'), + ); } - test_clamp_other_context_int() async { - await assertErrorsInCode( - ''' -abstract class A { - num clamp(String x, String y); -} -T f() => throw Error(); -g(A a) { - h(a.clamp(f(), f())); + test_hasReceiver_typeAlias_staticMethod_generic() async { + await assertNoErrorsInCode(r''' +class A { + static void foo(int _) {} } -h(int x) {} -''', - expectedErrorsByNullability(nullable: [ - error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 94, 17), - ], legacy: [])); - assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['String']); - assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['String']); - } +typedef B = A; - test_clamp_other_int_int() async { - await assertNoErrorsInCode(''' -abstract class A { - String clamp(int x, int y); -} -f(A a, int b, int c) { - a.clamp(b, c); +void f() { + B.foo(0); } '''); assertMethodInvocation( - findNode.methodInvocation('clamp(b'), - elementMatcher(findElement.class_('A').getMethod('clamp')), - 'String Function(int, int)', - expectedType: 'String'); + findNode.methodInvocation('foo(0)'), + findElement.method('foo'), + 'void Function(int)', + ); + + assertTypeAliasRef( + findNode.simple('B.foo'), + findElement.typeAlias('B'), + ); } - test_clamp_other_int_int_via_extension_explicit() async { + test_hasReceiver_typeParameter_promotedToNonNullable() async { await assertNoErrorsInCode(''' -class A {} -extension E on A { - String clamp(int x, int y) => ''; -} -f(A a, int b, int c) { - E(a).clamp(b, c); +void f(T? t) { + if (t is int) { + t.abs(); + } } '''); - assertMethodInvocation( - findNode.methodInvocation('clamp(b'), - elementMatcher(findElement.extension_('E').getMethod('clamp')), - 'String Function(int, int)', - expectedType: 'String'); + assertMethodInvocation2( + findNode.methodInvocation('t.abs()'), + element: intElement.getMethod('abs'), + typeArgumentTypes: [], + invokeType: 'int Function()', + type: 'int', + ); } - test_clamp_other_int_int_via_extension_implicit() async { + test_hasReceiver_typeParameter_promotedToOtherTypeParameter() async { await assertNoErrorsInCode(''' -class A {} -extension E on A { - String clamp(int x, int y) => ''; -} -f(A a, int b, int c) { - a.clamp(b, c); -} -'''); - - assertMethodInvocation( - findNode.methodInvocation('clamp(b'), - elementMatcher(findElement.extension_('E').getMethod('clamp')), - 'String Function(int, int)', - expectedType: 'String'); - } +abstract class A {} - test_demoteType() async { - await assertNoErrorsInCode(r''' -void test(T t) {} +abstract class B extends A { + void foo(); +} -void f(S s) { - if (s is int) { - test(s); +void f(T a) { + if (a is U) { + a.foo(); } } - '''); - assertTypeArgumentTypes( - findNode.methodInvocation('test(s)'), - ['S'], + assertMethodInvocation2( + findNode.methodInvocation('a.foo()'), + element: findElement.method('foo'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', ); } - test_error_ambiguousImport_topFunction() async { - newFile('$testPackageLibPath/a.dart', content: r''' -void foo(int _) {} -'''); - newFile('$testPackageLibPath/b.dart', content: r''' -void foo(int _) {} -'''); + test_namedArgument_anywhere() async { + await assertNoErrorsInCode(''' +class A {} +class B {} +class C {} +class D {} - await assertErrorsInCode(r''' -import 'a.dart'; -import 'b.dart'; +void foo(A a, B b, {C? c, D? d}) {} -main() { - foo(0); +T g1() => throw 0; +T g2() => throw 0; +T g3() => throw 0; +T g4() => throw 0; + +void f() { + foo(g1(), c: g3(), g2(), d: g4()); } -''', [ - error(CompileTimeErrorCode.AMBIGUOUS_IMPORT, 46, 3), - ]); +'''); - var invocation = findNode.methodInvocation('foo(0)'); - assertInvokeType(invocation, 'void Function(int)'); - assertType(invocation, 'void'); - } + assertMethodInvocation( + findNode.methodInvocation('foo(g'), + findElement.topFunction('foo'), + 'void Function(A, B, {C? c, D? d})', + ); - test_error_ambiguousImport_topFunction_prefixed() async { - newFile('$testPackageLibPath/a.dart', content: r''' -void foo(int _) {} -'''); - newFile('$testPackageLibPath/b.dart', content: r''' -void foo(int _) {} -'''); + var g1 = findNode.methodInvocation('g1()'); + assertType(g1, 'A'); + assertParameterElement(g1, findElement.parameter('a')); - await assertErrorsInCode(r''' -import 'a.dart' as p; -import 'b.dart' as p; + var g2 = findNode.methodInvocation('g2()'); + assertType(g2, 'B'); + assertParameterElement(g2, findElement.parameter('b')); -main() { - p.foo(0); -} -''', [ - error(CompileTimeErrorCode.AMBIGUOUS_IMPORT, 58, 3), - ]); + var named_g3 = findNode.namedExpression('c: g3()'); + assertType(named_g3.expression, 'C?'); + assertParameterElement(named_g3, findElement.parameter('c')); + assertNamedParameterRef('c:', 'c'); - var invocation = findNode.methodInvocation('foo(0)'); - assertInvokeType(invocation, 'void Function(int)'); - assertType(invocation, 'void'); + var named_g4 = findNode.namedExpression('d: g4()'); + assertType(named_g4.expression, 'D?'); + assertParameterElement(named_g4, findElement.parameter('d')); + assertNamedParameterRef('d:', 'd'); } - test_error_instanceAccessToStaticMember_method() async { - await assertErrorsInCode(r''' + test_nullShorting_cascade_firstMethodInvocation() async { + await assertNoErrorsInCode(r''' class A { - static void foo(int _) {} + int foo() => 0; + int bar() => 0; } -void f(A a) { - a.foo(0); +void f(A? a) { + a?..foo()..bar(); } -''', [ - error(CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 59, 3), - ]); +'''); + assertMethodInvocation2( - findNode.methodInvocation('a.foo(0)'), + findNode.methodInvocation('..foo()'), element: findElement.method('foo'), typeArgumentTypes: [], - invokeType: 'void Function(int)', - type: 'void', + invokeType: 'int Function()', + type: 'int', + ); + + assertMethodInvocation2( + findNode.methodInvocation('..bar()'), + element: findElement.method('bar'), + typeArgumentTypes: [], + invokeType: 'int Function()', + type: 'int', ); + + assertType(findNode.cascade('a?'), 'A?'); } - test_error_invocationOfNonFunction_interface_hasCall_field() async { - await assertErrorsInCode(r''' -class C { - void Function() call = throw Error(); + test_nullShorting_cascade_firstPropertyAccess() async { + await assertNoErrorsInCode(r''' +class A { + int get foo => 0; + int bar() => 0; } -void f(C c) { - c(); +void f(A? a) { + a?..foo..bar(); } -''', [ - error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 69, 1), - ]); +'''); - var invocation = findNode.functionExpressionInvocation('c();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); + assertPropertyAccess2( + findNode.propertyAccess('..foo'), + element: findElement.getter('foo'), + type: 'int', + ); - var cRef = invocation.function as SimpleIdentifier; - assertElement(cRef, findElement.parameter('c')); - assertType(cRef, 'C'); + assertMethodInvocation2( + findNode.methodInvocation('..bar()'), + element: findElement.method('bar'), + typeArgumentTypes: [], + invokeType: 'int Function()', + type: 'int', + ); + + assertType(findNode.cascade('a?'), 'A?'); } - test_error_invocationOfNonFunction_OK_dynamicGetter_instance() async { + test_nullShorting_cascade_nullAwareInside() async { await assertNoErrorsInCode(r''' -class C { - var foo; +class A { + int? foo() => 0; } -void f(C c) { - c.foo(); +main() { + A a = A()..foo()?.abs(); + a; } '''); - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); + assertMethodInvocation2( + findNode.methodInvocation('..foo()'), + element: findElement.method('foo'), + typeArgumentTypes: [], + invokeType: 'int? Function()', + type: 'int?', + ); - var foo = invocation.function as PropertyAccess; - assertTypeDynamic(foo); - assertElement(foo.propertyName, findElement.getter('foo')); - assertTypeDynamic(foo.propertyName); + assertMethodInvocation2( + findNode.methodInvocation('.abs()'), + element: intElement.getMethod('abs'), + typeArgumentTypes: [], + invokeType: 'int Function()', + type: 'int', + ); + + assertType(findNode.cascade('A()'), 'A'); } - test_error_invocationOfNonFunction_OK_dynamicGetter_superClass() async { - await assertNoErrorsInCode(r''' -class A { - var foo; -} + test_typeArgumentTypes_generic_inferred_leftTop_dynamic() async { + await assertNoErrorsInCode(''' +void foo(T? value) {} -class B extends A { - main() { - foo(); - } +void f(dynamic o) { + foo(o); } '''); - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.getter('foo')); - assertTypeDynamic(foo); + assertTypeArgumentTypes( + findNode.methodInvocation('foo(o)'), + ['Object'], + ); } - test_error_invocationOfNonFunction_OK_dynamicGetter_thisClass() async { - await assertNoErrorsInCode(r''' -class C { - var foo; + test_typeArgumentTypes_generic_inferred_leftTop_void() async { + await assertNoErrorsInCode(''' +void foo(List value) {} - main() { - foo(); - } +void f(List o) { + foo(o); } '''); - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.getter('foo')); - assertTypeDynamic(foo); + assertTypeArgumentTypes( + findNode.methodInvocation('foo(o)'), + ['Object'], + ); } +} - test_error_invocationOfNonFunction_OK_Function() async { - await assertNoErrorsInCode(r''' -f(Function foo) { - foo(1, 2); +mixin MethodInvocationResolutionTestCases on PubPackageResolutionTest { + test_clamp_double_context_double() async { + await assertNoErrorsInCode(''' +T f() => throw Error(); +g(double a) { + h(a.clamp(f(), f())); } +h(double x) {} '''); - var invocation = findNode.functionExpressionInvocation('foo(1, 2);'); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.parameter('foo')); - assertType(foo, 'Function'); + assertTypeArgumentTypes(findNode.methodInvocation('f(),'), + [typeStringByNullability(nullable: 'double', legacy: 'num')]); + assertTypeArgumentTypes(findNode.methodInvocation('f())'), + [typeStringByNullability(nullable: 'double', legacy: 'num')]); } - test_error_invocationOfNonFunction_OK_functionTypeTypeParameter() async { - await assertNoErrorsInCode(r''' -typedef MyFunction = double Function(int _); - -class C { - T foo; - C(this.foo); + test_clamp_double_context_int() async { + await assertErrorsInCode( + ''' +T f() => throw Error(); +g(double a) { + h(a.clamp(f(), f())); +} +h(int x) {} +''', + expectedErrorsByNullability(nullable: [ + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 45, 17), + ], legacy: [])); - main() { - foo(0); + assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); + assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); } + + test_clamp_double_context_none() async { + await assertNoErrorsInCode(''' +T f() => throw Error(); +g(double a) { + a.clamp(f(), f()); } '''); - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.getter('foo')); - assertType(foo, 'double Function(int)'); + assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); + assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); } - test_error_invocationOfNonFunction_parameter() async { - await assertErrorsInCode(r''' -main(Object foo) { - foo(); + test_clamp_double_double_double() async { + await assertNoErrorsInCode(''' +f(double a, double b, double c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 21, 3), - ]); - - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); +'''); - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.parameter('foo')); - assertType(foo, 'Object'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: + typeStringByNullability(nullable: 'double', legacy: 'num')); } - test_error_invocationOfNonFunction_parameter_dynamic() async { - await assertNoErrorsInCode(r''' -main(var foo) { - foo(); + test_clamp_double_double_int() async { + await assertNoErrorsInCode(''' +f(double a, double b, int c) { + a.clamp(b, c); } '''); - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.parameter('foo')); - assertTypeDynamic(foo); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_invocationOfNonFunction_static_hasTarget() async { - await assertErrorsInCode(r''' -class C { - static int foo = 0; -} - -main() { - C.foo(); + test_clamp_double_int_double() async { + await assertNoErrorsInCode(''' +f(double a, int b, double c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 46, 5), - ]); - - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); +'''); - var foo = invocation.function as PropertyAccess; - assertType(foo, 'int'); - assertElement(foo.propertyName, findElement.getter('foo')); - assertType(foo.propertyName, 'int'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_invocationOfNonFunction_static_noTarget() async { - await assertErrorsInCode(r''' -class C { - static int foo = 0; + test_clamp_double_int_int() async { + await assertNoErrorsInCode(''' +f(double a, int b, int c) { + a.clamp(b, c); +} +'''); - main() { - foo(); - } -} -''', [ - error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 48, 3), - ]); - - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.getter('foo')); - assertType(foo, 'int'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_invocationOfNonFunction_super_getter() async { - await assertErrorsInCode(r''' -class A { - int get foo => 0; + test_clamp_int_context_double() async { + await assertErrorsInCode( + ''' +T f() => throw Error(); +g(int a) { + h(a.clamp(f(), f())); } +h(double x) {} +''', + expectedErrorsByNullability(nullable: [ + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 42, 17), + ], legacy: [])); -class B extends A { - main() { - super.foo(); + assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); + assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); } -} -''', [ - error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 68, 9), - ]); - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); - - var foo = invocation.function as PropertyAccess; - assertType(foo, 'int'); - assertElement(foo.propertyName, findElement.getter('foo')); - assertType(foo.propertyName, 'int'); + test_clamp_int_context_int() async { + await assertNoErrorsInCode(''' +T f() => throw Error(); +g(int a) { + h(a.clamp(f(), f())); +} +h(int x) {} +'''); - assertSuperExpression(foo.target); + assertTypeArgumentTypes(findNode.methodInvocation('f(),'), + [typeStringByNullability(nullable: 'int', legacy: 'num')]); + assertTypeArgumentTypes(findNode.methodInvocation('f())'), + [typeStringByNullability(nullable: 'int', legacy: 'num')]); } - test_error_prefixIdentifierNotFollowedByDot() async { - newFile('$testPackageLibPath/a.dart', content: r''' -void foo() {} + test_clamp_int_context_none() async { + await assertNoErrorsInCode(''' +T f() => throw Error(); +g(int a) { + a.clamp(f(), f()); +} '''); - await assertErrorsInCode(r''' -import 'a.dart' as prefix; + assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['num']); + assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['num']); + } -main() { - prefix?.foo(); + test_clamp_int_double_double() async { + await assertNoErrorsInCode(''' +f(int a, double b, double c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 39, 6), - ]); - - var import = findElement.importFind('package:test/a.dart'); +'''); - var invocation = findNode.methodInvocation('foo();'); assertMethodInvocation( - invocation, - import.topFunction('foo'), - 'void Function()', - ); - assertImportPrefix(invocation.target, import.prefix); + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_prefixIdentifierNotFollowedByDot_deferred() async { - var question = typeToStringWithNullability ? '?' : ''; - await assertErrorsInCode(r''' -import 'dart:math' deferred as math; - -main() { - math?.loadLibrary(); + test_clamp_int_double_dynamic() async { + await assertNoErrorsInCode(''' +f(int a, double b, dynamic c) { + a.clamp(b, c); } -''', [ - error(HintCode.UNUSED_IMPORT, 7, 11), - error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 49, 4), - ]); - - var import = findElement.importFind('dart:math'); +'''); - var invocation = findNode.methodInvocation('loadLibrary()'); assertMethodInvocation( - invocation, - import.importedLibrary.loadLibraryFunction, - 'Future Function()', - expectedType: 'Future$question', - ); - assertImportPrefix(invocation.target, import.prefix); - } - - test_error_prefixIdentifierNotFollowedByDot_invoke() async { - await assertErrorsInCode(r''' -import 'dart:math' as foo; - -main() { - foo(); -} -''', [ - error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 39, 3), - ]); - _assertInvalidInvocation( - 'foo()', - findElement.import('dart:math').prefix, - dynamicNameType: true, - ); + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_undefinedFunction() async { - await assertErrorsInCode(r''' -main() { - foo(0); + test_clamp_int_double_int() async { + await assertNoErrorsInCode(''' +f(int a, double b, int c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 11, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0)'); - } - - test_error_undefinedFunction_hasTarget_importPrefix() async { - await assertErrorsInCode(r''' -import 'dart:math' as math; +'''); -main() { - math.foo(0); -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 45, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_undefinedIdentifier_target() async { - await assertErrorsInCode(r''' -main() { - bar.foo(0); + test_clamp_int_dynamic_double() async { + await assertNoErrorsInCode(''' +f(int a, dynamic b, double c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 11, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); - } +'''); - test_error_undefinedMethod_hasTarget_class() async { - await assertErrorsInCode(r''' -class C {} -main() { - C.foo(0); -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 24, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_undefinedMethod_hasTarget_class_arguments() async { - await assertErrorsInCode(r''' -class C {} - -int x = 0; -main() { - C.foo(x); + test_clamp_int_dynamic_int() async { + await assertNoErrorsInCode(''' +f(int a, dynamic b, int c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 36, 3), - ]); +'''); - _assertUnresolvedMethodInvocation('foo(x);'); - assertTopGetRef('x)', 'x'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_undefinedMethod_hasTarget_class_inSuperclass() async { - await assertErrorsInCode(r''' -class S { - static void foo(int _) {} + test_clamp_int_int_double() async { + await assertNoErrorsInCode(''' +f(int a, int b, double c) { + a.clamp(b, c); } +'''); -class C extends S {} - -main() { - C.foo(0); -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 76, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_undefinedMethod_hasTarget_class_typeArguments() async { - await assertErrorsInCode(r''' -class C {} - -main() { - C.foo(); + test_clamp_int_int_dynamic() async { + await assertNoErrorsInCode(''' +f(int a, int b, dynamic c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 25, 3), - ]); - - _assertUnresolvedMethodInvocation( - 'foo();', - expectedTypeArguments: ['int'], - ); - assertNamedType(findNode.namedType('int>'), intElement, 'int'); - } +'''); - test_error_undefinedMethod_hasTarget_class_typeParameter() async { - await assertErrorsInCode(r''' -class C { - static main() => C.T(); -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 34, 1), - ]); - _assertUnresolvedMethodInvocation('C.T();'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_undefinedMethod_hasTarget_instance() async { - await assertErrorsInCode(r''' -main() { - 42.foo(0); + test_clamp_int_int_int() async { + await assertNoErrorsInCode(''' +f(int a, int b, int c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 14, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); - } +'''); - test_error_undefinedMethod_hasTarget_localVariable_function() async { - await assertErrorsInCode(r''' -main() { - var v = () {}; - v.foo(0); -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 30, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); } - test_error_undefinedMethod_noTarget() async { - await assertErrorsInCode(r''' -class C { - main() { - foo(0); - } + test_clamp_int_int_int_from_cascade() async { + await assertErrorsInCode( + ''' +f(int a, int b, int c) { + a..clamp(b, c).isEven; } -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 25, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); - } +''', + expectedErrorsByNullability(nullable: [], legacy: [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 42, 6), + ])); - test_error_undefinedMethod_null() async { - await assertErrorsInCode(r''' -main() { - null.foo(); -} -''', [ - if (typeToStringWithNullability) - error(CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE, 16, 3) - else - error(CompileTimeErrorCode.UNDEFINED_METHOD, 16, 3), - ]); - _assertUnresolvedMethodInvocation('foo();'); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); } - test_error_undefinedMethod_object_call() async { - await assertErrorsInCode(r''' -main(Object o) { - o.call(); + test_clamp_int_int_int_via_extension_explicit() async { + await assertNoErrorsInCode(''' +extension E on int { + String clamp(int x, int y) => ''; } -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 21, 4), - ]); - } - - test_error_undefinedMethod_private() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - void _foo(int _) {} +f(int a, int b, int c) { + E(a).clamp(b, c); } '''); - await assertErrorsInCode(r''' -import 'a.dart'; -class B extends A { - main() { - _foo(0); - } -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 53, 4), - ]); - _assertUnresolvedMethodInvocation('_foo(0);'); + assertMethodInvocation( + findNode.methodInvocation('clamp(b'), + elementMatcher(findElement.extension_('E').getMethod('clamp')), + 'String Function(int, int)', + expectedType: 'String'); } - test_error_undefinedMethod_typeLiteral_cascadeTarget() async { - await assertErrorsInCode(r''' -class C { - static void foo() {} + test_clamp_int_int_never() async { + await assertNoErrorsInCode(''' +f(int a, int b, Never c) { + a.clamp(b, c); } +'''); -main() { - C..foo(); -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 50, 3), - ]); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_undefinedMethod_typeLiteral_conditional() async { - // When applied to a type literal, the conditional access operator '?.' - // cannot be used to access instance methods of Type. - await assertErrorsInCode(r''' -class A {} -main() { - A?.toString(); + test_clamp_int_never_int() async { + await assertErrorsInCode( + ''' +f(int a, Never b, int c) { + a.clamp(b, c); } -''', [ - error(CompileTimeErrorCode.UNDEFINED_METHOD, 25, 8), - ]); - } - - test_error_undefinedSuperMethod() async { - await assertErrorsInCode(r''' -class A {} +''', + expectedErrorsByNullability(nullable: [ + error(HintCode.DEAD_CODE, 40, 3), + ], legacy: [])); -class B extends A { - void foo(int _) { - super.foo(0); - } -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_SUPER_METHOD, 62, 3), - ]); - _assertUnresolvedMethodInvocation('foo(0);'); - assertSuperExpression(findNode.super_('super.foo')); + assertMethodInvocation( + findNode.methodInvocation('clamp'), + elementMatcher(numElement.getMethod('clamp'), + isLegacy: isLegacyLibrary), + 'num Function(num, num)', + expectedType: 'num'); } - test_error_unqualifiedReferenceToNonLocalStaticMember_method() async { - await assertErrorsInCode(r''' -class A { - static void foo() {} -} - -class B extends A { - main() { - foo(0); - } + test_clamp_never_int_int() async { + await assertErrorsInCode( + ''' +f(Never a, int b, int c) { + a.clamp(b, c); } -''', [ - error( - CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, - 71, - 3), - error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 75, 1), - ]); +''', + expectedErrorsByNullability(nullable: [ + error(HintCode.RECEIVER_OF_TYPE_NEVER, 29, 1), + error(HintCode.DEAD_CODE, 36, 7), + ], legacy: [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 31, 5), + ])); - assertMethodInvocation2( - findNode.methodInvocation('foo(0)'), - element: findElement.method('foo'), - typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', - ); + assertMethodInvocation( + findNode.methodInvocation('clamp'), isNull, 'dynamic', + expectedType: + typeStringByNullability(nullable: 'Never', legacy: 'dynamic')); } - /// The primary purpose of this test is to ensure that we are only getting a - /// single error generated when the only problem is that an imported file - /// does not exist. - test_error_uriDoesNotExist_prefixed() async { - await assertErrorsInCode(r''' -import 'missing.dart' as p; - -main() { - p.foo(1); - p.bar(2); + test_clamp_other_context_int() async { + await assertErrorsInCode( + ''' +abstract class A { + num clamp(String x, String y); } -''', [ - error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 14), - ]); - _assertUnresolvedMethodInvocation('foo(1);'); - _assertUnresolvedMethodInvocation('bar(2);'); - } +T f() => throw Error(); +g(A a) { + h(a.clamp(f(), f())); +} +h(int x) {} +''', + expectedErrorsByNullability(nullable: [ + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 94, 17), + ], legacy: [])); - /// The primary purpose of this test is to ensure that we are only getting a - /// single error generated when the only problem is that an imported file - /// does not exist. - test_error_uriDoesNotExist_show() async { - await assertErrorsInCode(r''' -import 'missing.dart' show foo, bar; + assertTypeArgumentTypes(findNode.methodInvocation('f(),'), ['String']); + assertTypeArgumentTypes(findNode.methodInvocation('f())'), ['String']); + } -main() { - foo(1); - bar(2); + test_clamp_other_int_int() async { + await assertNoErrorsInCode(''' +abstract class A { + String clamp(int x, int y); } -''', [ - error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 14), - ]); - _assertUnresolvedMethodInvocation('foo(1);'); - _assertUnresolvedMethodInvocation('bar(2);'); +f(A a, int b, int c) { + a.clamp(b, c); +} +'''); + + assertMethodInvocation( + findNode.methodInvocation('clamp(b'), + elementMatcher(findElement.class_('A').getMethod('clamp')), + 'String Function(int, int)', + expectedType: 'String'); } - test_error_useOfVoidResult_name_getter() async { - await assertErrorsInCode(''' -class C{ - T foo; - C(this.foo); + test_clamp_other_int_int_via_extension_explicit() async { + await assertNoErrorsInCode(''' +class A {} +extension E on A { + String clamp(int x, int y) => ''; } - -void f(C c) { - c.foo(); +f(A a, int b, int c) { + E(a).clamp(b, c); } -''', [ - error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 61, 5), - ]); - - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); +'''); - var foo = invocation.function as PropertyAccess; - assertType(foo, 'void'); - assertMember(foo.propertyName, findElement.getter('foo'), {'T': 'void'}); - assertType(foo.propertyName, 'void'); + assertMethodInvocation( + findNode.methodInvocation('clamp(b'), + elementMatcher(findElement.extension_('E').getMethod('clamp')), + 'String Function(int, int)', + expectedType: 'String'); } - test_error_useOfVoidResult_name_localVariable() async { - await assertErrorsInCode(r''' -main() { - void foo; - foo(); + test_clamp_other_int_int_via_extension_implicit() async { + await assertNoErrorsInCode(''' +class A {} +extension E on A { + String clamp(int x, int y) => ''; } -''', [ - error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), - ]); - - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); +f(A a, int b, int c) { + a.clamp(b, c); +} +'''); - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.localVar('foo')); - assertType(foo, 'void'); + assertMethodInvocation( + findNode.methodInvocation('clamp(b'), + elementMatcher(findElement.extension_('E').getMethod('clamp')), + 'String Function(int, int)', + expectedType: 'String'); } - test_error_useOfVoidResult_name_topFunction() async { - await assertErrorsInCode(r''' -void foo() {} + test_demoteType() async { + await assertNoErrorsInCode(r''' +void test(T t) {} -main() { - foo()(); +void f(S s) { + if (s is int) { + test(s); + } } -''', [ - error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 26, 3), - ]); - assertMethodInvocation( - findNode.methodInvocation('foo()()'), - findElement.topFunction('foo'), - 'void Function()', + +'''); + + assertTypeArgumentTypes( + findNode.methodInvocation('test(s)'), + ['S'], ); } - test_error_useOfVoidResult_name_topVariable() async { + test_error_ambiguousImport_topFunction() async { + newFile('$testPackageLibPath/a.dart', content: r''' +void foo(int _) {} +'''); + newFile('$testPackageLibPath/b.dart', content: r''' +void foo(int _) {} +'''); + await assertErrorsInCode(r''' -void foo; +import 'a.dart'; +import 'b.dart'; main() { - foo(); + foo(0); } ''', [ - error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 22, 3), + error(CompileTimeErrorCode.AMBIGUOUS_IMPORT, 46, 3), ]); - var invocation = findNode.functionExpressionInvocation('foo();'); - assertElementNull(invocation); - assertInvokeTypeDynamic(invocation); - assertTypeDynamic(invocation); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.topGet('foo')); - assertType(foo, 'void'); + var invocation = findNode.methodInvocation('foo(0)'); + assertInvokeType(invocation, 'void Function(int)'); + assertType(invocation, 'void'); } - test_error_useOfVoidResult_receiver() async { + test_error_ambiguousImport_topFunction_prefixed() async { + newFile('$testPackageLibPath/a.dart', content: r''' +void foo(int _) {} +'''); + newFile('$testPackageLibPath/b.dart', content: r''' +void foo(int _) {} +'''); + await assertErrorsInCode(r''' +import 'a.dart' as p; +import 'b.dart' as p; + main() { - void foo; - foo.toString(); + p.foo(0); } ''', [ - error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), + error(CompileTimeErrorCode.AMBIGUOUS_IMPORT, 58, 3), ]); - assertMethodInvocation2( - findNode.methodInvocation('toString()'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); + + var invocation = findNode.methodInvocation('foo(0)'); + assertInvokeType(invocation, 'void Function(int)'); + assertType(invocation, 'void'); } - test_error_useOfVoidResult_receiver_cascade() async { + test_error_instanceAccessToStaticMember_method() async { await assertErrorsInCode(r''' -main() { - void foo; - foo..toString(); +class A { + static void foo(int _) {} } -''', [ - error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), - ]); - assertMethodInvocation2( - findNode.methodInvocation('toString()'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); - } - test_error_useOfVoidResult_receiver_withNull() async { - await assertErrorsInCode(r''' -main() { - void foo; - foo?.toString(); +void f(A a) { + a.foo(0); } ''', [ - error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), + error(CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 59, 3), ]); assertMethodInvocation2( - findNode.methodInvocation('toString()'), - element: null, + findNode.methodInvocation('a.foo(0)'), + element: findElement.method('foo'), typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); - } - - test_error_wrongNumberOfTypeArgumentsMethod_01() async { - await assertErrorsInCode(r''' -void foo() {} - -main() { - foo(); -} -''', [ - error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 29, 5), - ]); - assertMethodInvocation( - findNode.methodInvocation('foo()'), - findElement.topFunction('foo'), - 'void Function()', + invokeType: 'void Function(int)', + type: 'void', ); - assertNamedType(findNode.namedType('int>'), intElement, 'int'); } - test_error_wrongNumberOfTypeArgumentsMethod_21() async { + test_error_invocationOfNonFunction_interface_hasCall_field() async { await assertErrorsInCode(r''' -Map foo() => throw Error(); +class C { + void Function() call = throw Error(); +} -main() { - foo(); +void f(C c) { + c(); } ''', [ - error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 67, 5), + error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 69, 1), ]); - assertMethodInvocation( - findNode.methodInvocation('foo()'), - findElement.topFunction('foo'), - 'Map Function()', - expectedTypeArguments: ['dynamic', 'dynamic'], - ); - assertNamedType(findNode.namedType('int>'), intElement, 'int'); + + var invocation = findNode.functionExpressionInvocation('c();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); + + var cRef = invocation.function as SimpleIdentifier; + assertElement(cRef, findElement.parameter('c')); + assertType(cRef, 'C'); } - test_hasReceiver_class_staticGetter() async { + test_error_invocationOfNonFunction_OK_dynamicGetter_instance() async { await assertNoErrorsInCode(r''' class C { - static double Function(int) get foo => throw Error(); + var foo; } -main() { - C.foo(0); +void f(C c) { + c.foo(); } '''); - var invocation = findNode.functionExpressionInvocation('foo(0);'); + var invocation = findNode.functionExpressionInvocation('foo();'); assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); var foo = invocation.function as PropertyAccess; - assertClassRef(foo.target, findElement.class_('C')); - assertType(foo, 'double Function(int)'); + assertTypeDynamic(foo); assertElement(foo.propertyName, findElement.getter('foo')); - assertType(foo.propertyName, 'double Function(int)'); + assertTypeDynamic(foo.propertyName); } - test_hasReceiver_class_staticMethod() async { + test_error_invocationOfNonFunction_OK_dynamicGetter_superClass() async { + await assertNoErrorsInCode(r''' +class A { + var foo; +} + +class B extends A { + main() { + foo(); + } +} +'''); + + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.getter('foo')); + assertTypeDynamic(foo); + } + + test_error_invocationOfNonFunction_OK_dynamicGetter_thisClass() async { await assertNoErrorsInCode(r''' class C { - static void foo(int _) {} + var foo; + + main() { + foo(); + } } +'''); -main() { - C.foo(0); + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.getter('foo')); + assertTypeDynamic(foo); + } + + test_error_invocationOfNonFunction_OK_Function() async { + await assertNoErrorsInCode(r''' +f(Function foo) { + foo(1, 2); } '''); - var invocation = findNode.methodInvocation('foo(0);'); - assertMethodInvocation( - invocation, - findElement.method('foo'), - 'void Function(int)', - ); - assertClassRef(invocation.target, findElement.class_('C')); + var invocation = findNode.functionExpressionInvocation('foo(1, 2);'); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.parameter('foo')); + assertType(foo, 'Function'); } - test_hasReceiver_deferredImportPrefix_loadLibrary() async { - await assertErrorsInCode(r''' -import 'dart:math' deferred as math; + test_error_invocationOfNonFunction_OK_functionTypeTypeParameter() async { + await assertNoErrorsInCode(r''' +typedef MyFunction = double Function(int _); -main() { - math.loadLibrary(); +class C { + T foo; + C(this.foo); + + main() { + foo(0); + } +} +'''); + + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.getter('foo')); + assertType(foo, 'double Function(int)'); + } + + test_error_invocationOfNonFunction_parameter() async { + await assertErrorsInCode(r''' +main(Object foo) { + foo(); } ''', [ - error(HintCode.UNUSED_IMPORT, 7, 11), + error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 21, 3), ]); - var import = findElement.importFind('dart:math'); + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); - var invocation = findNode.methodInvocation('loadLibrary()'); - assertImportPrefix(invocation.target, import.prefix); + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.parameter('foo')); + assertType(foo, 'Object'); + } - assertMethodInvocation( - invocation, - import.importedLibrary.loadLibraryFunction, - 'Future Function()', - ); + test_error_invocationOfNonFunction_parameter_dynamic() async { + await assertNoErrorsInCode(r''' +main(var foo) { + foo(); +} +'''); + + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.parameter('foo')); + assertTypeDynamic(foo); } - test_hasReceiver_deferredImportPrefix_loadLibrary_extraArgument() async { + test_error_invocationOfNonFunction_static_hasTarget() async { await assertErrorsInCode(r''' -import 'dart:math' deferred as math; +class C { + static int foo = 0; +} main() { - math.loadLibrary(1 + 2); + C.foo(); } ''', [ - error(HintCode.UNUSED_IMPORT, 7, 11), - error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 66, 5), + error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 46, 5), ]); - var import = findElement.importFind('dart:math'); + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); - var invocation = findNode.methodInvocation('loadLibrary(1 + 2)'); - assertImportPrefix(invocation.target, import.prefix); + var foo = invocation.function as PropertyAccess; + assertType(foo, 'int'); + assertElement(foo.propertyName, findElement.getter('foo')); + assertType(foo.propertyName, 'int'); + } - assertMethodInvocation( - invocation, - import.importedLibrary.loadLibraryFunction, - 'Future Function()', - ); + test_error_invocationOfNonFunction_static_noTarget() async { + await assertErrorsInCode(r''' +class C { + static int foo = 0; - assertType(findNode.binary('1 + 2'), 'int'); + main() { + foo(); } - - test_hasReceiver_dynamic_hash() async { - await assertNoErrorsInCode(r''' -void f(dynamic a) { - a.hash(0, 1); } -'''); - assertMethodInvocation2( - findNode.methodInvocation('hash('), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); - } +''', [ + error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 48, 3), + ]); - test_hasReceiver_functionTyped() async { - await assertNoErrorsInCode(r''' -void foo(int _) {} + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); -main() { - foo.call(0); + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.getter('foo')); + assertType(foo, 'int'); + } + + test_error_invocationOfNonFunction_super_getter() async { + await assertErrorsInCode(r''' +class A { + int get foo => 0; } -'''); - var invocation = findNode.methodInvocation('call(0)'); - assertMethodInvocation( - invocation, - null, - 'void Function(int)', - ); - assertElement(invocation.target, findElement.topFunction('foo')); - assertType(invocation.target, 'void Function(int)'); +class B extends A { + main() { + super.foo(); } +} +''', [ + error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 68, 9), + ]); - test_hasReceiver_functionTyped_generic() async { - await assertNoErrorsInCode(r''' -void foo(T _) {} + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); -main() { - foo.call(0); -} -'''); + var foo = invocation.function as PropertyAccess; + assertType(foo, 'int'); + assertElement(foo.propertyName, findElement.getter('foo')); + assertType(foo.propertyName, 'int'); - var invocation = findNode.methodInvocation('call(0)'); - assertMethodInvocation( - invocation, - null, - 'void Function(int)', - expectedTypeArguments: ['int'], - ); - assertElement(invocation.target, findElement.topFunction('foo')); - assertType(invocation.target, 'void Function(T)'); + assertSuperExpression(foo.target); } - test_hasReceiver_importPrefix_topFunction() async { + test_error_prefixIdentifierNotFollowedByDot() async { newFile('$testPackageLibPath/a.dart', content: r''' -T foo(T a, T b) => a; +void foo() {} '''); - await assertNoErrorsInCode(r''' + await assertErrorsInCode(r''' import 'a.dart' as prefix; main() { - prefix.foo(1, 2); + prefix?.foo(); } -'''); +''', [ + error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 39, 6), + ]); var import = findElement.importFind('package:test/a.dart'); - var invocation = findNode.methodInvocation('foo(1, 2)'); + var invocation = findNode.methodInvocation('foo();'); assertMethodInvocation( invocation, import.topFunction('foo'), - 'int Function(int, int)', - expectedTypeArguments: ['int'], + 'void Function()', ); assertImportPrefix(invocation.target, import.prefix); } - test_hasReceiver_importPrefix_topGetter() async { - newFile('$testPackageLibPath/a.dart', content: r''' -T Function(T a, T b) get foo => null; -'''); - - await assertNoErrorsInCode(r''' -import 'a.dart' as prefix; + test_error_prefixIdentifierNotFollowedByDot_deferred() async { + var question = typeToStringWithNullability ? '?' : ''; + await assertErrorsInCode(r''' +import 'dart:math' deferred as math; main() { - prefix.foo(1, 2); + math?.loadLibrary(); } -'''); - - var import = findElement.importFind('package:test/a.dart'); - - var invocation = findNode.functionExpressionInvocation('foo(1, 2);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'int Function(int, int)'); - assertType(invocation, 'int'); +''', [ + error(HintCode.UNUSED_IMPORT, 7, 11), + error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 49, 4), + ]); - var foo = invocation.function as PrefixedIdentifier; - assertType(foo, 'T Function(T, T)'); - assertElement(foo.identifier, import.topGet('foo')); - assertType(foo.identifier, 'T Function(T, T)'); + var import = findElement.importFind('dart:math'); - assertImportPrefix(foo.prefix, import.prefix); + var invocation = findNode.methodInvocation('loadLibrary()'); + assertMethodInvocation( + invocation, + import.importedLibrary.loadLibraryFunction, + 'Future Function()', + expectedType: 'Future$question', + ); + assertImportPrefix(invocation.target, import.prefix); } - test_hasReceiver_instance_Function_call_localVariable() async { - await assertNoErrorsInCode(r''' -void f(Function getFunction()) { - Function foo = getFunction(); + test_error_prefixIdentifierNotFollowedByDot_invoke() async { + await assertErrorsInCode(r''' +import 'dart:math' as foo; - foo.call(0); +main() { + foo(); } -'''); - _assertInvalidInvocation('call(0)', null); +''', [ + error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 39, 3), + ]); + _assertInvalidInvocation( + 'foo()', + findElement.import('dart:math').prefix, + dynamicNameType: true, + ); } - test_hasReceiver_instance_Function_call_topVariable() async { - await assertNoErrorsInCode(r''' -Function foo = throw Error(); - -void main() { - foo.call(0); + test_error_undefinedFunction() async { + await assertErrorsInCode(r''' +main() { + foo(0); } -'''); - _assertInvalidInvocation('call(0)', null); +''', [ + error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 11, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0)'); } - test_hasReceiver_instance_getter() async { - await assertNoErrorsInCode(r''' -class C { - double Function(int) get foo => throw Error(); -} + test_error_undefinedFunction_hasTarget_importPrefix() async { + await assertErrorsInCode(r''' +import 'dart:math' as math; -void f(C c) { - c.foo(0); +main() { + math.foo(0); } -'''); - - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); - - var foo = invocation.function as PropertyAccess; - assertType(foo, 'double Function(int)'); - assertElement(foo.propertyName, findElement.getter('foo')); - assertType(foo.propertyName, 'double Function(int)'); +''', [ + error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 45, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); } - /// It is important to use this expression as an initializer of a top-level - /// variable, because of the way top-level inference works, at the time of - /// writing this. We resolve initializers twice - first for dependencies, - /// then for resolution. This has its issues (for example we miss some - /// dependencies), but the important thing is that we rewrite `foo(0)` from - /// being a [MethodInvocation] to [FunctionExpressionInvocation]. So, during - /// the second pass we see [SimpleIdentifier] `foo` as a `function`. And - /// we should be aware that it is not a stand-alone identifier, but a - /// cascade section. - test_hasReceiver_instance_getter_cascade() async { - await resolveTestCode(r''' -class C { - double Function(int) get foo => 0; + test_error_undefinedIdentifier_target() async { + await assertErrorsInCode(r''' +main() { + bar.foo(0); } - -var v = C()..foo(0) = 0; -'''); - - var invocation = findNode.functionExpressionInvocation('foo(0)'); - assertFunctionExpressionInvocation( - invocation, - element: null, - typeArgumentTypes: [], - invokeType: 'double Function(int)', - type: 'double', - ); - assertSimpleIdentifier( - invocation.function, - element: findElement.getter('foo'), - type: 'double Function(int)', - ); +''', [ + error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 11, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); } - test_hasReceiver_instance_getter_switchStatementExpression() async { - await assertNoErrorsInCode(r''' -class C { - int Function() get foo => throw Error(); + test_error_undefinedMethod_hasTarget_class() async { + await assertErrorsInCode(r''' +class C {} +main() { + C.foo(0); } - -void f(C c) { - switch ( c.foo() ) { - default: - break; +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 24, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); } -} -'''); - var invocation = findNode.functionExpressionInvocation('foo()'); - assertElementNull(invocation); - assertInvokeType(invocation, 'int Function()'); - assertType(invocation, 'int'); + test_error_undefinedMethod_hasTarget_class_arguments() async { + await assertErrorsInCode(r''' +class C {} - var foo = invocation.function as PropertyAccess; - assertType(foo, 'int Function()'); - assertElement(foo.propertyName, findElement.getter('foo')); - assertType(foo.propertyName, 'int Function()'); +int x = 0; +main() { + C.foo(x); +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 36, 3), + ]); + + _assertUnresolvedMethodInvocation('foo(x);'); + assertTopGetRef('x)', 'x'); } - test_hasReceiver_instance_method() async { - await assertNoErrorsInCode(r''' -class C { - void foo(int _) {} + test_error_undefinedMethod_hasTarget_class_inSuperclass() async { + await assertErrorsInCode(r''' +class S { + static void foo(int _) {} } -void f(C c) { - c.foo(0); -} -'''); +class C extends S {} - var invocation = findNode.methodInvocation('foo(0);'); - assertMethodInvocation( - invocation, - findElement.method('foo'), - 'void Function(int)', - expectedMethodNameType: 'void Function(int)', - ); - assertTypeArgumentTypes(invocation, []); +main() { + C.foo(0); +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 76, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); } - test_hasReceiver_instance_method_generic() async { - await assertNoErrorsInCode(r''' -class C { - T foo(T a) { - return a; - } -} + test_error_undefinedMethod_hasTarget_class_typeArguments() async { + await assertErrorsInCode(r''' +class C {} -void f(C c) { - c.foo(0); +main() { + C.foo(); } -'''); +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 25, 3), + ]); - var invocation = findNode.methodInvocation('foo(0);'); - assertMethodInvocation( - invocation, - findElement.method('foo'), - 'int Function(int)', - expectedMethodNameType: 'int Function(int)', + _assertUnresolvedMethodInvocation( + 'foo();', expectedTypeArguments: ['int'], ); - assertTypeArgumentTypes(invocation, ['int']); + assertNamedType(findNode.namedType('int>'), intElement, 'int'); } - test_hasReceiver_instance_method_issue30552() async { - await assertNoErrorsInCode(r''' -abstract class I1 { - void foo(int i); + test_error_undefinedMethod_hasTarget_class_typeParameter() async { + await assertErrorsInCode(r''' +class C { + static main() => C.T(); } +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 34, 1), + ]); + _assertUnresolvedMethodInvocation('C.T();'); + } -abstract class I2 { - void foo(Object o); + test_error_undefinedMethod_hasTarget_instance() async { + await assertErrorsInCode(r''' +main() { + 42.foo(0); } +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 14, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); + } -abstract class C implements I1, I2 {} + test_error_undefinedMethod_hasTarget_localVariable_function() async { + await assertErrorsInCode(r''' +main() { + var v = () {}; + v.foo(0); +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 30, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); + } -class D extends C { - void foo(Object o) {} + test_error_undefinedMethod_noTarget() async { + await assertErrorsInCode(r''' +class C { + main() { + foo(0); + } } +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 25, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); + } -void f(C c) { - c.foo('hi'); + test_error_undefinedMethod_null() async { + await assertErrorsInCode(r''' +main() { + null.foo(); } -'''); +''', [ + if (typeToStringWithNullability) + error(CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE, 16, 3) + else + error(CompileTimeErrorCode.UNDEFINED_METHOD, 16, 3), + ]); + _assertUnresolvedMethodInvocation('foo();'); + } - var invocation = findNode.methodInvocation("foo('hi')"); - assertMethodInvocation( - invocation, - findElement.method('foo', of: 'I2'), - 'void Function(Object)', - ); + test_error_undefinedMethod_object_call() async { + await assertErrorsInCode(r''' +main(Object o) { + o.call(); +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 21, 4), + ]); } - test_hasReceiver_instance_typeParameter() async { - await assertNoErrorsInCode(r''' + test_error_undefinedMethod_private() async { + newFile('$testPackageLibPath/a.dart', content: r''' class A { - void foo(int _) {} + void _foo(int _) {} } +'''); + await assertErrorsInCode(r''' +import 'a.dart'; -class C { - T a; - C(this.a); - +class B extends A { main() { - a.foo(0); + _foo(0); } } -'''); - - var invocation = findNode.methodInvocation('foo(0);'); - assertMethodInvocation( - invocation, - findElement.method('foo'), - 'void Function(int)', - ); +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 53, 4), + ]); + _assertUnresolvedMethodInvocation('_foo(0);'); } - test_hasReceiver_prefixed_class_staticGetter() async { - newFile('$testPackageLibPath/a.dart', content: r''' + test_error_undefinedMethod_typeLiteral_cascadeTarget() async { + await assertErrorsInCode(r''' class C { - static double Function(int) get foo => null; + static void foo() {} } -'''); - await assertNoErrorsInCode(r''' -import 'a.dart' as prefix; +main() { + C..foo(); +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 50, 3), + ]); + } + test_error_undefinedMethod_typeLiteral_conditional() async { + // When applied to a type literal, the conditional access operator '?.' + // cannot be used to access instance methods of Type. + await assertErrorsInCode(r''' +class A {} main() { - prefix.C.foo(0); + A?.toString(); } -'''); +''', [ + error(CompileTimeErrorCode.UNDEFINED_METHOD, 25, 8), + ]); + } - var import = findElement.importFind('package:test/a.dart'); + test_error_undefinedSuperMethod() async { + await assertErrorsInCode(r''' +class A {} - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); +class B extends A { + void foo(int _) { + super.foo(0); + } +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_SUPER_METHOD, 62, 3), + ]); + _assertUnresolvedMethodInvocation('foo(0);'); + assertSuperExpression(findNode.super_('super.foo')); + } - var foo = invocation.function as PropertyAccess; - assertType(foo, 'double Function(int)'); - assertElement(foo.propertyName, import.class_('C').getGetter('foo')); - assertType(foo.propertyName, 'double Function(int)'); + test_error_unqualifiedReferenceToNonLocalStaticMember_method() async { + await assertErrorsInCode(r''' +class A { + static void foo() {} +} - var target = foo.target as PrefixedIdentifier; - assertImportPrefix(target.prefix, import.prefix); - assertClassRef(target.identifier, import.class_('C')); +class B extends A { + main() { + foo(0); } - - test_hasReceiver_prefixed_class_staticMethod() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class C { - static void foo(int _) => null; } -'''); +''', [ + error( + CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, + 71, + 3), + error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 75, 1), + ]); - await assertNoErrorsInCode(r''' -import 'a.dart' as prefix; + assertMethodInvocation2( + findNode.methodInvocation('foo(0)'), + element: findElement.method('foo'), + typeArgumentTypes: [], + invokeType: 'void Function()', + type: 'void', + ); + } + + /// The primary purpose of this test is to ensure that we are only getting a + /// single error generated when the only problem is that an imported file + /// does not exist. + test_error_uriDoesNotExist_prefixed() async { + await assertErrorsInCode(r''' +import 'missing.dart' as p; main() { - prefix.C.foo(0); + p.foo(1); + p.bar(2); } -'''); - - var import = findElement.importFind('package:test/a.dart'); +''', [ + error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 14), + ]); + _assertUnresolvedMethodInvocation('foo(1);'); + _assertUnresolvedMethodInvocation('bar(2);'); + } - var invocation = findNode.methodInvocation('foo(0)'); - assertMethodInvocation( - invocation, - import.class_('C').getMethod('foo'), - 'void Function(int)', - ); + /// The primary purpose of this test is to ensure that we are only getting a + /// single error generated when the only problem is that an imported file + /// does not exist. + test_error_uriDoesNotExist_show() async { + await assertErrorsInCode(r''' +import 'missing.dart' show foo, bar; - var target = invocation.target as PrefixedIdentifier; - assertImportPrefix(target.prefix, import.prefix); - assertClassRef(target.identifier, import.class_('C')); +main() { + foo(1); + bar(2); +} +''', [ + error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 14), + ]); + _assertUnresolvedMethodInvocation('foo(1);'); + _assertUnresolvedMethodInvocation('bar(2);'); } - test_hasReceiver_super_getter() async { - await assertNoErrorsInCode(r''' -class A { - double Function(int) get foo => throw Error(); + test_error_useOfVoidResult_name_getter() async { + await assertErrorsInCode(''' +class C{ + T foo; + C(this.foo); } -class B extends A { - void bar() { - super.foo(0); - } +void f(C c) { + c.foo(); } -'''); +''', [ + error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 61, 5), + ]); - var invocation = findNode.functionExpressionInvocation('foo(0);'); + var invocation = findNode.functionExpressionInvocation('foo();'); assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); var foo = invocation.function as PropertyAccess; - assertType(foo, 'double Function(int)'); - assertElement(foo.propertyName, findElement.getter('foo')); - assertType(foo.propertyName, 'double Function(int)'); - - assertSuperExpression(foo.target); + assertType(foo, 'void'); + assertMember(foo.propertyName, findElement.getter('foo'), {'T': 'void'}); + assertType(foo.propertyName, 'void'); } - test_hasReceiver_super_method() async { - await assertNoErrorsInCode(r''' -class A { - void foo(int _) {} + test_error_useOfVoidResult_name_localVariable() async { + await assertErrorsInCode(r''' +main() { + void foo; + foo(); } +''', [ + error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), + ]); -class B extends A { - void foo(int _) { - super.foo(0); + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.localVar('foo')); + assertType(foo, 'void'); } -} -'''); - var invocation = findNode.methodInvocation('foo(0);'); + test_error_useOfVoidResult_name_topFunction() async { + await assertErrorsInCode(r''' +void foo() {} + +main() { + foo()(); +} +''', [ + error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 26, 3), + ]); assertMethodInvocation( - invocation, - findElement.method('foo', of: 'A'), - 'void Function(int)', + findNode.methodInvocation('foo()()'), + findElement.topFunction('foo'), + 'void Function()', ); - assertSuperExpression(invocation.target); } - test_invalid_inDefaultValue_nullAware() async { - await assertInvalidTestCode(''' -void f({a = b?.foo()}) {} -'''); + test_error_useOfVoidResult_name_topVariable() async { + await assertErrorsInCode(r''' +void foo; + +main() { + foo(); +} +''', [ + error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 22, 3), + ]); + var invocation = findNode.functionExpressionInvocation('foo();'); + assertElementNull(invocation); + assertInvokeTypeDynamic(invocation); + assertTypeDynamic(invocation); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.topGet('foo')); + assertType(foo, 'void'); + } + + test_error_useOfVoidResult_receiver() async { + await assertErrorsInCode(r''' +main() { + void foo; + foo.toString(); +} +''', [ + error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), + ]); assertMethodInvocation2( - findNode.methodInvocation('?.foo()'), + findNode.methodInvocation('toString()'), element: null, typeArgumentTypes: [], invokeType: 'dynamic', @@ -1842,13 +1834,17 @@ void f({a = b?.foo()}) {} ); } - test_invalid_inDefaultValue_nullAware2() async { - await assertInvalidTestCode(''' -typedef void F({a = b?.foo()}); -'''); - + test_error_useOfVoidResult_receiver_cascade() async { + await assertErrorsInCode(r''' +main() { + void foo; + foo..toString(); +} +''', [ + error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), + ]); assertMethodInvocation2( - findNode.methodInvocation('?.foo()'), + findNode.methodInvocation('toString()'), element: null, typeArgumentTypes: [], invokeType: 'dynamic', @@ -1856,1220 +1852,1225 @@ typedef void F({a = b?.foo()}); ); } - test_namedArgument() async { - var question = typeToStringWithNullability ? '?' : ''; - await assertNoErrorsInCode(''' -void foo({int$question a, bool$question b}) {} - + test_error_useOfVoidResult_receiver_withNull() async { + await assertErrorsInCode(r''' main() { - foo(b: false, a: 0); + void foo; + foo?.toString(); } -'''); - - var invocation = findNode.methodInvocation('foo(b:'); - assertMethodInvocation( - invocation, - findElement.topFunction('foo'), - 'void Function({int$question a, bool$question b})', +''', [ + error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3), + ]); + assertMethodInvocation2( + findNode.methodInvocation('toString()'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', ); - assertNamedParameterRef('b: false', 'b'); - assertNamedParameterRef('a: 0', 'a'); - } - - test_noReceiver_getter_superClass() async { - await assertNoErrorsInCode(r''' -class A { - double Function(int) get foo => throw Error(); -} - -class B extends A { - void bar() { - foo(0); - } -} -'''); - - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.getter('foo')); - assertType(foo, 'double Function(int)'); - } - - test_noReceiver_getter_thisClass() async { - await assertNoErrorsInCode(r''' -class C { - double Function(int) get foo => throw Error(); - - void bar() { - foo(0); - } -} -'''); - - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.getter('foo')); - assertType(foo, 'double Function(int)'); } - test_noReceiver_importPrefix() async { + test_error_wrongNumberOfTypeArgumentsMethod_01() async { await assertErrorsInCode(r''' -import 'dart:math' as math; +void foo() {} main() { - math(); + foo(); } ''', [ - error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 40, 4), + error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 29, 5), ]); - assertElement(findNode.simple('math()'), findElement.prefix('math')); - } - - test_noReceiver_localFunction() async { - await assertNoErrorsInCode(r''' -main() { - void foo(int _) {} - - foo(0); -} -'''); - - var invocation = findNode.methodInvocation('foo(0)'); assertMethodInvocation( - invocation, - findElement.localFunction('foo'), - 'void Function(int)', + findNode.methodInvocation('foo()'), + findElement.topFunction('foo'), + 'void Function()', ); + assertNamedType(findNode.namedType('int>'), intElement, 'int'); } - test_noReceiver_localVariable_call() async { - await assertNoErrorsInCode(r''' -class C { - void call(int _) {} -} - -void f(C c) { - c(0); -} -'''); - - var invocation = findNode.functionExpressionInvocation('c(0);'); - assertElement(invocation, findElement.method('call', of: 'C')); - assertInvokeType(invocation, 'void Function(int)'); - assertType(invocation, 'void'); + test_error_wrongNumberOfTypeArgumentsMethod_21() async { + await assertErrorsInCode(r''' +Map foo() => throw Error(); - var cRef = invocation.function as SimpleIdentifier; - assertElement(cRef, findElement.parameter('c')); - assertType(cRef, 'C'); +main() { + foo(); +} +''', [ + error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 67, 5), + ]); + assertMethodInvocation( + findNode.methodInvocation('foo()'), + findElement.topFunction('foo'), + 'Map Function()', + expectedTypeArguments: ['dynamic', 'dynamic'], + ); + assertNamedType(findNode.namedType('int>'), intElement, 'int'); } - test_noReceiver_localVariable_promoted() async { + test_hasReceiver_class_staticGetter() async { await assertNoErrorsInCode(r''' +class C { + static double Function(int) get foo => throw Error(); +} + main() { - var foo; - if (foo is void Function(int)) { - foo(0); - } + C.foo(0); } '''); var invocation = findNode.functionExpressionInvocation('foo(0);'); assertElementNull(invocation); - assertInvokeType(invocation, 'void Function(int)'); - assertType(invocation, 'void'); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.localVar('foo')); - assertType(foo, 'void Function(int)'); + var foo = invocation.function as PropertyAccess; + assertClassRef(foo.target, findElement.class_('C')); + assertType(foo, 'double Function(int)'); + assertElement(foo.propertyName, findElement.getter('foo')); + assertType(foo.propertyName, 'double Function(int)'); } - test_noReceiver_method_superClass() async { + test_hasReceiver_class_staticMethod() async { await assertNoErrorsInCode(r''' -class A { - void foo(int _) {} +class C { + static void foo(int _) {} } -class B extends A { - void bar() { - foo(0); - } +main() { + C.foo(0); } '''); - var invocation = findNode.methodInvocation('foo(0)'); + var invocation = findNode.methodInvocation('foo(0);'); assertMethodInvocation( invocation, findElement.method('foo'), 'void Function(int)', ); + assertClassRef(invocation.target, findElement.class_('C')); } - test_noReceiver_method_thisClass() async { - await assertNoErrorsInCode(r''' -class C { - void foo(int _) {} + test_hasReceiver_deferredImportPrefix_loadLibrary() async { + await assertErrorsInCode(r''' +import 'dart:math' deferred as math; - void bar() { - foo(0); - } +main() { + math.loadLibrary(); } -'''); +''', [ + error(HintCode.UNUSED_IMPORT, 7, 11), + ]); + + var import = findElement.importFind('dart:math'); + + var invocation = findNode.methodInvocation('loadLibrary()'); + assertImportPrefix(invocation.target, import.prefix); - var invocation = findNode.methodInvocation('foo(0)'); assertMethodInvocation( invocation, - findElement.method('foo'), - 'void Function(int)', + import.importedLibrary.loadLibraryFunction, + 'Future Function()', ); } - test_noReceiver_parameter() async { - await assertNoErrorsInCode(r''' -void f(void Function(int) foo) { - foo(0); -} -'''); + test_hasReceiver_deferredImportPrefix_loadLibrary_extraArgument() async { + await assertErrorsInCode(r''' +import 'dart:math' deferred as math; - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'void Function(int)'); - assertType(invocation, 'void'); +main() { + math.loadLibrary(1 + 2); +} +''', [ + error(HintCode.UNUSED_IMPORT, 7, 11), + error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 66, 5), + ]); - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.parameter('foo')); - assertType(foo, 'void Function(int)'); - } + var import = findElement.importFind('dart:math'); - test_noReceiver_parameter_call_nullAware() async { - var question = typeToStringWithNullability ? '?' : ''; - await assertNoErrorsInCode(''' -double Function(int)$question foo; + var invocation = findNode.methodInvocation('loadLibrary(1 + 2)'); + assertImportPrefix(invocation.target, import.prefix); -main() { - foo?.call(1); -} - '''); + assertMethodInvocation( + invocation, + import.importedLibrary.loadLibraryFunction, + 'Future Function()', + ); - var invocation = findNode.methodInvocation('call(1)'); - if (typeToStringWithNullability) { - assertType(invocation.target, 'double Function(int)?'); - } else { - assertTypeLegacy(invocation.target); - } + assertType(findNode.binary('1 + 2'), 'int'); } - test_noReceiver_parameter_functionTyped_typedef() async { + test_hasReceiver_dynamic_hash() async { await assertNoErrorsInCode(r''' -typedef F = void Function(); - -void f(F a) { - a(); +void f(dynamic a) { + a.hash(0, 1); } '''); - - var invocation = findNode.functionExpressionInvocation('a();'); - assertFunctionExpressionInvocation( - invocation, + assertMethodInvocation2( + findNode.methodInvocation('hash('), element: null, typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', + invokeType: 'dynamic', + type: 'dynamic', ); - - var aRef = invocation.function as SimpleIdentifier; - assertElement(aRef, findElement.parameter('a')); - assertType(aRef, 'void Function()'); } - test_noReceiver_topFunction() async { + test_hasReceiver_functionTyped() async { await assertNoErrorsInCode(r''' void foo(int _) {} main() { - foo(0); + foo.call(0); } '''); - var invocation = findNode.methodInvocation('foo(0)'); + var invocation = findNode.methodInvocation('call(0)'); assertMethodInvocation( invocation, - findElement.topFunction('foo'), + null, 'void Function(int)', - expectedMethodNameType: 'void Function(int)', ); + assertElement(invocation.target, findElement.topFunction('foo')); + assertType(invocation.target, 'void Function(int)'); } - test_noReceiver_topGetter() async { + test_hasReceiver_functionTyped_generic() async { await assertNoErrorsInCode(r''' -double Function(int) get foo => throw Error(); +void foo(T _) {} main() { - foo(0); + foo.call(0); } '''); - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'double Function(int)'); - assertType(invocation, 'double'); - - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.topGet('foo')); - assertType(foo, 'double Function(int)'); + var invocation = findNode.methodInvocation('call(0)'); + assertMethodInvocation( + invocation, + null, + 'void Function(int)', + expectedTypeArguments: ['int'], + ); + assertElement(invocation.target, findElement.topFunction('foo')); + assertType(invocation.target, 'void Function(T)'); } - test_noReceiver_topVariable() async { + test_hasReceiver_importPrefix_topFunction() async { + newFile('$testPackageLibPath/a.dart', content: r''' +T foo(T a, T b) => a; +'''); + await assertNoErrorsInCode(r''' -void Function(int) foo = throw Error(); +import 'a.dart' as prefix; main() { - foo(0); + prefix.foo(1, 2); } '''); - var invocation = findNode.functionExpressionInvocation('foo(0);'); - assertElementNull(invocation); - assertInvokeType(invocation, 'void Function(int)'); - assertType(invocation, 'void'); + var import = findElement.importFind('package:test/a.dart'); - var foo = invocation.function as SimpleIdentifier; - assertElement(foo, findElement.topGet('foo')); - assertType(foo, 'void Function(int)'); + var invocation = findNode.methodInvocation('foo(1, 2)'); + assertMethodInvocation( + invocation, + import.topFunction('foo'), + 'int Function(int, int)', + expectedTypeArguments: ['int'], + ); + assertImportPrefix(invocation.target, import.prefix); } - test_objectMethodOnDynamic_argumentsDontMatch() async { + test_hasReceiver_importPrefix_topGetter() async { + newFile('$testPackageLibPath/a.dart', content: r''' +T Function(T a, T b) get foo => null; +'''); + await assertNoErrorsInCode(r''' -void f(a, int b) { - a.toString(b); +import 'a.dart' as prefix; + +main() { + prefix.foo(1, 2); } '''); - assertMethodInvocation2( - findNode.methodInvocation('toString(b)'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); - assertType(findNode.simple('b);'), 'int'); + var import = findElement.importFind('package:test/a.dart'); + + var invocation = findNode.functionExpressionInvocation('foo(1, 2);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'int Function(int, int)'); + assertType(invocation, 'int'); + + var foo = invocation.function as PrefixedIdentifier; + assertType(foo, 'T Function(T, T)'); + assertElement(foo.identifier, import.topGet('foo')); + assertType(foo.identifier, 'T Function(T, T)'); + + assertImportPrefix(foo.prefix, import.prefix); } - test_objectMethodOnDynamic_argumentsMatch() async { + test_hasReceiver_instance_Function_call_localVariable() async { await assertNoErrorsInCode(r''' -void f(a) { - a.toString(); +void f(Function getFunction()) { + Function foo = getFunction(); + + foo.call(0); } '''); - assertMethodInvocation2( - findNode.methodInvocation('toString()'), - element: elementMatcher( - objectElement.getMethod('toString'), - isLegacy: isLegacyLibrary, - ), - typeArgumentTypes: [], - invokeType: 'String Function()', - type: 'String', - ); + _assertInvalidInvocation('call(0)', null); } - test_objectMethodOnFunction() async { + test_hasReceiver_instance_Function_call_topVariable() async { await assertNoErrorsInCode(r''' -void f() {} +Function foo = throw Error(); -main() { - f.toString(); +void main() { + foo.call(0); } '''); - - var invocation = findNode.methodInvocation('toString();'); - assertMethodInvocation( - invocation, - typeProvider.objectType.getMethod('toString'), - 'String Function()', - ); + _assertInvalidInvocation('call(0)', null); } - test_remainder_int_context_cascaded() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(int a) { - h(a..remainder(f())); + test_hasReceiver_instance_getter() async { + await assertNoErrorsInCode(r''' +class C { + double Function(int) get foo => throw Error(); } -h(int x) {} -'''); - - assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); - } - test_remainder_int_context_int() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(int a) { - h(a.remainder(f())); +void f(C c) { + c.foo(0); } -h(int x) {} '''); - assertTypeArgumentTypes(findNode.methodInvocation('f()'), - [typeStringByNullability(nullable: 'int', legacy: 'num')]); + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); + + var foo = invocation.function as PropertyAccess; + assertType(foo, 'double Function(int)'); + assertElement(foo.propertyName, findElement.getter('foo')); + assertType(foo.propertyName, 'double Function(int)'); } - test_remainder_int_context_int_target_rewritten() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(int Function() a) { - h(a().remainder(f())); + /// It is important to use this expression as an initializer of a top-level + /// variable, because of the way top-level inference works, at the time of + /// writing this. We resolve initializers twice - first for dependencies, + /// then for resolution. This has its issues (for example we miss some + /// dependencies), but the important thing is that we rewrite `foo(0)` from + /// being a [MethodInvocation] to [FunctionExpressionInvocation]. So, during + /// the second pass we see [SimpleIdentifier] `foo` as a `function`. And + /// we should be aware that it is not a stand-alone identifier, but a + /// cascade section. + test_hasReceiver_instance_getter_cascade() async { + await resolveTestCode(r''' +class C { + double Function(int) get foo => 0; } -h(int x) {} + +var v = C()..foo(0) = 0; '''); - assertTypeArgumentTypes(findNode.methodInvocation('f()'), - [typeStringByNullability(nullable: 'int', legacy: 'num')]); + var invocation = findNode.functionExpressionInvocation('foo(0)'); + assertFunctionExpressionInvocation( + invocation, + element: null, + typeArgumentTypes: [], + invokeType: 'double Function(int)', + type: 'double', + ); + assertSimpleIdentifier( + invocation.function, + element: findElement.getter('foo'), + type: 'double Function(int)', + ); } - test_remainder_int_context_int_via_extension_explicit() async { - await assertErrorsInCode(''' -extension E on int { - String remainder(num x) => ''; -} -T f() => throw Error(); -g(int a) { - h(E(a).remainder(f())); + test_hasReceiver_instance_getter_switchStatementExpression() async { + await assertNoErrorsInCode(r''' +class C { + int Function() get foo => throw Error(); } -h(int x) {} -''', [ - error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 98, 19), - ]); - assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); +void f(C c) { + switch ( c.foo() ) { + default: + break; } - - test_remainder_int_context_none() async { - await assertNoErrorsInCode(''' -T f() => throw Error(); -g(int a) { - a.remainder(f()); } '''); - assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); + var invocation = findNode.functionExpressionInvocation('foo()'); + assertElementNull(invocation); + assertInvokeType(invocation, 'int Function()'); + assertType(invocation, 'int'); + + var foo = invocation.function as PropertyAccess; + assertType(foo, 'int Function()'); + assertElement(foo.propertyName, findElement.getter('foo')); + assertType(foo.propertyName, 'int Function()'); } - test_remainder_int_double() async { - await assertNoErrorsInCode(''' -f(int a, double b) { - a.remainder(b); + test_hasReceiver_instance_method() async { + await assertNoErrorsInCode(r''' +class C { + void foo(int _) {} } -'''); - - assertMethodInvocation( - findNode.methodInvocation('remainder'), - elementMatcher(numElement.getMethod('remainder'), - isLegacy: isLegacyLibrary), - 'num Function(num)', - expectedType: - typeStringByNullability(nullable: 'double', legacy: 'num')); - } - test_remainder_int_int() async { - await assertNoErrorsInCode(''' -f(int a, int b) { - a.remainder(b); +void f(C c) { + c.foo(0); } '''); + var invocation = findNode.methodInvocation('foo(0);'); assertMethodInvocation( - findNode.methodInvocation('remainder'), - elementMatcher(numElement.getMethod('remainder'), - isLegacy: isLegacyLibrary), - 'num Function(num)', - expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); + invocation, + findElement.method('foo'), + 'void Function(int)', + expectedMethodNameType: 'void Function(int)', + ); + assertTypeArgumentTypes(invocation, []); } - test_remainder_int_int_target_rewritten() async { - await assertNoErrorsInCode(''' -f(int Function() a, int b) { - a().remainder(b); + test_hasReceiver_instance_method_generic() async { + await assertNoErrorsInCode(r''' +class C { + T foo(T a) { + return a; + } +} + +void f(C c) { + c.foo(0); } '''); + var invocation = findNode.methodInvocation('foo(0);'); assertMethodInvocation( - findNode.methodInvocation('remainder'), - elementMatcher(numElement.getMethod('remainder'), - isLegacy: isLegacyLibrary), - 'num Function(num)', - expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); + invocation, + findElement.method('foo'), + 'int Function(int)', + expectedMethodNameType: 'int Function(int)', + expectedTypeArguments: ['int'], + ); + assertTypeArgumentTypes(invocation, ['int']); } - test_remainder_other_context_int_via_extension_explicit() async { - await assertErrorsInCode(''' -class A {} -extension E on A { - String remainder(num x) => ''; + test_hasReceiver_instance_method_issue30552() async { + await assertNoErrorsInCode(r''' +abstract class I1 { + void foo(int i); } -T f() => throw Error(); -g(A a) { - h(E(a).remainder(f())); + +abstract class I2 { + void foo(Object o); } -h(int x) {} -''', [ - error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 105, 19), - ]); - assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); - } +abstract class C implements I1, I2 {} - test_remainder_other_context_int_via_extension_implicit() async { - await assertErrorsInCode(''' -class A {} -extension E on A { - String remainder(num x) => ''; +class D extends C { + void foo(Object o) {} } -T f() => throw Error(); -g(A a) { - h(a.remainder(f())); + +void f(C c) { + c.foo('hi'); } -h(int x) {} -''', [ - error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 105, 16), - ]); +'''); - assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); + var invocation = findNode.methodInvocation("foo('hi')"); + assertMethodInvocation( + invocation, + findElement.method('foo', of: 'I2'), + 'void Function(Object)', + ); } - test_syntheticName() async { - // This code is invalid, and the constructor initializer has a method - // invocation with a synthetic name. But we should still resolve the - // invocation, and resolve all its arguments. - await assertErrorsInCode(r''' + test_hasReceiver_instance_typeParameter() async { + await assertNoErrorsInCode(r''' class A { - A() : B(1 + 2, [0]); + void foo(int _) {} } -''', [ - error(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 18, 1), - error(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, 18, 13), - ]); - assertMethodInvocation2( - findNode.methodInvocation(');'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); +class C { + T a; + C(this.a); + + main() { + a.foo(0); + } +} +'''); - assertType(findNode.binary('1 + 2'), 'int'); - assertType(findNode.listLiteral('[0]'), 'List'); + var invocation = findNode.methodInvocation('foo(0);'); + assertMethodInvocation( + invocation, + findElement.method('foo'), + 'void Function(int)', + ); } - test_typeArgumentTypes_generic_inferred() async { - await assertErrorsInCode(r''' -U foo(T a) => throw Error(); + test_hasReceiver_prefixed_class_staticGetter() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class C { + static double Function(int) get foo => null; +} +'''); + + await assertNoErrorsInCode(r''' +import 'a.dart' as prefix; main() { - bool v = foo(0); + prefix.C.foo(0); } -''', [ - error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 1), - ]); +'''); - var invocation = findNode.methodInvocation('foo(0)'); - assertTypeArgumentTypes(invocation, ['int', 'bool']); + var import = findElement.importFind('package:test/a.dart'); + + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); + + var foo = invocation.function as PropertyAccess; + assertType(foo, 'double Function(int)'); + assertElement(foo.propertyName, import.class_('C').getGetter('foo')); + assertType(foo.propertyName, 'double Function(int)'); + + var target = foo.target as PrefixedIdentifier; + assertImportPrefix(target.prefix, import.prefix); + assertClassRef(target.identifier, import.class_('C')); } - test_typeArgumentTypes_generic_instantiateToBounds() async { + test_hasReceiver_prefixed_class_staticMethod() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class C { + static void foo(int _) => null; +} +'''); + await assertNoErrorsInCode(r''' -void foo() {} +import 'a.dart' as prefix; main() { - foo(); + prefix.C.foo(0); } '''); - var invocation = findNode.methodInvocation('foo();'); - assertTypeArgumentTypes(invocation, ['num']); - } + var import = findElement.importFind('package:test/a.dart'); - test_typeArgumentTypes_generic_typeArguments_notBounds() async { - await assertErrorsInCode(r''' -void foo() {} + var invocation = findNode.methodInvocation('foo(0)'); + assertMethodInvocation( + invocation, + import.class_('C').getMethod('foo'), + 'void Function(int)', + ); -main() { - foo(); -} -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 45, 4), - ]); - var invocation = findNode.methodInvocation('foo();'); - assertTypeArgumentTypes(invocation, ['bool']); + var target = invocation.target as PrefixedIdentifier; + assertImportPrefix(target.prefix, import.prefix); + assertClassRef(target.identifier, import.class_('C')); } - test_typeArgumentTypes_generic_typeArguments_wrongNumber() async { - await assertErrorsInCode(r''' -void foo() {} + test_hasReceiver_super_getter() async { + await assertNoErrorsInCode(r''' +class A { + double Function(int) get foo => throw Error(); +} -main() { - foo(); +class B extends A { + void bar() { + super.foo(0); + } } -''', [ - error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 32, 13), - ]); - var invocation = findNode.methodInvocation('foo();'); - assertTypeArgumentTypes(invocation, ['dynamic']); +'''); + + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); + + var foo = invocation.function as PropertyAccess; + assertType(foo, 'double Function(int)'); + assertElement(foo.propertyName, findElement.getter('foo')); + assertType(foo.propertyName, 'double Function(int)'); + + assertSuperExpression(foo.target); } - test_typeArgumentTypes_notGeneric() async { + test_hasReceiver_super_method() async { await assertNoErrorsInCode(r''' -void foo(int a) {} - -main() { - foo(0); +class A { + void foo(int _) {} } -'''); - var invocation = findNode.methodInvocation('foo(0)'); - assertTypeArgumentTypes(invocation, []); +class B extends A { + void foo(int _) { + super.foo(0); } +} +'''); - void _assertInvalidInvocation(String search, Element? expectedElement, - {String? expectedMethodNameType, - String? expectedNameType, - List expectedTypeArguments = const [], - bool dynamicNameType = false}) { - var invocation = findNode.methodInvocation(search); - if (dynamicNameType) { - assertTypeDynamic(invocation.methodName); - } - // TODO(scheglov) I think `invokeType` should be `null`. + var invocation = findNode.methodInvocation('foo(0);'); assertMethodInvocation( invocation, - expectedElement, - 'dynamic', - expectedMethodNameType: expectedMethodNameType, - expectedNameType: expectedNameType, - expectedType: 'dynamic', - expectedTypeArguments: expectedTypeArguments, + findElement.method('foo', of: 'A'), + 'void Function(int)', ); - assertTypeArgumentTypes(invocation, expectedTypeArguments); + assertSuperExpression(invocation.target); } - void _assertUnresolvedMethodInvocation( - String search, { - List expectedTypeArguments = const [], - }) { - // TODO(scheglov) clean up - _assertInvalidInvocation( - search, - null, - expectedTypeArguments: expectedTypeArguments, + test_invalid_inDefaultValue_nullAware() async { + await assertInvalidTestCode(''' +void f({a = b?.foo()}) {} +'''); + + assertMethodInvocation2( + findNode.methodInvocation('?.foo()'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', ); -// var invocation = findNode.methodInvocation(search); -// assertTypeDynamic(invocation.methodName); -// // TODO(scheglov) I think `invokeType` should be `null`. -// assertMethodInvocation( -// invocation, -// null, -// 'dynamic', -// expectedType: 'dynamic', -// ); } -} -@reflectiveTest -class MethodInvocationResolutionWithNullSafetyTest - extends PubPackageResolutionTest with MethodInvocationResolutionTestCases { - test_hasReceiver_deferredImportPrefix_loadLibrary_optIn_fromOptOut() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A {} + test_invalid_inDefaultValue_nullAware2() async { + await assertInvalidTestCode(''' +typedef void F({a = b?.foo()}); '''); - await assertErrorsInCode(r''' -// @dart = 2.7 -import 'a.dart' deferred as a; + assertMethodInvocation2( + findNode.methodInvocation('?.foo()'), + element: null, + typeArgumentTypes: [], + invokeType: 'dynamic', + type: 'dynamic', + ); + } + + test_namedArgument() async { + var question = typeToStringWithNullability ? '?' : ''; + await assertNoErrorsInCode(''' +void foo({int$question a, bool$question b}) {} main() { - a.loadLibrary(); + foo(b: false, a: 0); } -''', [ - error(HintCode.UNUSED_IMPORT, 22, 8), - ]); - - var import = findElement.importFind('package:test/a.dart'); - - var invocation = findNode.methodInvocation('loadLibrary()'); - assertImportPrefix(invocation.target, import.prefix); +'''); + var invocation = findNode.methodInvocation('foo(b:'); assertMethodInvocation( invocation, - import.importedLibrary.loadLibraryFunction, - 'Future* Function()*', + findElement.topFunction('foo'), + 'void Function({int$question a, bool$question b})', ); + assertNamedParameterRef('b: false', 'b'); + assertNamedParameterRef('a: 0', 'a'); } - test_hasReceiver_interfaceQ_Function_call_checked() async { + test_noReceiver_getter_superClass() async { await assertNoErrorsInCode(r''' -void f(Function? foo) { - foo?.call(); +class A { + double Function(int) get foo => throw Error(); +} + +class B extends A { + void bar() { + foo(0); + } +} +'''); + + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.getter('foo')); + assertType(foo, 'double Function(int)'); + } + + test_noReceiver_getter_thisClass() async { + await assertNoErrorsInCode(r''' +class C { + double Function(int) get foo => throw Error(); + + void bar() { + foo(0); + } } '''); - assertMethodInvocation2( - findNode.methodInvocation('foo?.call()'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.getter('foo')); + assertType(foo, 'double Function(int)'); } - test_hasReceiver_interfaceQ_Function_call_unchecked() async { + test_noReceiver_importPrefix() async { await assertErrorsInCode(r''' -void f(Function? foo) { - foo.call(); +import 'dart:math' as math; + +main() { + math(); } ''', [ - error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, - 30, 4), + error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 40, 4), ]); + assertElement(findNode.simple('math()'), findElement.prefix('math')); + } - assertMethodInvocation2( - findNode.methodInvocation('foo.call()'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', + test_noReceiver_localFunction() async { + await assertNoErrorsInCode(r''' +main() { + void foo(int _) {} + + foo(0); +} +'''); + + var invocation = findNode.methodInvocation('foo(0)'); + assertMethodInvocation( + invocation, + findElement.localFunction('foo'), + 'void Function(int)', ); } - test_hasReceiver_interfaceQ_nullShorting() async { + test_noReceiver_localVariable_call() async { await assertNoErrorsInCode(r''' class C { - C foo() => throw 0; - C bar() => throw 0; + void call(int _) {} } -void testShort(C? c) { - c?.foo().bar(); +void f(C c) { + c(0); } '''); - assertMethodInvocation2( - findNode.methodInvocation('c?.foo()'), - element: findElement.method('foo'), - typeArgumentTypes: [], - invokeType: 'C Function()', - type: 'C', - ); + var invocation = findNode.functionExpressionInvocation('c(0);'); + assertElement(invocation, findElement.method('call', of: 'C')); + assertInvokeType(invocation, 'void Function(int)'); + assertType(invocation, 'void'); - assertMethodInvocation2( - findNode.methodInvocation('bar();'), - element: findElement.method('bar'), - typeArgumentTypes: [], - invokeType: 'C Function()', - type: 'C?', - ); + var cRef = invocation.function as SimpleIdentifier; + assertElement(cRef, findElement.parameter('c')); + assertType(cRef, 'C'); } - test_hasReceiver_interfaceQ_nullShorting_getter() async { + test_noReceiver_localVariable_promoted() async { await assertNoErrorsInCode(r''' -abstract class C { - void Function(C) get foo; -} - -void f(C? c) { - c?.foo(c); // 1 +main() { + var foo; + if (foo is void Function(int)) { + foo(0); + } } '''); - var invocation = findNode.functionExpressionInvocation('foo(c);'); + var invocation = findNode.functionExpressionInvocation('foo(0);'); assertElementNull(invocation); - assertInvokeType(invocation, 'void Function(C)'); + assertInvokeType(invocation, 'void Function(int)'); assertType(invocation, 'void'); - var foo = invocation.function as PropertyAccess; - assertType(foo, 'void Function(C)'); - assertElement(foo.propertyName, findElement.getter('foo')); - assertType(foo.propertyName, 'void Function(C)'); - - assertSimpleIdentifier( - findNode.simple('c); // 1'), - element: findElement.parameter('c'), - type: 'C', - ); + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.localVar('foo')); + assertType(foo, 'void Function(int)'); } - test_hasReceiver_interfaceType_enum() async { + test_noReceiver_method_superClass() async { await assertNoErrorsInCode(r''' -enum E { - v; - void foo() {} +class A { + void foo(int _) {} } -void f(E e) { - e.foo(); +class B extends A { + void bar() { + foo(0); + } } '''); - assertMethodInvocation2( - findNode.methodInvocation('e.foo()'), - element: findElement.method('foo', of: 'E'), - typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', + var invocation = findNode.methodInvocation('foo(0)'); + assertMethodInvocation( + invocation, + findElement.method('foo'), + 'void Function(int)', ); } - test_hasReceiver_interfaceType_enum_fromMixin() async { + test_noReceiver_method_thisClass() async { await assertNoErrorsInCode(r''' -mixin M on Enum { - void foo() {} -} - -enum E with M { - v; -} +class C { + void foo(int _) {} -void f(E e) { - e.foo(); + void bar() { + foo(0); + } } '''); - assertMethodInvocation2( - findNode.methodInvocation('e.foo()'), - element: findElement.method('foo', of: 'M'), - typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', + var invocation = findNode.methodInvocation('foo(0)'); + assertMethodInvocation( + invocation, + findElement.method('foo'), + 'void Function(int)', ); } - test_hasReceiver_interfaceTypeQ_defined() async { - await assertErrorsInCode(r''' -class A { - void foo() {} + test_noReceiver_parameter() async { + await assertNoErrorsInCode(r''' +void f(void Function(int) foo) { + foo(0); } +'''); -void f(A? a) { - a.foo(); -} -''', [ - error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, - 48, 3), - ]); + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'void Function(int)'); + assertType(invocation, 'void'); - assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), - element: findElement.method('foo', of: 'A'), - typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', - ); + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.parameter('foo')); + assertType(foo, 'void Function(int)'); } - test_hasReceiver_interfaceTypeQ_defined_extension() async { - await assertErrorsInCode(r''' -class A { - void foo() {} -} - -extension E on A { - void foo() {} -} + test_noReceiver_parameter_call_nullAware() async { + var question = typeToStringWithNullability ? '?' : ''; + await assertNoErrorsInCode(''' +double Function(int)$question foo; -void f(A? a) { - a.foo(); +main() { + foo?.call(1); } -''', [ - error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, - 86, 3), - ]); + '''); - assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), - element: findElement.method('foo', of: 'A'), - typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', - ); + var invocation = findNode.methodInvocation('call(1)'); + if (typeToStringWithNullability) { + assertType(invocation.target, 'double Function(int)?'); + } else { + assertTypeLegacy(invocation.target); + } } - test_hasReceiver_interfaceTypeQ_defined_extensionQ() async { + test_noReceiver_parameter_functionTyped_typedef() async { await assertNoErrorsInCode(r''' -class A { - void foo() {} -} - -extension E on A? { - void foo() {} -} +typedef F = void Function(); -void f(A? a) { - a.foo(); +void f(F a) { + a(); } '''); - assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), - element: findElement.method('foo', of: 'E'), + var invocation = findNode.functionExpressionInvocation('a();'); + assertFunctionExpressionInvocation( + invocation, + element: null, typeArgumentTypes: [], invokeType: 'void Function()', type: 'void', ); + + var aRef = invocation.function as SimpleIdentifier; + assertElement(aRef, findElement.parameter('a')); + assertType(aRef, 'void Function()'); } - test_hasReceiver_interfaceTypeQ_defined_extensionQ2() async { + test_noReceiver_topFunction() async { await assertNoErrorsInCode(r''' -extension E on T? { - T foo() => throw 0; -} +void foo(int _) {} -void f(int? a) { - a.foo(); +main() { + foo(0); } '''); - assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), - element: elementMatcher( - findElement.method('foo', of: 'E'), - substitution: {'T': 'int'}, - ), - typeArgumentTypes: [], - invokeType: 'int Function()', - type: 'int', + var invocation = findNode.methodInvocation('foo(0)'); + assertMethodInvocation( + invocation, + findElement.topFunction('foo'), + 'void Function(int)', + expectedMethodNameType: 'void Function(int)', ); } - test_hasReceiver_interfaceTypeQ_notDefined() async { - await assertErrorsInCode(r''' -class A {} + test_noReceiver_topGetter() async { + await assertNoErrorsInCode(r''' +double Function(int) get foo => throw Error(); -void f(A? a) { - a.foo(); +main() { + foo(0); } -''', [ - error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, - 31, 3), - ]); +'''); - assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), - element: null, - typeArgumentTypes: [], - invokeType: 'dynamic', - type: 'dynamic', - ); + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'double Function(int)'); + assertType(invocation, 'double'); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.topGet('foo')); + assertType(foo, 'double Function(int)'); } - test_hasReceiver_interfaceTypeQ_notDefined_extension() async { - await assertErrorsInCode(r''' -class A {} + test_noReceiver_topVariable() async { + await assertNoErrorsInCode(r''' +void Function(int) foo = throw Error(); -extension E on A { - void foo() {} +main() { + foo(0); } +'''); -void f(A? a) { - a.foo(); -} -''', [ - error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE, - 69, 3), - ]); + var invocation = findNode.functionExpressionInvocation('foo(0);'); + assertElementNull(invocation); + assertInvokeType(invocation, 'void Function(int)'); + assertType(invocation, 'void'); + + var foo = invocation.function as SimpleIdentifier; + assertElement(foo, findElement.topGet('foo')); + assertType(foo, 'void Function(int)'); + } + test_objectMethodOnDynamic_argumentsDontMatch() async { + await assertNoErrorsInCode(r''' +void f(a, int b) { + a.toString(b); +} +'''); assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), + findNode.methodInvocation('toString(b)'), element: null, typeArgumentTypes: [], invokeType: 'dynamic', type: 'dynamic', ); + + assertType(findNode.simple('b);'), 'int'); } - test_hasReceiver_interfaceTypeQ_notDefined_extensionQ() async { + test_objectMethodOnDynamic_argumentsMatch() async { await assertNoErrorsInCode(r''' -class A {} - -extension E on A? { - void foo() {} -} - -void f(A? a) { - a.foo(); +void f(a) { + a.toString(); } '''); - assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), - element: findElement.method('foo', of: 'E'), + findNode.methodInvocation('toString()'), + element: elementMatcher( + objectElement.getMethod('toString'), + isLegacy: isLegacyLibrary, + ), typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', + invokeType: 'String Function()', + type: 'String', ); } - test_hasReceiver_typeAlias_staticMethod() async { + test_objectMethodOnFunction() async { await assertNoErrorsInCode(r''' -class A { - static void foo(int _) {} -} - -typedef B = A; +void f() {} -void f() { - B.foo(0); +main() { + f.toString(); } '''); + var invocation = findNode.methodInvocation('toString();'); assertMethodInvocation( - findNode.methodInvocation('foo(0)'), - findElement.method('foo'), - 'void Function(int)', - ); - - assertTypeAliasRef( - findNode.simple('B.foo'), - findElement.typeAlias('B'), + invocation, + typeProvider.objectType.getMethod('toString'), + 'String Function()', ); } - test_hasReceiver_typeAlias_staticMethod_generic() async { - await assertNoErrorsInCode(r''' -class A { - static void foo(int _) {} + test_remainder_int_context_cascaded() async { + await assertNoErrorsInCode(''' +T f() => throw Error(); +g(int a) { + h(a..remainder(f())); } +h(int x) {} +'''); -typedef B = A; + assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); + } -void f() { - B.foo(0); + test_remainder_int_context_int() async { + await assertNoErrorsInCode(''' +T f() => throw Error(); +g(int a) { + h(a.remainder(f())); } +h(int x) {} '''); - assertMethodInvocation( - findNode.methodInvocation('foo(0)'), - findElement.method('foo'), - 'void Function(int)', - ); - - assertTypeAliasRef( - findNode.simple('B.foo'), - findElement.typeAlias('B'), - ); + assertTypeArgumentTypes(findNode.methodInvocation('f()'), + [typeStringByNullability(nullable: 'int', legacy: 'num')]); } - test_hasReceiver_typeParameter_promotedToNonNullable() async { + test_remainder_int_context_int_target_rewritten() async { await assertNoErrorsInCode(''' -void f(T? t) { - if (t is int) { - t.abs(); - } +T f() => throw Error(); +g(int Function() a) { + h(a().remainder(f())); } +h(int x) {} '''); - assertMethodInvocation2( - findNode.methodInvocation('t.abs()'), - element: intElement.getMethod('abs'), - typeArgumentTypes: [], - invokeType: 'int Function()', - type: 'int', - ); + assertTypeArgumentTypes(findNode.methodInvocation('f()'), + [typeStringByNullability(nullable: 'int', legacy: 'num')]); } - test_hasReceiver_typeParameter_promotedToOtherTypeParameter() async { - await assertNoErrorsInCode(''' -abstract class A {} - -abstract class B extends A { - void foo(); + test_remainder_int_context_int_via_extension_explicit() async { + await assertErrorsInCode(''' +extension E on int { + String remainder(num x) => ''; +} +T f() => throw Error(); +g(int a) { + h(E(a).remainder(f())); } +h(int x) {} +''', [ + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 98, 19), + ]); -void f(T a) { - if (a is U) { - a.foo(); + assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); } + + test_remainder_int_context_none() async { + await assertNoErrorsInCode(''' +T f() => throw Error(); +g(int a) { + a.remainder(f()); } '''); - assertMethodInvocation2( - findNode.methodInvocation('a.foo()'), - element: findElement.method('foo'), - typeArgumentTypes: [], - invokeType: 'void Function()', - type: 'void', - ); + assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); } - test_namedArgument_anywhere() async { + test_remainder_int_double() async { await assertNoErrorsInCode(''' -class A {} -class B {} -class C {} -class D {} +f(int a, double b) { + a.remainder(b); +} +'''); -void foo(A a, B b, {C? c, D? d}) {} + assertMethodInvocation( + findNode.methodInvocation('remainder'), + elementMatcher(numElement.getMethod('remainder'), + isLegacy: isLegacyLibrary), + 'num Function(num)', + expectedType: + typeStringByNullability(nullable: 'double', legacy: 'num')); + } -T g1() => throw 0; -T g2() => throw 0; -T g3() => throw 0; -T g4() => throw 0; + test_remainder_int_int() async { + await assertNoErrorsInCode(''' +f(int a, int b) { + a.remainder(b); +} +'''); + + assertMethodInvocation( + findNode.methodInvocation('remainder'), + elementMatcher(numElement.getMethod('remainder'), + isLegacy: isLegacyLibrary), + 'num Function(num)', + expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); + } -void f() { - foo(g1(), c: g3(), g2(), d: g4()); + test_remainder_int_int_target_rewritten() async { + await assertNoErrorsInCode(''' +f(int Function() a, int b) { + a().remainder(b); } '''); assertMethodInvocation( - findNode.methodInvocation('foo(g'), - findElement.topFunction('foo'), - 'void Function(A, B, {C? c, D? d})', - ); + findNode.methodInvocation('remainder'), + elementMatcher(numElement.getMethod('remainder'), + isLegacy: isLegacyLibrary), + 'num Function(num)', + expectedType: typeStringByNullability(nullable: 'int', legacy: 'num')); + } - var g1 = findNode.methodInvocation('g1()'); - assertType(g1, 'A'); - assertParameterElement(g1, findElement.parameter('a')); + test_remainder_other_context_int_via_extension_explicit() async { + await assertErrorsInCode(''' +class A {} +extension E on A { + String remainder(num x) => ''; +} +T f() => throw Error(); +g(A a) { + h(E(a).remainder(f())); +} +h(int x) {} +''', [ + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 105, 19), + ]); - var g2 = findNode.methodInvocation('g2()'); - assertType(g2, 'B'); - assertParameterElement(g2, findElement.parameter('b')); + assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); + } - var named_g3 = findNode.namedExpression('c: g3()'); - assertType(named_g3.expression, 'C?'); - assertParameterElement(named_g3, findElement.parameter('c')); - assertNamedParameterRef('c:', 'c'); + test_remainder_other_context_int_via_extension_implicit() async { + await assertErrorsInCode(''' +class A {} +extension E on A { + String remainder(num x) => ''; +} +T f() => throw Error(); +g(A a) { + h(a.remainder(f())); +} +h(int x) {} +''', [ + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 105, 16), + ]); - var named_g4 = findNode.namedExpression('d: g4()'); - assertType(named_g4.expression, 'D?'); - assertParameterElement(named_g4, findElement.parameter('d')); - assertNamedParameterRef('d:', 'd'); + assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['num']); } - test_nullShorting_cascade_firstMethodInvocation() async { - await assertNoErrorsInCode(r''' + test_syntheticName() async { + // This code is invalid, and the constructor initializer has a method + // invocation with a synthetic name. But we should still resolve the + // invocation, and resolve all its arguments. + await assertErrorsInCode(r''' class A { - int foo() => 0; - int bar() => 0; -} - -void f(A? a) { - a?..foo()..bar(); + A() : B(1 + 2, [0]); } -'''); - - assertMethodInvocation2( - findNode.methodInvocation('..foo()'), - element: findElement.method('foo'), - typeArgumentTypes: [], - invokeType: 'int Function()', - type: 'int', - ); +''', [ + error(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 18, 1), + error(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, 18, 13), + ]); assertMethodInvocation2( - findNode.methodInvocation('..bar()'), - element: findElement.method('bar'), + findNode.methodInvocation(');'), + element: null, typeArgumentTypes: [], - invokeType: 'int Function()', - type: 'int', + invokeType: 'dynamic', + type: 'dynamic', ); - assertType(findNode.cascade('a?'), 'A?'); + assertType(findNode.binary('1 + 2'), 'int'); + assertType(findNode.listLiteral('[0]'), 'List'); } - test_nullShorting_cascade_firstPropertyAccess() async { - await assertNoErrorsInCode(r''' -class A { - int get foo => 0; - int bar() => 0; -} + test_typeArgumentTypes_generic_inferred() async { + await assertErrorsInCode(r''' +U foo(T a) => throw Error(); -void f(A? a) { - a?..foo..bar(); +main() { + bool v = foo(0); } -'''); - - assertPropertyAccess2( - findNode.propertyAccess('..foo'), - element: findElement.getter('foo'), - type: 'int', - ); - - assertMethodInvocation2( - findNode.methodInvocation('..bar()'), - element: findElement.method('bar'), - typeArgumentTypes: [], - invokeType: 'int Function()', - type: 'int', - ); +''', [ + error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 1), + ]); - assertType(findNode.cascade('a?'), 'A?'); + var invocation = findNode.methodInvocation('foo(0)'); + assertTypeArgumentTypes(invocation, ['int', 'bool']); } - test_nullShorting_cascade_nullAwareInside() async { + test_typeArgumentTypes_generic_instantiateToBounds() async { await assertNoErrorsInCode(r''' -class A { - int? foo() => 0; -} +void foo() {} main() { - A a = A()..foo()?.abs(); - a; + foo(); } '''); - assertMethodInvocation2( - findNode.methodInvocation('..foo()'), - element: findElement.method('foo'), - typeArgumentTypes: [], - invokeType: 'int? Function()', - type: 'int?', - ); + var invocation = findNode.methodInvocation('foo();'); + assertTypeArgumentTypes(invocation, ['num']); + } - assertMethodInvocation2( - findNode.methodInvocation('.abs()'), - element: intElement.getMethod('abs'), - typeArgumentTypes: [], - invokeType: 'int Function()', - type: 'int', - ); + test_typeArgumentTypes_generic_typeArguments_notBounds() async { + await assertErrorsInCode(r''' +void foo() {} - assertType(findNode.cascade('A()'), 'A'); +main() { + foo(); +} +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 45, 4), + ]); + var invocation = findNode.methodInvocation('foo();'); + assertTypeArgumentTypes(invocation, ['bool']); } - test_typeArgumentTypes_generic_inferred_leftTop_dynamic() async { - await assertNoErrorsInCode(''' -void foo(T? value) {} + test_typeArgumentTypes_generic_typeArguments_wrongNumber() async { + await assertErrorsInCode(r''' +void foo() {} -void f(dynamic o) { - foo(o); +main() { + foo(); } -'''); - - assertTypeArgumentTypes( - findNode.methodInvocation('foo(o)'), - ['Object'], - ); +''', [ + error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 32, 13), + ]); + var invocation = findNode.methodInvocation('foo();'); + assertTypeArgumentTypes(invocation, ['dynamic']); } - test_typeArgumentTypes_generic_inferred_leftTop_void() async { - await assertNoErrorsInCode(''' -void foo(List value) {} + test_typeArgumentTypes_notGeneric() async { + await assertNoErrorsInCode(r''' +void foo(int a) {} -void f(List o) { - foo(o); +main() { + foo(0); } '''); - assertTypeArgumentTypes( - findNode.methodInvocation('foo(o)'), - ['Object'], + var invocation = findNode.methodInvocation('foo(0)'); + assertTypeArgumentTypes(invocation, []); + } + + void _assertInvalidInvocation(String search, Element? expectedElement, + {String? expectedMethodNameType, + String? expectedNameType, + List expectedTypeArguments = const [], + bool dynamicNameType = false}) { + var invocation = findNode.methodInvocation(search); + if (dynamicNameType) { + assertTypeDynamic(invocation.methodName); + } + // TODO(scheglov) I think `invokeType` should be `null`. + assertMethodInvocation( + invocation, + expectedElement, + 'dynamic', + expectedMethodNameType: expectedMethodNameType, + expectedNameType: expectedNameType, + expectedType: 'dynamic', + expectedTypeArguments: expectedTypeArguments, + ); + assertTypeArgumentTypes(invocation, expectedTypeArguments); + } + + void _assertUnresolvedMethodInvocation( + String search, { + List expectedTypeArguments = const [], + }) { + // TODO(scheglov) clean up + _assertInvalidInvocation( + search, + null, + expectedTypeArguments: expectedTypeArguments, ); +// var invocation = findNode.methodInvocation(search); +// assertTypeDynamic(invocation.methodName); +// // TODO(scheglov) I think `invokeType` should be `null`. +// assertMethodInvocation( +// invocation, +// null, +// 'dynamic', +// expectedType: 'dynamic', +// ); } } + +@reflectiveTest +class MethodInvocationResolutionWithoutNullSafetyTest + extends PubPackageResolutionTest + with WithoutNullSafetyMixin, MethodInvocationResolutionTestCases {} diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart index 45cef2a8181cf..c189677943abd 100644 --- a/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart @@ -8,14 +8,14 @@ import '../context_collection_resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(ForElementWithNullSafetyTest); - defineReflectiveTests(IfElementWithNullSafetyTest); - defineReflectiveTests(SpreadElementWithNullSafetyTest); + defineReflectiveTests(ForElementTest); + defineReflectiveTests(IfElementTest); + defineReflectiveTests(SpreadElementTest); }); } @reflectiveTest -class ForElementWithNullSafetyTest extends PubPackageResolutionTest { +class ForElementTest extends PubPackageResolutionTest { test_list_awaitForIn_dynamic_downward() async { await resolveTestCode(''' void f() async { @@ -192,7 +192,7 @@ T a() => throw ''; } @reflectiveTest -class IfElementWithNullSafetyTest extends PubPackageResolutionTest { +class IfElementTest extends PubPackageResolutionTest { test_list_downward() async { await resolveTestCode(''' void f() { @@ -228,7 +228,7 @@ T a() => throw ''; } @reflectiveTest -class SpreadElementWithNullSafetyTest extends PubPackageResolutionTest { +class SpreadElementTest extends PubPackageResolutionTest { test_list_downward() async { await resolveTestCode(''' void f() { diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart index 7db248ab3dafb..93b026cf174ac 100644 --- a/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart @@ -8,12 +8,12 @@ import '../context_collection_resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(ThrowWithNullSafetyTest); + defineReflectiveTests(ThrowTest); }); } @reflectiveTest -class ThrowWithNullSafetyTest extends PubPackageResolutionTest { +class ThrowTest extends PubPackageResolutionTest { test_downward() async { await resolveTestCode(''' void f() { diff --git a/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart index ae2f29457c708..3cf147ad8e644 100644 --- a/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart +++ b/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart @@ -10,13 +10,40 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(AssignmentToFinalLocalTest); - defineReflectiveTests(AssignmentToFinalLocalWithNullSafetyTest); + defineReflectiveTests(AssignmentToFinalLocalWithoutNullSafetyTest); }); } @reflectiveTest -class AssignmentToFinalLocalTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { +class AssignmentToFinalLocalTest extends PubPackageResolutionTest { + test_localVariable_late() async { + await assertNoErrorsInCode(''' +void f() { + late final int a; + a = 1; + a; +} +'''); + } + + test_parameter_superFormal() async { + await assertErrorsInCode(''' +class A { + A(int a); +} +class B extends A { + var x; + B(super.a) : x = (() { a = 0; }); +} +''', [ + error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 78, 1), + ]); + } +} + +@reflectiveTest +class AssignmentToFinalLocalWithoutNullSafetyTest + extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_localVariable() async { await assertErrorsInCode(''' f() { @@ -150,31 +177,3 @@ f() { ]); } } - -@reflectiveTest -class AssignmentToFinalLocalWithNullSafetyTest - extends PubPackageResolutionTest { - test_localVariable_late() async { - await assertNoErrorsInCode(''' -void f() { - late final int a; - a = 1; - a; -} -'''); - } - - test_parameter_superFormal() async { - await assertErrorsInCode(''' -class A { - A(int a); -} -class B extends A { - var x; - B(super.a) : x = (() { a = 0; }); -} -''', [ - error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 78, 1), - ]); - } -} diff --git a/pkg/analyzer/test/src/diagnostics/case_expression_type_implements_equals_test.dart b/pkg/analyzer/test/src/diagnostics/case_expression_type_implements_equals_test.dart index 2af52ed4f37d1..ecd9733540c7b 100644 --- a/pkg/analyzer/test/src/diagnostics/case_expression_type_implements_equals_test.dart +++ b/pkg/analyzer/test/src/diagnostics/case_expression_type_implements_equals_test.dart @@ -10,13 +10,14 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(CaseExpressionTypeImplementsEqualsTest); - defineReflectiveTests(CaseExpressionTypeImplementsEqualsWithNullSafetyTest); + defineReflectiveTests( + CaseExpressionTypeImplementsEqualsWithoutNullSafetyTest, + ); }); } @reflectiveTest -class CaseExpressionTypeImplementsEqualsTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { +class CaseExpressionTypeImplementsEqualsTest extends PubPackageResolutionTest { test_declares() async { await assertNoErrorsInCode(r''' abstract class A { @@ -62,7 +63,7 @@ void f(e) { } ''', [ error( - CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, 128, 6), + CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, 150, 4), ]); } @@ -106,8 +107,8 @@ void f(e) { } @reflectiveTest -class CaseExpressionTypeImplementsEqualsWithNullSafetyTest - extends PubPackageResolutionTest { +class CaseExpressionTypeImplementsEqualsWithoutNullSafetyTest + extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_declares() async { await assertNoErrorsInCode(r''' abstract class A { @@ -153,7 +154,7 @@ void f(e) { } ''', [ error( - CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, 150, 4), + CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, 128, 6), ]); } diff --git a/pkg/analyzer/test/src/diagnostics/concrete_class_with_abstract_member_test.dart b/pkg/analyzer/test/src/diagnostics/concrete_class_with_abstract_member_test.dart index 3faf7214ae560..d81ddad7ce22c 100644 --- a/pkg/analyzer/test/src/diagnostics/concrete_class_with_abstract_member_test.dart +++ b/pkg/analyzer/test/src/diagnostics/concrete_class_with_abstract_member_test.dart @@ -10,40 +10,12 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(ConcreteClassWithAbstractMemberTest); - defineReflectiveTests(ConcreteClassWithAbstractMemberWithNullSafetyTest); + defineReflectiveTests(ConcreteClassWithAbstractMemberWithoutNullSafetyTest); }); } @reflectiveTest class ConcreteClassWithAbstractMemberTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, ConcreteClassWithAbstractMemberTestCases {} - -mixin ConcreteClassWithAbstractMemberTestCases on PubPackageResolutionTest { - test_direct() async { - await assertErrorsInCode(''' -class A { - m(); -}''', [ - error(CompileTimeErrorCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, 12, 4), - ]); - } - - test_noSuchMethod_interface() async { - await assertErrorsInCode(''' -class I { - noSuchMethod(v) => ''; -} -class A implements I { - m(); -}''', [ - error(CompileTimeErrorCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, 62, 4), - ]); - } -} - -@reflectiveTest -class ConcreteClassWithAbstractMemberWithNullSafetyTest - extends PubPackageResolutionTest with ConcreteClassWithAbstractMemberTestCases { test_abstract_field() async { await assertErrorsInCode(''' @@ -85,3 +57,31 @@ class A { '''); } } + +mixin ConcreteClassWithAbstractMemberTestCases on PubPackageResolutionTest { + test_direct() async { + await assertErrorsInCode(''' +class A { + m(); +}''', [ + error(CompileTimeErrorCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, 12, 4), + ]); + } + + test_noSuchMethod_interface() async { + await assertErrorsInCode(''' +class I { + noSuchMethod(v) => ''; +} +class A implements I { + m(); +}''', [ + error(CompileTimeErrorCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, 62, 4), + ]); + } +} + +@reflectiveTest +class ConcreteClassWithAbstractMemberWithoutNullSafetyTest + extends PubPackageResolutionTest + with WithoutNullSafetyMixin, ConcreteClassWithAbstractMemberTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart index 3e89e8fe8cbc2..70ce1ae0e2905 100644 --- a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart +++ b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart @@ -10,12 +10,81 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(CouldNotInferTest); - defineReflectiveTests(CouldNotInferWithNullSafetyTest); + defineReflectiveTests(CouldNotInferWithoutNullSafetyTest); }); } +/// TODO(https://github.com/dart-lang/sdk/issues/44078): Add tests with +/// non-function typedefs. +@reflectiveTest +class CouldNotInferTest extends PubPackageResolutionTest { + test_constructor_nullSafe_fromLegacy() async { + newFile('$testPackageLibPath/a.dart', content: ''' +class C { + C(T t); +} +'''); + + await assertNoErrorsInCode(''' +// @dart = 2.8 +import 'a.dart'; + +void f(dynamic a) { + C(a); +} +'''); + } + + test_functionType() async { + await assertNoErrorsInCode(''' +void f() {} + +main() { + [f]; +} +'''); + } + + test_functionType_optOutOfGenericMetadata() async { + newFile('$testPackageLibPath/a.dart', content: ''' +void f() {} +'''); + await assertErrorsInCode(''' +// @dart=2.12 +import 'a.dart'; +main() { + [f]; +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 42, 3), + ]); + } + + test_instanceCreation_viaTypeAlias_notWellBounded() async { + await assertErrorsInCode(''' +class C { + C(); + factory C.foo() => C(); + factory C.bar() = C; +} +typedef G = X Function(X); +typedef A>> = C; + +void f() { + A(); // Error. + A.foo(); // Error. + A.bar(); // Error. +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 152, 1), + error(CompileTimeErrorCode.COULD_NOT_INFER, 169, 5), + error(CompileTimeErrorCode.COULD_NOT_INFER, 190, 5), + ]); + } +} + @reflectiveTest -class CouldNotInferTest extends PubPackageResolutionTest +class CouldNotInferWithoutNullSafetyTest extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_constructors_inferenceFBounded() async { await assertErrorsInCode(''' @@ -267,72 +336,3 @@ main() { new C().f((S s) => s); } ]); } } - -/// TODO(https://github.com/dart-lang/sdk/issues/44078): Add tests with -/// non-function typedefs. -@reflectiveTest -class CouldNotInferWithNullSafetyTest extends PubPackageResolutionTest { - test_constructor_nullSafe_fromLegacy() async { - newFile('$testPackageLibPath/a.dart', content: ''' -class C { - C(T t); -} -'''); - - await assertNoErrorsInCode(''' -// @dart = 2.8 -import 'a.dart'; - -void f(dynamic a) { - C(a); -} -'''); - } - - test_functionType() async { - await assertNoErrorsInCode(''' -void f() {} - -main() { - [f]; -} -'''); - } - - test_functionType_optOutOfGenericMetadata() async { - newFile('$testPackageLibPath/a.dart', content: ''' -void f() {} -'''); - await assertErrorsInCode(''' -// @dart=2.12 -import 'a.dart'; -main() { - [f]; -} -''', [ - error(CompileTimeErrorCode.COULD_NOT_INFER, 42, 3), - ]); - } - - test_instanceCreation_viaTypeAlias_notWellBounded() async { - await assertErrorsInCode(''' -class C { - C(); - factory C.foo() => C(); - factory C.bar() = C; -} -typedef G = X Function(X); -typedef A>> = C; - -void f() { - A(); // Error. - A.foo(); // Error. - A.bar(); // Error. -} -''', [ - error(CompileTimeErrorCode.COULD_NOT_INFER, 152, 1), - error(CompileTimeErrorCode.COULD_NOT_INFER, 169, 5), - error(CompileTimeErrorCode.COULD_NOT_INFER, 190, 5), - ]); - } -} diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart index 4c9a2d6e95865..0b7b7e8f22315 100644 --- a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart +++ b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart @@ -11,7 +11,8 @@ main() { defineReflectiveSuite(() { defineReflectiveTests(DeprecatedMemberUse_BasicWorkspaceTest); defineReflectiveTests( - DeprecatedMemberUse_BasicWorkspace_WithNullSafetyTest); + DeprecatedMemberUse_BasicWorkspace_WithoutNullSafetyTest, + ); defineReflectiveTests(DeprecatedMemberUse_BazelWorkspaceTest); defineReflectiveTests(DeprecatedMemberUse_GnWorkspaceTest); defineReflectiveTests(DeprecatedMemberUse_PackageBuildWorkspaceTest); @@ -29,8 +30,12 @@ main() { } @reflectiveTest -class DeprecatedMemberUse_BasicWorkspace_WithNullSafetyTest +class DeprecatedMemberUse_BasicWorkspace_WithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin, DeprecatedMemberUse_BasicWorkspaceTestCases {} + +@reflectiveTest +class DeprecatedMemberUse_BasicWorkspaceTest extends PubPackageResolutionTest with DeprecatedMemberUse_BasicWorkspaceTestCases { test_instanceCreation_namedParameter_fromLegacy() async { newFile('$workspaceRootPath/aaa/lib/a.dart', content: r''' @@ -107,10 +112,6 @@ class B extends A { } } -@reflectiveTest -class DeprecatedMemberUse_BasicWorkspaceTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, DeprecatedMemberUse_BasicWorkspaceTestCases {} - mixin DeprecatedMemberUse_BasicWorkspaceTestCases on PubPackageResolutionTest { @override void setUp() { diff --git a/pkg/analyzer/test/src/diagnostics/extension_override_argument_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/extension_override_argument_not_assignable_test.dart index c669f19cd381c..87e39b2d7dac4 100644 --- a/pkg/analyzer/test/src/diagnostics/extension_override_argument_not_assignable_test.dart +++ b/pkg/analyzer/test/src/diagnostics/extension_override_argument_not_assignable_test.dart @@ -11,12 +11,42 @@ main() { defineReflectiveSuite(() { defineReflectiveTests(ExtensionOverrideArgumentNotAssignableTest); defineReflectiveTests( - ExtensionOverrideArgumentNotAssignableWithNullSafetyTest); + ExtensionOverrideArgumentNotAssignableWithoutNullSafetyTest, + ); }); } @reflectiveTest class ExtensionOverrideArgumentNotAssignableTest + extends PubPackageResolutionTest { + test_override_onNonNullable() async { + await assertErrorsInCode(r''' +extension E on String { + void m() {} +} +f() { + E(null).m(); +} +''', [ + error(CompileTimeErrorCode.EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE, 50, + 4), + ]); + } + + test_override_onNullable() async { + await assertNoErrorsInCode(r''' +extension E on String? { + void m() {} +} +f() { + E(null).m(); +} +'''); + } +} + +@reflectiveTest +class ExtensionOverrideArgumentNotAssignableWithoutNullSafetyTest extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_subtype() async { await assertNoErrorsInCode(''' @@ -61,32 +91,3 @@ void f(B b) { ]); } } - -@reflectiveTest -class ExtensionOverrideArgumentNotAssignableWithNullSafetyTest - extends PubPackageResolutionTest { - test_override_onNonNullable() async { - await assertErrorsInCode(r''' -extension E on String { - void m() {} -} -f() { - E(null).m(); -} -''', [ - error(CompileTimeErrorCode.EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE, 50, - 4), - ]); - } - - test_override_onNullable() async { - await assertNoErrorsInCode(r''' -extension E on String? { - void m() {} -} -f() { - E(null).m(); -} -'''); - } -} diff --git a/pkg/analyzer/test/src/diagnostics/final_not_initialized_test.dart b/pkg/analyzer/test/src/diagnostics/final_not_initialized_test.dart index d5bb2f64844e0..f24221ef92309 100644 --- a/pkg/analyzer/test/src/diagnostics/final_not_initialized_test.dart +++ b/pkg/analyzer/test/src/diagnostics/final_not_initialized_test.dart @@ -10,88 +10,12 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(FinalNotInitializedTest); - defineReflectiveTests(FinalNotInitializedWithNullSafetyTest); + defineReflectiveTests(FinalNotInitializedWithoutNullSafetyTest); }); } @reflectiveTest -class FinalNotInitializedTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { - test_class_instanceField_final_factoryConstructor_only() async { - await assertNoErrorsInCode(''' -class A { - final int x; - - factory A() => throw 0; -}'''); - } - - test_extension_static() async { - await assertErrorsInCode(''' -extension E on String { - static final F; -}''', [ - error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 39, 1), - ]); - } - - test_instanceField_final() async { - await assertErrorsInCode(''' -class A { - final F; -}''', [ - error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 18, 1), - ]); - } - - test_instanceField_final_static() async { - await assertErrorsInCode(''' -class A { - static final F; -}''', [ - error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 25, 1), - ]); - } - - test_library_final() async { - await assertErrorsInCode(''' -final F; -''', [ - error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 6, 1), - ]); - } - - test_local_final() async { - await assertErrorsInCode(''' -f() { - final int x; -}''', [ - error(HintCode.UNUSED_LOCAL_VARIABLE, 18, 1), - error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 18, 1), - ]); - } - - test_mixin() async { - await assertErrorsInCode(''' -mixin M { - final int x; -} -''', [ - error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 22, 1), - ]); - } - - test_mixin_OK() async { - await assertNoErrorsInCode(r''' -mixin M { - final int f = 0; -} -'''); - } -} - -@reflectiveTest -class FinalNotInitializedWithNullSafetyTest extends PubPackageResolutionTest { +class FinalNotInitializedTest extends PubPackageResolutionTest { test_class_field_abstract() async { await assertNoErrorsInCode(''' abstract class A { @@ -262,3 +186,79 @@ external final int x; '''); } } + +@reflectiveTest +class FinalNotInitializedWithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin { + test_class_instanceField_final_factoryConstructor_only() async { + await assertNoErrorsInCode(''' +class A { + final int x; + + factory A() => throw 0; +}'''); + } + + test_extension_static() async { + await assertErrorsInCode(''' +extension E on String { + static final F; +}''', [ + error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 39, 1), + ]); + } + + test_instanceField_final() async { + await assertErrorsInCode(''' +class A { + final F; +}''', [ + error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 18, 1), + ]); + } + + test_instanceField_final_static() async { + await assertErrorsInCode(''' +class A { + static final F; +}''', [ + error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 25, 1), + ]); + } + + test_library_final() async { + await assertErrorsInCode(''' +final F; +''', [ + error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 6, 1), + ]); + } + + test_local_final() async { + await assertErrorsInCode(''' +f() { + final int x; +}''', [ + error(HintCode.UNUSED_LOCAL_VARIABLE, 18, 1), + error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 18, 1), + ]); + } + + test_mixin() async { + await assertErrorsInCode(''' +mixin M { + final int x; +} +''', [ + error(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, 22, 1), + ]); + } + + test_mixin_OK() async { + await assertNoErrorsInCode(r''' +mixin M { + final int f = 0; +} +'''); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart b/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart index e26ef2bf8b661..804508473e2d1 100644 --- a/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart +++ b/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart @@ -10,13 +10,36 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(InconsistentCaseExpressionTypesTest); - defineReflectiveTests(InconsistentCaseExpressionTypesWithNullSafetyTest); + defineReflectiveTests(InconsistentCaseExpressionTypesWithoutNullSafetyTest); }); } @reflectiveTest -class InconsistentCaseExpressionTypesTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { +class InconsistentCaseExpressionTypesTest extends PubPackageResolutionTest { + test_int_none_legacy() async { + newFile('$testPackageLibPath/a.dart', content: r''' +const a = 0; +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.8 +import 'a.dart'; + +void f(int e) { + switch (e) { + case a: + break; + case 1: + break; + } +} +'''); + } +} + +@reflectiveTest +class InconsistentCaseExpressionTypesWithoutNullSafetyTest + extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_dynamic() async { // Even though A.S and S have a static type of "dynamic", we should see // that they match 'abc', because they are constant strings. @@ -112,27 +135,3 @@ void f(var e) { ]); } } - -@reflectiveTest -class InconsistentCaseExpressionTypesWithNullSafetyTest - extends PubPackageResolutionTest { - test_int_none_legacy() async { - newFile('$testPackageLibPath/a.dart', content: r''' -const a = 0; -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.8 -import 'a.dart'; - -void f(int e) { - switch (e) { - case a: - break; - case 1: - break; - } -} -'''); - } -} diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart index 016d36b128a70..c44810c165892 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart @@ -11,13 +11,53 @@ main() { defineReflectiveSuite(() { defineReflectiveTests(InvalidOverrideDifferentDefaultValuesNamedTest); defineReflectiveTests( - InvalidOverrideDifferentDefaultValuesNamedWithNullSafetyTest, + InvalidOverrideDifferentDefaultValuesNamedWithoutNullSafetyTest, ); }); } @reflectiveTest class InvalidOverrideDifferentDefaultValuesNamedTest + extends InvalidOverrideDifferentDefaultValuesNamedWithoutNullSafetyTest { + test_concrete_equal_optIn_extends_optOut() async { + newFile('$testPackageLibPath/a.dart', content: r''' +// @dart = 2.7 +class A { + void foo({int a = 0}) {} +} +'''); + + await assertErrorsInCode(r''' +import 'a.dart'; + +class B extends A { + void foo({int a = 0}) {} +} +''', [ + error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), + ]); + } + + test_concrete_equal_optOut_extends_optIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + void foo({int a = 0}) {} +} +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.7 +import 'a.dart'; + +class B extends A { + void foo({int a = 0}) {} +} +'''); + } +} + +@reflectiveTest +class InvalidOverrideDifferentDefaultValuesNamedWithoutNullSafetyTest extends PubPackageResolutionTest { test_abstract_different_base_value() async { await assertErrorsInCode( @@ -304,43 +344,3 @@ class B extends A { ); } } - -@reflectiveTest -class InvalidOverrideDifferentDefaultValuesNamedWithNullSafetyTest - extends InvalidOverrideDifferentDefaultValuesNamedTest { - test_concrete_equal_optIn_extends_optOut() async { - newFile('$testPackageLibPath/a.dart', content: r''' -// @dart = 2.7 -class A { - void foo({int a = 0}) {} -} -'''); - - await assertErrorsInCode(r''' -import 'a.dart'; - -class B extends A { - void foo({int a = 0}) {} -} -''', [ - error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), - ]); - } - - test_concrete_equal_optOut_extends_optIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - void foo({int a = 0}) {} -} -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.7 -import 'a.dart'; - -class B extends A { - void foo({int a = 0}) {} -} -'''); - } -} diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart index fb62381ff68a1..9c9fe63b6c5fc 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart @@ -9,15 +9,57 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(InvalidOverrideDifferentDefaultValuesPositionalTest); defineReflectiveTests( - InvalidOverrideDifferentDefaultValuesPositionalWithNullSafetyTest, + InvalidOverrideDifferentDefaultValuesPositionalTest, + ); + defineReflectiveTests( + InvalidOverrideDifferentDefaultValuesPositionalWithoutNullSafetyTest, ); }); } @reflectiveTest class InvalidOverrideDifferentDefaultValuesPositionalTest + extends InvalidOverrideDifferentDefaultValuesPositionalWithoutNullSafetyTest { + test_concrete_equal_optIn_extends_optOut() async { + newFile('$testPackageLibPath/a.dart', content: r''' +// @dart = 2.7 +class A { + void foo([int a = 0]) {} +} +'''); + + await assertErrorsInCode(r''' +import 'a.dart'; + +class B extends A { + void foo([int a = 0]) {} +} +''', [ + error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), + ]); + } + + test_concrete_equal_optOut_extends_optIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + void foo([int a = 0]) {} +} +'''); + + await assertNoErrorsInCode(r''' +// @dart = 2.7 +import 'a.dart'; + +class B extends A { + void foo([int a = 0]) {} +} +'''); + } +} + +@reflectiveTest +class InvalidOverrideDifferentDefaultValuesPositionalWithoutNullSafetyTest extends PubPackageResolutionTest { test_abstract_different_base_value() async { await assertErrorsInCode( @@ -319,43 +361,3 @@ class B extends A { ); } } - -@reflectiveTest -class InvalidOverrideDifferentDefaultValuesPositionalWithNullSafetyTest - extends InvalidOverrideDifferentDefaultValuesPositionalTest { - test_concrete_equal_optIn_extends_optOut() async { - newFile('$testPackageLibPath/a.dart', content: r''' -// @dart = 2.7 -class A { - void foo([int a = 0]) {} -} -'''); - - await assertErrorsInCode(r''' -import 'a.dart'; - -class B extends A { - void foo([int a = 0]) {} -} -''', [ - error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), - ]); - } - - test_concrete_equal_optOut_extends_optIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A { - void foo([int a = 0]) {} -} -'''); - - await assertNoErrorsInCode(r''' -// @dart = 2.7 -import 'a.dart'; - -class B extends A { - void foo([int a = 0]) {} -} -'''); - } -} diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart index 2b5c52713bae3..96157ccb19796 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart @@ -10,1091 +10,1091 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(InvalidOverrideTest); - defineReflectiveTests(InvalidOverrideWithNullSafetyTest); + defineReflectiveTests(InvalidOverrideWithoutNullSafetyTest); }); } @reflectiveTest -class InvalidOverrideTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { - test_getter_returnType() async { - await assertErrorsInCode(''' -class A { - int get g { return 0; } +class InvalidOverrideTest extends PubPackageResolutionTest { + test_abstract_field_covariant_inheritance() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract covariant num x; } -class B extends A { - String get g { return 'a'; } +abstract class B implements A { + void set x(Object value); // Implicitly covariant } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 71, 1, - contextMessages: [message('/home/test/lib/test.dart', 20, 1)]), - ]); +abstract class C implements B { + int get x; + void set x(int value); // Ok because covariant +} +'''); } - test_getter_returnType_implicit() async { - await assertErrorsInCode(''' -class A { - String f; + test_external_field_covariant_inheritance() async { + await assertNoErrorsInCode(''' +abstract class A { + external covariant num x; } -class B extends A { - int f; +abstract class B implements A { + void set x(Object value); // Implicitly covariant } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 1, - contextMessages: [message('/home/test/lib/test.dart', 19, 1)]), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 1, - contextMessages: [message('/home/test/lib/test.dart', 19, 1)]), - ]); +abstract class C implements B { + int get x; + void set x(int value); // Ok because covariant +} +'''); } - test_getter_returnType_twoInterfaces() async { - // test from language/override_inheritance_field_test_11.dart + test_getter_overrides_abstract_field_covariant_invalid() async { await assertErrorsInCode(''' -abstract class I { - int get getter => null; -} -abstract class J { - num get getter => null; +abstract class A { + abstract covariant int x; } -abstract class A implements I, J {} -class B extends A { - String get getter => null; +abstract class B implements A { + num get x; + void set x(num value); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 163, 6, - contextMessages: [message('/home/test/lib/test.dart', 29, 6)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 91, 1, + contextMessages: [message('/home/test/lib/test.dart', 44, 1)]), ]); } - test_getter_returnType_twoInterfaces_conflicting() async { - await assertErrorsInCode(''' -abstract class I { - U get g => null; -} -abstract class J { - V get g => null; + test_getter_overrides_abstract_field_covariant_valid() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract covariant num x; } -class B implements I, J { - double get g => null; +abstract class B implements A { + int get x; } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 138, 1, - contextMessages: [message('/home/test/lib/test.dart', 73, 1)]), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 138, 1, - contextMessages: [message('/home/test/lib/test.dart', 30, 1)]), - ]); +'''); } - test_method_abstractOverridesConcrete() async { + test_getter_overrides_abstract_field_final_invalid() async { await assertErrorsInCode(''' -class A { - int add(int a, int b) => a + b; +abstract class A { + abstract final int x; } -class B extends A { - int add(); +abstract class B implements A { + num get x; + void set x(num value); } ''', [ - error(CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE, 52, 1), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 72, 3, - contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 87, 1, + contextMessages: [message('/home/test/lib/test.dart', 40, 1)]), ]); } - test_method_abstractOverridesConcreteInMixin() async { - await assertErrorsInCode(''' -mixin M { - int add(int a, int b) => a + b; + test_getter_overrides_abstract_field_final_valid() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract final num x; } -class A with M { - int add(); +abstract class B implements A { + int get x; } -''', [ - error(CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE, 52, 1), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 69, 3, - contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), - ]); +'''); } - test_method_abstractOverridesConcreteViaMixin() async { + test_getter_overrides_abstract_field_invalid() async { await assertErrorsInCode(''' -class A { - int add(int a, int b) => a + b; +abstract class A { + abstract int x; } -mixin M { - int add(); +abstract class B implements A { + num get x; + void set x(num value); } -class B extends A with M {} ''', [ - error(CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE, 77, 1), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 94, 1, - contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 81, 1, + contextMessages: [message('/home/test/lib/test.dart', 34, 1)]), ]); } - test_method_covariant_1() async { - await assertNoErrorsInCode(r''' -abstract class A { - A foo(covariant A> a); -} - -abstract class B extends A { - B foo(B> a); -} -'''); - } - - test_method_covariant_2() async { - await assertNoErrorsInCode(r''' + test_getter_overrides_abstract_field_valid() async { + await assertNoErrorsInCode(''' abstract class A { - R foo(VA v); + abstract num x; } - abstract class B implements A { - R foo(covariant VB v); + int get x; } - -abstract class VA {} - -abstract class VB implements VA {} '''); } - test_method_covariant_3() async { - await assertErrorsInCode(r''' + test_getter_overrides_external_field_covariant_invalid() async { + await assertErrorsInCode(''' class A { - void foo(num a) {} -} - -class B extends A { - void foo(dynamic a) {} + external covariant int x; } - -class C extends B { - void foo(covariant String a) {} +abstract class B implements A { + num get x; + void set x(num value); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 109, 3), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 82, 1, + contextMessages: [message('/home/test/lib/test.dart', 35, 1)]), ]); } - test_method_named_fewerNamedParameters() async { - await assertErrorsInCode(''' + test_getter_overrides_external_field_covariant_valid() async { + await assertNoErrorsInCode(''' class A { - m({a, b}) {} + external covariant num x; } -class B extends A { - m({a}) {} +abstract class B implements A { + int get x; } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), - ]); +'''); } - test_method_named_missingNamedParameter() async { + test_getter_overrides_external_field_final_invalid() async { await assertErrorsInCode(''' class A { - m({a, b}) {} + external final int x; } -class B extends A { - m({a, c}) {} +abstract class B implements A { + num get x; + void set x(num value); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 78, 1, + contextMessages: [message('/home/test/lib/test.dart', 31, 1)]), ]); } - test_method_namedParamType() async { - await assertErrorsInCode(''' + test_getter_overrides_external_field_final_valid() async { + await assertNoErrorsInCode(''' class A { - m({int a}) {} + external final num x; } -class B implements A { - m({String a}) {} +abstract class B implements A { + int get x; } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), - ]); +'''); } - test_method_normalParamType_interface() async { + test_getter_overrides_external_field_invalid() async { await assertErrorsInCode(''' class A { - m(int a) {} + external int x; } -class B implements A { - m(String a) {} +abstract class B implements A { + num get x; + void set x(num value); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 51, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 72, 1, + contextMessages: [message('/home/test/lib/test.dart', 25, 1)]), ]); } - test_method_normalParamType_superclass() async { - await assertErrorsInCode(''' + test_getter_overrides_external_field_valid() async { + await assertNoErrorsInCode(''' class A { - m(int a) {} + external num x; } -class B extends A { - m(String a) {} +abstract class B implements A { + int get x; } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 48, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), - ]); +'''); } - test_method_normalParamType_superclass_interface() async { - await assertErrorsInCode(''' -abstract class I { - void m(U u) => null; -} -abstract class J { - void m(V v) => null; + test_method_parameter_functionTyped_optOut_extends_optIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' +abstract class A { + A catchError(void Function(Object) a); } -class B extends I implements J { - void m(double d) {} +'''); + + await assertNoErrorsInCode(''' +// @dart=2.6 +import 'a.dart'; + +class B implements A { + A catchError(void Function(dynamic) a) => this; } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 147, 1, - contextMessages: [message('/home/test/lib/test.dart', 76, 1)]), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 147, 1, - contextMessages: [message('/home/test/lib/test.dart', 29, 1)]), - ]); +'''); } - test_method_normalParamType_twoInterfaces() async { - await assertErrorsInCode(''' -abstract class I { - m(int n); -} -abstract class J { - m(num n); + test_method_parameter_interfaceOptOut_concreteOptIn() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A { + void foo(Object a) {} } -abstract class A implements I, J {} +'''); + + await assertNoErrorsInCode(''' +// @dart=2.6 +import 'a.dart'; + class B extends A { - m(String n) {} + void foo(dynamic a); } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 1, - contextMessages: [message('/home/test/lib/test.dart', 54, 1)]), - ]); +'''); } - test_method_normalParamType_twoInterfaces_conflicting() async { - // language/override_inheritance_generic_test/08 - await assertErrorsInCode(''' -abstract class I { - void m(U u) => null; -} -abstract class J { - void m(V v) => null; + test_mixedInheritance_1() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class B { + List get a => []; + set a(List _) {} + int Function(int) m(int Function(int) x) => x; } -class B implements I, J { - void m(double d) {} + +class Bq { + List get a => []; + set a(List _) {} + int? Function(int?) m(int? Function(int?) x) => x; } +'''); + + newFile('$testPackageLibPath/b.dart', content: r''' +// @dart = 2.7 +import 'a.dart'; + +class C with B {} +'''); + + await assertErrorsInCode(r''' +import 'a.dart'; +import 'b.dart'; + +class D extends C implements Bq {} ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 140, 1, - contextMessages: [message('/home/test/lib/test.dart', 29, 1)]), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 140, 1, - contextMessages: [message('/home/test/lib/test.dart', 76, 1)]), + error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 24, 8), ]); } - test_method_optionalParamType() async { - await assertErrorsInCode(''' -class A { - m([int a]) {} + test_mixedInheritance_2() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class B { + List get a => []; + set a(List _) {} + int Function(int) m(int Function(int) x) => x; } -class B implements A { - m([String a]) {} + +class Bq { + List get a => []; + set a(List _) {} + int? Function(int?) m(int? Function(int?) x) => x; +} +'''); + + newFile('$testPackageLibPath/b.dart', content: r''' +// @dart = 2.7 +import 'a.dart'; + +class C extends B with Bq {} +'''); + + await assertErrorsInCode(r''' +import 'b.dart'; + +class D extends C { + List get a => []; + set a(List _) {} + int Function(int) m(int Function(int) x) => x; } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), + error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), ]); } - test_method_optionalParamType_twoInterfaces() async { - await assertErrorsInCode(''' -abstract class I { - m([int n]); -} -abstract class J { - m([num n]); + test_setter_overrides_abstract_field_covariant_valid() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract covariant num x; } -abstract class A implements I, J {} -class B extends A { - m([String n]) {} +abstract class B implements A { + int get x; + void set x(int value); } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 1, - contextMessages: [message('/home/test/lib/test.dart', 56, 1)]), - ]); +'''); } - test_method_positional_optional() async { - await assertErrorsInCode(''' -class A { - m([a, b]) {} + test_setter_overrides_abstract_field_final_valid() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract final num x; } -class B extends A { - m([a]) {} +abstract class B implements A { + int get x; + void set x(int value); } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), - ]); +'''); } - test_method_positional_optionalAndRequired() async { + test_setter_overrides_abstract_field_invalid() async { await assertErrorsInCode(''' -class A { - m(a, b, [c, d]) {} +abstract class A { + abstract num x; } -class B extends A { - m(a, b, [c]) {} +abstract class B implements A { + int get x; + void set x(int value); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 95, 1, + contextMessages: [message('/home/test/lib/test.dart', 34, 1)]), ]); } - test_method_positional_optionalAndRequired2() async { - await assertErrorsInCode(''' -class A { - m(a, b, [c, d]) {} + test_setter_overrides_abstract_field_valid() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract int x; } -class B extends A { - m(a, [c, d]) {} +abstract class B implements A { + void set x(num value); } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), - ]); +'''); } - test_method_required() async { - await assertErrorsInCode(''' + test_setter_overrides_external_field_covariant_valid() async { + await assertNoErrorsInCode(''' class A { - m(a) {} + external covariant num x; } -class B extends A { - m(a, b) {} +abstract class B implements A { + int get x; + void set x(int value); } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 44, 1, - contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), - ]); +'''); } - test_method_returnType_interface() async { - await assertErrorsInCode(''' + test_setter_overrides_external_field_final_valid() async { + await assertNoErrorsInCode(''' class A { - int m() { return 0; } + external final num x; } -class B implements A { - String m() { return 'a'; } +abstract class B implements A { + int get x; + void set x(int value); } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 68, 1, - contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), - ]); +'''); } - test_method_returnType_interface_grandparent() async { + test_setter_overrides_external_field_invalid() async { await assertErrorsInCode(''' -abstract class A { - int m(); +class A { + external num x; } abstract class B implements A { -} -class C implements B { - String m() { return 'a'; } + int get x; + void set x(int value); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 98, 1, + error(CompileTimeErrorCode.INVALID_OVERRIDE, 86, 1, contextMessages: [message('/home/test/lib/test.dart', 25, 1)]), ]); } - test_method_returnType_mixin() async { - await assertErrorsInCode(''' + test_setter_overrides_external_field_valid() async { + await assertNoErrorsInCode(''' class A { - int m() { return 0; } + external int x; } -class B extends Object with A { - String m() { return 'a'; } +abstract class B implements A { + void set x(num value); } -''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 77, 1, - contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), +'''); + } + + test_viaLegacy_class() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A1 { + int m() => 0; + int get g => 0; + set s(int? _) {} +} + +class A2 { + int? m() => 0; + int? get g => 0; + set s(int _) {} +} +'''); + + newFile('$testPackageLibPath/b.dart', content: r''' +// @dart=2.6 +import 'a.dart'; + +class L extends A2 implements A1 {} +'''); + + await assertErrorsInCode(''' +import 'a.dart'; +import 'b.dart'; + +class X1 extends L implements A1 {} +class X2 extends L implements A2 {} + +class Y extends L { + int? get g => 0; + int? m() => 0; + set s(int _) {} +} +''', [ + error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 24, 8), ]); } - test_method_returnType_superclass() async { + test_viaLegacy_mixin() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A1 { + int m() => 0; + int get g => 0; + set s(int? _) {} +} + +mixin A2 { + int? m() => 0; + int? get g => 0; + set s(int _) {} +} +'''); + + newFile('$testPackageLibPath/b.dart', content: r''' +// @dart=2.6 +import 'a.dart'; + +class L extends Object with A2 implements A1 {} +'''); + + await assertErrorsInCode(''' +import 'a.dart'; +import 'b.dart'; + +class X1 extends L implements A1 {} +class X2 extends L implements A2 {} + +class Y extends L { + int? get g => 0; + int? m() => 0; + set s(int _) {} +} +''', [ + error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 24, 8), + ]); + } +} + +@reflectiveTest +class InvalidOverrideWithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin { + test_getter_returnType() async { await assertErrorsInCode(''' class A { - int m() { return 0; } + int get g { return 0; } } class B extends A { - String m() { return 'a'; } + String get g { return 'a'; } } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 65, 1, - contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 71, 1, + contextMessages: [message('/home/test/lib/test.dart', 20, 1)]), ]); } - test_method_returnType_superclass_grandparent() async { + test_getter_returnType_implicit() async { await assertErrorsInCode(''' class A { - int m() { return 0; } + String f; } class B extends A { -} -class C extends B { - String m() { return 'a'; } + int f; } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 87, 1, - contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 1, + contextMessages: [message('/home/test/lib/test.dart', 19, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 1, + contextMessages: [message('/home/test/lib/test.dart', 19, 1)]), ]); } - test_method_returnType_twoInterfaces() async { + test_getter_returnType_twoInterfaces() async { + // test from language/override_inheritance_field_test_11.dart await assertErrorsInCode(''' abstract class I { - int m(); + int get getter => null; } abstract class J { - num m(); + num get getter => null; } abstract class A implements I, J {} class B extends A { - String m() => ''; + String get getter => null; } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 129, 1, - contextMessages: [message('/home/test/lib/test.dart', 25, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 163, 6, + contextMessages: [message('/home/test/lib/test.dart', 29, 6)]), ]); } - test_method_returnType_void() async { + test_getter_returnType_twoInterfaces_conflicting() async { await assertErrorsInCode(''' -class A { - int m() { return 0; } +abstract class I { + U get g => null; } -class B extends A { - void m() {} +abstract class J { + V get g => null; +} +class B implements I, J { + double get g => null; } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 63, 1, - contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 138, 1, + contextMessages: [message('/home/test/lib/test.dart', 73, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 138, 1, + contextMessages: [message('/home/test/lib/test.dart', 30, 1)]), ]); } - test_mixin_field_type() async { - await assertErrorsInCode(r''' -class A { - String foo = ''; + test_method_abstractOverridesConcrete() async { + await assertErrorsInCode(''' +class A { + int add(int a, int b) => a + b; } - -mixin M on A { - int foo = 0; +class B extends A { + int add(); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 3, - contextMessages: [message('/home/test/lib/test.dart', 19, 3)]), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 3, - contextMessages: [message('/home/test/lib/test.dart', 19, 3)]), + error(CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE, 52, 1), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 72, 3, + contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), ]); } - test_mixin_getter_type() async { - await assertErrorsInCode(r''' -class A { - String get foo => ''; + test_method_abstractOverridesConcreteInMixin() async { + await assertErrorsInCode(''' +mixin M { + int add(int a, int b) => a + b; } - -mixin M on A { - int get foo => 0; +class A with M { + int add(); } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 62, 3, - contextMessages: [message('/home/test/lib/test.dart', 23, 3)]), + error(CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE, 52, 1), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 69, 3, + contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), ]); } - test_mixin_method_returnType() async { - await assertErrorsInCode(r''' + test_method_abstractOverridesConcreteViaMixin() async { + await assertErrorsInCode(''' class A { - String foo() => ''; + int add(int a, int b) => a + b; } - -mixin M on A { - int foo() => 0; +mixin M { + int add(); } +class B extends A with M {} ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 56, 3, - contextMessages: [message('/home/test/lib/test.dart', 19, 3)]), + error(CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE, 77, 1), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 94, 1, + contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), ]); } - test_mixin_setter_type() async { + test_method_covariant_1() async { + await assertNoErrorsInCode(r''' +abstract class A { + A foo(covariant A> a); +} + +abstract class B extends A { + B foo(B> a); +} +'''); + } + + test_method_covariant_2() async { + await assertNoErrorsInCode(r''' +abstract class A { + R foo(VA v); +} + +abstract class B implements A { + R foo(covariant VB v); +} + +abstract class VA {} + +abstract class VB implements VA {} +'''); + } + + test_method_covariant_3() async { await assertErrorsInCode(r''' class A { - set foo(String _) {} + void foo(num a) {} } -mixin M on A { - set foo(int _) {} +class B extends A { + void foo(dynamic a) {} +} + +class C extends B { + void foo(covariant String a) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 57, 3, - contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 109, 3), ]); } - test_setter_normalParamType() async { + test_method_named_fewerNamedParameters() async { await assertErrorsInCode(''' class A { - void set s(int v) {} + m({a, b}) {} } class B extends A { - void set s(String v) {} + m({a}) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 66, 1, - contextMessages: [message('/home/test/lib/test.dart', 21, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), ]); } - test_setter_normalParamType_superclass_interface() async { + test_method_named_missingNamedParameter() async { await assertErrorsInCode(''' -abstract class I { - set setter14(int _) => null; -} -abstract class J { - set setter14(num _) => null; +class A { + m({a, b}) {} } -abstract class A extends I implements J {} class B extends A { - set setter14(String _) => null; + m({a, c}) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 173, 8, - contextMessages: [message('/home/test/lib/test.dart', 77, 8)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), ]); } - test_setter_normalParamType_twoInterfaces() async { - // test from language/override_inheritance_field_test_34.dart + test_method_namedParamType() async { await assertErrorsInCode(''' -abstract class I { - set setter14(int _) => null; -} -abstract class J { - set setter14(num _) => null; +class A { + m({int a}) {} } -abstract class A implements I, J {} -class B extends A { - set setter14(String _) => null; +class B implements A { + m({String a}) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 166, 8, - contextMessages: [message('/home/test/lib/test.dart', 77, 8)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), ]); } - test_setter_normalParamType_twoInterfaces_conflicting() async { + test_method_normalParamType_interface() async { await assertErrorsInCode(''' -abstract class I { - set s(U u) {} -} -abstract class J { - set s(V v) {} +class A { + m(int a) {} } -class B implements I, J { - set s(double d) {} +class B implements A { + m(String a) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1, - contextMessages: [message('/home/test/lib/test.dart', 28, 1)]), - error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1, - contextMessages: [message('/home/test/lib/test.dart', 68, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 51, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), ]); } -} -@reflectiveTest -class InvalidOverrideWithNullSafetyTest extends PubPackageResolutionTest { - test_abstract_field_covariant_inheritance() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract covariant num x; -} -abstract class B implements A { - void set x(Object value); // Implicitly covariant + test_method_normalParamType_superclass() async { + await assertErrorsInCode(''' +class A { + m(int a) {} } -abstract class C implements B { - int get x; - void set x(int value); // Ok because covariant +class B extends A { + m(String a) {} } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 48, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), + ]); } - test_external_field_covariant_inheritance() async { - await assertNoErrorsInCode(''' -abstract class A { - external covariant num x; + test_method_normalParamType_superclass_interface() async { + await assertErrorsInCode(''' +abstract class I { + void m(U u) => null; } -abstract class B implements A { - void set x(Object value); // Implicitly covariant +abstract class J { + void m(V v) => null; } -abstract class C implements B { - int get x; - void set x(int value); // Ok because covariant +class B extends I implements J { + void m(double d) {} } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 147, 1, + contextMessages: [message('/home/test/lib/test.dart', 76, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 147, 1, + contextMessages: [message('/home/test/lib/test.dart', 29, 1)]), + ]); } - test_getter_overrides_abstract_field_covariant_invalid() async { + test_method_normalParamType_twoInterfaces() async { await assertErrorsInCode(''' -abstract class A { - abstract covariant int x; +abstract class I { + m(int n); } -abstract class B implements A { - num get x; - void set x(num value); +abstract class J { + m(num n); +} +abstract class A implements I, J {} +class B extends A { + m(String n) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 91, 1, - contextMessages: [message('/home/test/lib/test.dart', 44, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 1, + contextMessages: [message('/home/test/lib/test.dart', 54, 1)]), ]); } - test_getter_overrides_abstract_field_covariant_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract covariant num x; + test_method_normalParamType_twoInterfaces_conflicting() async { + // language/override_inheritance_generic_test/08 + await assertErrorsInCode(''' +abstract class I { + void m(U u) => null; } -abstract class B implements A { - int get x; +abstract class J { + void m(V v) => null; } -'''); +class B implements I, J { + void m(double d) {} +} +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 140, 1, + contextMessages: [message('/home/test/lib/test.dart', 29, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 140, 1, + contextMessages: [message('/home/test/lib/test.dart', 76, 1)]), + ]); } - test_getter_overrides_abstract_field_final_invalid() async { + test_method_optionalParamType() async { await assertErrorsInCode(''' -abstract class A { - abstract final int x; +class A { + m([int a]) {} } -abstract class B implements A { - num get x; - void set x(num value); +class B implements A { + m([String a]) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 87, 1, - contextMessages: [message('/home/test/lib/test.dart', 40, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), ]); } - test_getter_overrides_abstract_field_final_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract final num x; + test_method_optionalParamType_twoInterfaces() async { + await assertErrorsInCode(''' +abstract class I { + m([int n]); } -abstract class B implements A { - int get x; +abstract class J { + m([num n]); } -'''); +abstract class A implements I, J {} +class B extends A { + m([String n]) {} +} +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 1, + contextMessages: [message('/home/test/lib/test.dart', 56, 1)]), + ]); } - test_getter_overrides_abstract_field_invalid() async { + test_method_positional_optional() async { await assertErrorsInCode(''' -abstract class A { - abstract int x; +class A { + m([a, b]) {} } -abstract class B implements A { - num get x; - void set x(num value); +class B extends A { + m([a]) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 81, 1, - contextMessages: [message('/home/test/lib/test.dart', 34, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), ]); } - test_getter_overrides_abstract_field_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract num x; + test_method_positional_optionalAndRequired() async { + await assertErrorsInCode(''' +class A { + m(a, b, [c, d]) {} } -abstract class B implements A { - int get x; +class B extends A { + m(a, b, [c]) {} } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), + ]); } - test_getter_overrides_external_field_covariant_invalid() async { + test_method_positional_optionalAndRequired2() async { await assertErrorsInCode(''' class A { - external covariant int x; + m(a, b, [c, d]) {} } -abstract class B implements A { - num get x; - void set x(num value); +class B extends A { + m(a, [c, d]) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 82, 1, - contextMessages: [message('/home/test/lib/test.dart', 35, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), ]); } - test_getter_overrides_external_field_covariant_valid() async { - await assertNoErrorsInCode(''' + test_method_required() async { + await assertErrorsInCode(''' class A { - external covariant num x; + m(a) {} } -abstract class B implements A { - int get x; +class B extends A { + m(a, b) {} } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 44, 1, + contextMessages: [message('/home/test/lib/test.dart', 12, 1)]), + ]); } - test_getter_overrides_external_field_final_invalid() async { + test_method_returnType_interface() async { await assertErrorsInCode(''' class A { - external final int x; + int m() { return 0; } } -abstract class B implements A { - num get x; - void set x(num value); +class B implements A { + String m() { return 'a'; } } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 78, 1, - contextMessages: [message('/home/test/lib/test.dart', 31, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 68, 1, + contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), ]); } - test_getter_overrides_external_field_final_valid() async { - await assertNoErrorsInCode(''' -class A { - external final num x; + test_method_returnType_interface_grandparent() async { + await assertErrorsInCode(''' +abstract class A { + int m(); } abstract class B implements A { - int get x; } -'''); - } - - test_getter_overrides_external_field_invalid() async { - await assertErrorsInCode(''' -class A { - external int x; -} -abstract class B implements A { - num get x; - void set x(num value); +class C implements B { + String m() { return 'a'; } } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 72, 1, + error(CompileTimeErrorCode.INVALID_OVERRIDE, 98, 1, contextMessages: [message('/home/test/lib/test.dart', 25, 1)]), ]); } - test_getter_overrides_external_field_valid() async { - await assertNoErrorsInCode(''' + test_method_returnType_mixin() async { + await assertErrorsInCode(''' class A { - external num x; + int m() { return 0; } } -abstract class B implements A { - int get x; +class B extends Object with A { + String m() { return 'a'; } } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 77, 1, + contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), + ]); } - test_method_parameter_functionTyped_optOut_extends_optIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' -abstract class A { - A catchError(void Function(Object) a); + test_method_returnType_superclass() async { + await assertErrorsInCode(''' +class A { + int m() { return 0; } } -'''); - - await assertNoErrorsInCode(''' -// @dart=2.6 -import 'a.dart'; - -class B implements A { - A catchError(void Function(dynamic) a) => this; +class B extends A { + String m() { return 'a'; } } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 65, 1, + contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), + ]); } - test_method_parameter_interfaceOptOut_concreteOptIn() async { - newFile('$testPackageLibPath/a.dart', content: r''' + test_method_returnType_superclass_grandparent() async { + await assertErrorsInCode(''' class A { - void foo(Object a) {} + int m() { return 0; } } -'''); - - await assertNoErrorsInCode(''' -// @dart=2.6 -import 'a.dart'; - class B extends A { - void foo(dynamic a); -} -'''); - } - - test_mixedInheritance_1() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class B { - List get a => []; - set a(List _) {} - int Function(int) m(int Function(int) x) => x; } - -class Bq { - List get a => []; - set a(List _) {} - int? Function(int?) m(int? Function(int?) x) => x; +class C extends B { + String m() { return 'a'; } } -'''); - - newFile('$testPackageLibPath/b.dart', content: r''' -// @dart = 2.7 -import 'a.dart'; - -class C with B {} -'''); - - await assertErrorsInCode(r''' -import 'a.dart'; -import 'b.dart'; - -class D extends C implements Bq {} ''', [ - error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 24, 8), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 87, 1, + contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), ]); } - test_mixedInheritance_2() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class B { - List get a => []; - set a(List _) {} - int Function(int) m(int Function(int) x) => x; + test_method_returnType_twoInterfaces() async { + await assertErrorsInCode(''' +abstract class I { + int m(); } - -class Bq { - List get a => []; - set a(List _) {} - int? Function(int?) m(int? Function(int?) x) => x; +abstract class J { + num m(); } -'''); - - newFile('$testPackageLibPath/b.dart', content: r''' -// @dart = 2.7 -import 'a.dart'; - -class C extends B with Bq {} -'''); - - await assertErrorsInCode(r''' -import 'b.dart'; - -class D extends C { - List get a => []; - set a(List _) {} - int Function(int) m(int Function(int) x) => x; +abstract class A implements I, J {} +class B extends A { + String m() => ''; } ''', [ - error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 129, 1, + contextMessages: [message('/home/test/lib/test.dart', 25, 1)]), ]); } - test_setter_overrides_abstract_field_covariant_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract covariant num x; + test_method_returnType_void() async { + await assertErrorsInCode(''' +class A { + int m() { return 0; } } -abstract class B implements A { - int get x; - void set x(int value); +class B extends A { + void m() {} } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 63, 1, + contextMessages: [message('/home/test/lib/test.dart', 16, 1)]), + ]); } - test_setter_overrides_abstract_field_final_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract final num x; -} -abstract class B implements A { - int get x; - void set x(int value); + test_mixin_field_type() async { + await assertErrorsInCode(r''' +class A { + String foo = ''; } -'''); - } - test_setter_overrides_abstract_field_invalid() async { - await assertErrorsInCode(''' -abstract class A { - abstract num x; -} -abstract class B implements A { - int get x; - void set x(int value); +mixin M on A { + int foo = 0; } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 95, 1, - contextMessages: [message('/home/test/lib/test.dart', 34, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 3, + contextMessages: [message('/home/test/lib/test.dart', 19, 3)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 3, + contextMessages: [message('/home/test/lib/test.dart', 19, 3)]), ]); } - test_setter_overrides_abstract_field_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract int x; + test_mixin_getter_type() async { + await assertErrorsInCode(r''' +class A { + String get foo => ''; } -abstract class B implements A { - void set x(num value); + +mixin M on A { + int get foo => 0; } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 62, 3, + contextMessages: [message('/home/test/lib/test.dart', 23, 3)]), + ]); } - test_setter_overrides_external_field_covariant_valid() async { - await assertNoErrorsInCode(''' + test_mixin_method_returnType() async { + await assertErrorsInCode(r''' class A { - external covariant num x; + String foo() => ''; } -abstract class B implements A { - int get x; - void set x(int value); + +mixin M on A { + int foo() => 0; } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 56, 3, + contextMessages: [message('/home/test/lib/test.dart', 19, 3)]), + ]); } - test_setter_overrides_external_field_final_valid() async { - await assertNoErrorsInCode(''' + test_mixin_setter_type() async { + await assertErrorsInCode(r''' class A { - external final num x; + set foo(String _) {} } -abstract class B implements A { - int get x; - void set x(int value); + +mixin M on A { + set foo(int _) {} } -'''); +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 57, 3, + contextMessages: [message('/home/test/lib/test.dart', 16, 3)]), + ]); } - test_setter_overrides_external_field_invalid() async { + test_setter_normalParamType() async { await assertErrorsInCode(''' class A { - external num x; + void set s(int v) {} } -abstract class B implements A { - int get x; - void set x(int value); +class B extends A { + void set s(String v) {} } ''', [ - error(CompileTimeErrorCode.INVALID_OVERRIDE, 86, 1, - contextMessages: [message('/home/test/lib/test.dart', 25, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 66, 1, + contextMessages: [message('/home/test/lib/test.dart', 21, 1)]), ]); } - test_setter_overrides_external_field_valid() async { - await assertNoErrorsInCode(''' -class A { - external int x; + test_setter_normalParamType_superclass_interface() async { + await assertErrorsInCode(''' +abstract class I { + set setter14(int _) => null; } -abstract class B implements A { - void set x(num value); +abstract class J { + set setter14(num _) => null; } -'''); +abstract class A extends I implements J {} +class B extends A { + set setter14(String _) => null; +} +''', [ + error(CompileTimeErrorCode.INVALID_OVERRIDE, 173, 8, + contextMessages: [message('/home/test/lib/test.dart', 77, 8)]), + ]); } - test_viaLegacy_class() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A1 { - int m() => 0; - int get g => 0; - set s(int? _) {} + test_setter_normalParamType_twoInterfaces() async { + // test from language/override_inheritance_field_test_34.dart + await assertErrorsInCode(''' +abstract class I { + set setter14(int _) => null; } - -class A2 { - int? m() => 0; - int? get g => 0; - set s(int _) {} +abstract class J { + set setter14(num _) => null; } -'''); - - newFile('$testPackageLibPath/b.dart', content: r''' -// @dart=2.6 -import 'a.dart'; - -class L extends A2 implements A1 {} -'''); - - await assertErrorsInCode(''' -import 'a.dart'; -import 'b.dart'; - -class X1 extends L implements A1 {} -class X2 extends L implements A2 {} - -class Y extends L { - int? get g => 0; - int? m() => 0; - set s(int _) {} +abstract class A implements I, J {} +class B extends A { + set setter14(String _) => null; } ''', [ - error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 24, 8), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 166, 8, + contextMessages: [message('/home/test/lib/test.dart', 77, 8)]), ]); } - test_viaLegacy_mixin() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A1 { - int m() => 0; - int get g => 0; - set s(int? _) {} + test_setter_normalParamType_twoInterfaces_conflicting() async { + await assertErrorsInCode(''' +abstract class I { + set s(U u) {} } - -mixin A2 { - int? m() => 0; - int? get g => 0; - set s(int _) {} +abstract class J { + set s(V v) {} } -'''); - - newFile('$testPackageLibPath/b.dart', content: r''' -// @dart=2.6 -import 'a.dart'; - -class L extends Object with A2 implements A1 {} -'''); - - await assertErrorsInCode(''' -import 'a.dart'; -import 'b.dart'; - -class X1 extends L implements A1 {} -class X2 extends L implements A2 {} - -class Y extends L { - int? get g => 0; - int? m() => 0; - set s(int _) {} +class B implements I, J { + set s(double d) {} } ''', [ - error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 24, 8), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1, + contextMessages: [message('/home/test/lib/test.dart', 28, 1)]), + error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1, + contextMessages: [message('/home/test/lib/test.dart', 68, 1)]), ]); } } diff --git a/pkg/analyzer/test/src/diagnostics/main_first_positional_parameter_type_test.dart b/pkg/analyzer/test/src/diagnostics/main_first_positional_parameter_type_test.dart index a8e490ce58451..1c09427ff4f1b 100644 --- a/pkg/analyzer/test/src/diagnostics/main_first_positional_parameter_type_test.dart +++ b/pkg/analyzer/test/src/diagnostics/main_first_positional_parameter_type_test.dart @@ -10,13 +10,31 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(MainFirstPositionalParameterTest); - defineReflectiveTests(MainFirstPositionalParameterWithNullSafetyTest); + defineReflectiveTests(MainFirstPositionalParameterWithoutNullSafetyTest); }); } @reflectiveTest class MainFirstPositionalParameterTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, MainFirstPositionalParameterTestCases {} + with MainFirstPositionalParameterTestCases { + test_positionalRequired_listOfStringQuestion() async { + await assertNoErrorsInCode(''' +void main(List args) {} +'''); + } + + test_positionalRequired_listQuestionOfString() async { + await assertNoErrorsInCode(''' +void main(List? args) {} +'''); + } + + test_positionalRequired_objectQuestion() async { + await assertNoErrorsInCode(''' +void main(Object? args) {} +'''); + } +} mixin MainFirstPositionalParameterTestCases on PubPackageResolutionTest { test_positionalOptional_listOfInt() async { @@ -72,24 +90,6 @@ void main(Object args) {} } @reflectiveTest -class MainFirstPositionalParameterWithNullSafetyTest +class MainFirstPositionalParameterWithoutNullSafetyTest extends PubPackageResolutionTest - with MainFirstPositionalParameterTestCases { - test_positionalRequired_listOfStringQuestion() async { - await assertNoErrorsInCode(''' -void main(List args) {} -'''); - } - - test_positionalRequired_listQuestionOfString() async { - await assertNoErrorsInCode(''' -void main(List? args) {} -'''); - } - - test_positionalRequired_objectQuestion() async { - await assertNoErrorsInCode(''' -void main(Object? args) {} -'''); - } -} + with WithoutNullSafetyMixin, MainFirstPositionalParameterTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/main_has_required_named_parameters_test.dart b/pkg/analyzer/test/src/diagnostics/main_has_required_named_parameters_test.dart index 46a8f2fc16ebd..65e103e9600f1 100644 --- a/pkg/analyzer/test/src/diagnostics/main_has_required_named_parameters_test.dart +++ b/pkg/analyzer/test/src/diagnostics/main_has_required_named_parameters_test.dart @@ -10,13 +10,21 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(MainHasRequiredNamedParametersTest); - defineReflectiveTests(MainHasRequiredNamedParametersWithNullSafetyTest); + defineReflectiveTests(MainHasRequiredNamedParametersWithoutNullSafetyTest); }); } @reflectiveTest class MainHasRequiredNamedParametersTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, MainHasRequiredNamedParametersTestCases {} + with MainHasRequiredNamedParametersTestCases { + test_namedRequired() async { + await assertErrorsInCode(''' +void main({required List a}) {} +''', [ + error(CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS, 5, 4), + ]); + } +} mixin MainHasRequiredNamedParametersTestCases on PubPackageResolutionTest { test_namedOptional() async { @@ -28,14 +36,6 @@ void main({int a = 0}) {} } @reflectiveTest -class MainHasRequiredNamedParametersWithNullSafetyTest +class MainHasRequiredNamedParametersWithoutNullSafetyTest extends PubPackageResolutionTest - with MainHasRequiredNamedParametersTestCases { - test_namedRequired() async { - await assertErrorsInCode(''' -void main({required List a}) {} -''', [ - error(CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS, 5, 4), - ]); - } -} + with WithoutNullSafetyMixin, MainHasRequiredNamedParametersTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/main_has_too_many_required_positional_parameters_test.dart b/pkg/analyzer/test/src/diagnostics/main_has_too_many_required_positional_parameters_test.dart index b08a0390587cf..e1061f811fbef 100644 --- a/pkg/analyzer/test/src/diagnostics/main_has_too_many_required_positional_parameters_test.dart +++ b/pkg/analyzer/test/src/diagnostics/main_has_too_many_required_positional_parameters_test.dart @@ -9,9 +9,11 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(MainHasTooManyRequiredPositionalParametersTest); defineReflectiveTests( - MainHasTooManyRequiredPositionalParametersWithNullSafetyTest, + MainHasTooManyRequiredPositionalParametersTest, + ); + defineReflectiveTests( + MainHasTooManyRequiredPositionalParametersWithoutNullSafetyTest, ); }); } @@ -19,9 +21,20 @@ main() { @reflectiveTest class MainHasTooManyRequiredPositionalParametersTest extends PubPackageResolutionTest - with - WithoutNullSafetyMixin, - MainHasTooManyRequiredPositionalParametersTestCases {} + with MainHasTooManyRequiredPositionalParametersTestCases { + test_positionalRequired_3_namedRequired_1() async { + await resolveTestCode(''' +void main(args, int a, int b, {required int c}) {} +'''); + assertErrorsInResult(expectedErrorsByNullability(nullable: [ + error(CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS, 5, 4), + error( + CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS, + 5, + 4), + ], legacy: [])); + } +} mixin MainHasTooManyRequiredPositionalParametersTestCases on PubPackageResolutionTest { @@ -93,19 +106,8 @@ void main(args, int a, int b, {int c = 0}) {} } @reflectiveTest -class MainHasTooManyRequiredPositionalParametersWithNullSafetyTest +class MainHasTooManyRequiredPositionalParametersWithoutNullSafetyTest extends PubPackageResolutionTest - with MainHasTooManyRequiredPositionalParametersTestCases { - test_positionalRequired_3_namedRequired_1() async { - await resolveTestCode(''' -void main(args, int a, int b, {required int c}) {} -'''); - assertErrorsInResult(expectedErrorsByNullability(nullable: [ - error(CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS, 5, 4), - error( - CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS, - 5, - 4), - ], legacy: [])); - } -} + with + WithoutNullSafetyMixin, + MainHasTooManyRequiredPositionalParametersTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/main_is_not_function_test.dart b/pkg/analyzer/test/src/diagnostics/main_is_not_function_test.dart index 93d3d3780af86..2cf8747a715ce 100644 --- a/pkg/analyzer/test/src/diagnostics/main_is_not_function_test.dart +++ b/pkg/analyzer/test/src/diagnostics/main_is_not_function_test.dart @@ -10,13 +10,13 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(MainIsNotFunctionTest); - defineReflectiveTests(MainIsNotFunctionWithNullSafetyTest); + defineReflectiveTests(MainIsNotFunctionWithoutNullSafetyTest); }); } @reflectiveTest class MainIsNotFunctionTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, MainIsNotFunctionTestCases {} + with MainIsNotFunctionTestCases {} mixin MainIsNotFunctionTestCases on PubPackageResolutionTest { test_class() async { @@ -104,5 +104,5 @@ var main = 0; } @reflectiveTest -class MainIsNotFunctionWithNullSafetyTest extends PubPackageResolutionTest - with MainIsNotFunctionTestCases {} +class MainIsNotFunctionWithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin, MainIsNotFunctionTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart index 456f6d04f6fb5..c70450cf5855a 100644 --- a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart +++ b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart @@ -11,239 +11,12 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(MissingRequiredParamTest); - defineReflectiveTests(MissingRequiredParamWithNullSafetyTest); + defineReflectiveTests(MissingRequiredParamWithoutNullSafetyTest); }); } @reflectiveTest -class MissingRequiredParamTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { - @override - void setUp() { - super.setUp(); - writeTestPackageConfigWithMeta(); - } - - test_constructor_argumentGiven() async { - await assertNoErrorsInCode(r''' -import 'package:meta/meta.dart'; - -class C { - C({@required int a}) {} -} - -main() { - new C(a: 2); -} -'''); - } - - test_constructor_fieldFormalParameter() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -class C { - final int a; - C({@required this.a}); -} - -main() { - new C(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM, 102, 1), - ]); - } - - test_constructor_hasReason() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; -class C { - C({@Required('must specify an `a`') int a}) {} -} -main() { - new C(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 109, 1), - ]); - } - - test_constructor_noReason() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -class C { - C({@required int a}) {} -} - -main() { - new C(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM, 88, 1), - ]); - } - - test_constructor_noReason_generic() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -class C { - C({@required int a}) {} -} - -main() { - new C(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM, 91, 1), - ]); - } - - test_constructor_nullReason() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -class C { - C({@Required(null) int a}) {} -} - -main() { - new C(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM, 94, 1), - ]); - } - - test_constructor_redirectingConstructorCall() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; -class C { - C({@required int x}); - C.named() : this(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM, 81, 6), - ]); - } - - test_constructor_superCall() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -class C { - C({@Required('must specify an `a`') int a}) {} -} - -class D extends C { - D() : super(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 124, 7), - ]); - } - - test_function() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -void f({@Required('must specify an `a`') int a}) {} - -main() { - f(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 98, 1), - ]); - } - - test_method() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - void m({@Required('must specify an `a`') int a}) {} -} -f() { - new A().m(); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 115, 1), - ]); - } - - test_method_generic() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -class A { - void m(U a, {@Required('must specify an `b`') int b}) {} -} -f() { - new A().m(true); -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 135, 1), - ]); - } - - test_method_inOtherLib() async { - newFile('$testPackageLibPath/a.dart', content: r''' -import 'package:meta/meta.dart'; -class A { - void m({@Required('must specify an `a`') int a}) {} -} -'''); - newFile('$testPackageLibPath/test.dart', content: r''' -import 'a.dart'; -f() { - new A().m(); -} -'''); - - await _resolveFile('$testPackageLibPath/a.dart'); - await _resolveFile('$testPackageLibPath/test.dart', [ - error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 33, 1), - ]); - } - - @FailingTest(reason: r''' -MISSING_REQUIRED_PARAM cannot be reported here with summary2, because -the return type of `C.m` is a structural FunctionType, which does -not know its elements, and does not know that there was a parameter -marked `@required`. There is exactly one such typedef in Flutter. -''') - test_typedef_function() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; - -String test(C c) => c.m()(); - -typedef String F({@required String x}); - -class C { - F m() => ({@required String x}) => null; -} -''', [ - error(HintCode.MISSING_REQUIRED_PARAM, 54, 7), - ]); - } - - /// Resolve the file with the given [path]. - /// - /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported. - Future _resolveFile( - String path, [ - List expectedErrors = const [], - ]) async { - result = await resolveFile(convertPath(path)); - assertErrorsInResolvedUnit(result, expectedErrors); - } -} - -@reflectiveTest -class MissingRequiredParamWithNullSafetyTest extends PubPackageResolutionTest { +class MissingRequiredParamTest extends PubPackageResolutionTest { test_constructor_legacy_argumentGiven() async { newFile('$testPackageLibPath/a.dart', content: r''' class A { @@ -492,3 +265,230 @@ class C { ]); } } + +@reflectiveTest +class MissingRequiredParamWithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin { + @override + void setUp() { + super.setUp(); + writeTestPackageConfigWithMeta(); + } + + test_constructor_argumentGiven() async { + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@required int a}) {} +} + +main() { + new C(a: 2); +} +'''); + } + + test_constructor_fieldFormalParameter() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + final int a; + C({@required this.a}); +} + +main() { + new C(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM, 102, 1), + ]); + } + + test_constructor_hasReason() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class C { + C({@Required('must specify an `a`') int a}) {} +} +main() { + new C(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 109, 1), + ]); + } + + test_constructor_noReason() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@required int a}) {} +} + +main() { + new C(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM, 88, 1), + ]); + } + + test_constructor_noReason_generic() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@required int a}) {} +} + +main() { + new C(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM, 91, 1), + ]); + } + + test_constructor_nullReason() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@Required(null) int a}) {} +} + +main() { + new C(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM, 94, 1), + ]); + } + + test_constructor_redirectingConstructorCall() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class C { + C({@required int x}); + C.named() : this(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM, 81, 6), + ]); + } + + test_constructor_superCall() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@Required('must specify an `a`') int a}) {} +} + +class D extends C { + D() : super(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 124, 7), + ]); + } + + test_function() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +void f({@Required('must specify an `a`') int a}) {} + +main() { + f(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 98, 1), + ]); + } + + test_method() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + void m({@Required('must specify an `a`') int a}) {} +} +f() { + new A().m(); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 115, 1), + ]); + } + + test_method_generic() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class A { + void m(U a, {@Required('must specify an `b`') int b}) {} +} +f() { + new A().m(true); +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 135, 1), + ]); + } + + test_method_inOtherLib() async { + newFile('$testPackageLibPath/a.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + void m({@Required('must specify an `a`') int a}) {} +} +'''); + newFile('$testPackageLibPath/test.dart', content: r''' +import 'a.dart'; +f() { + new A().m(); +} +'''); + + await _resolveFile('$testPackageLibPath/a.dart'); + await _resolveFile('$testPackageLibPath/test.dart', [ + error(HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS, 33, 1), + ]); + } + + @FailingTest(reason: r''' +MISSING_REQUIRED_PARAM cannot be reported here with summary2, because +the return type of `C.m` is a structural FunctionType, which does +not know its elements, and does not know that there was a parameter +marked `@required`. There is exactly one such typedef in Flutter. +''') + test_typedef_function() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +String test(C c) => c.m()(); + +typedef String F({@required String x}); + +class C { + F m() => ({@required String x}) => null; +} +''', [ + error(HintCode.MISSING_REQUIRED_PARAM, 54, 7), + ]); + } + + /// Resolve the file with the given [path]. + /// + /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported. + Future _resolveFile( + String path, [ + List expectedErrors = const [], + ]) async { + result = await resolveFile(convertPath(path)); + assertErrorsInResolvedUnit(result, expectedErrors); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart index 9f752750d32a9..4c1104b6989ab 100644 --- a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart +++ b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart @@ -10,12 +10,62 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(MissingReturnTest); - defineReflectiveTests(MissingReturnWithNullSafetyTest); + defineReflectiveTests(MissingReturnWithoutNullSafetyTest); }); } @reflectiveTest -class MissingReturnTest extends PubPackageResolutionTest +class MissingReturnTest extends PubPackageResolutionTest { + test_function_async_block_futureOrVoid() async { + await assertNoErrorsInCode(''' +import 'dart:async'; +FutureOr f() async {} +'''); + } + + test_function_async_block_void() async { + await assertNoErrorsInCode(''' +void f() async {} +'''); + } + + test_function_sync_block_dynamic() async { + await assertNoErrorsInCode(''' +dynamic f() {} +'''); + } + + test_function_sync_block_Never() async { + newFile('$testPackageLibPath/a.dart', content: r''' +Never foo() { + throw 0; +} +'''); + await assertNoErrorsInCode(r''' +// @dart = 2.8 +import 'a.dart'; + +int f() { + foo(); +} +'''); + } + + test_function_sync_block_Null() async { + await assertNoErrorsInCode(''' +Null f() {} +'''); + } + + test_function_sync_block_void() async { + await assertNoErrorsInCode(''' +void f() {} +'''); + } +} + +@reflectiveTest +class MissingReturnWithoutNullSafetyTest extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_alwaysThrows() async { writeTestPackageConfigWithMeta(); @@ -214,53 +264,3 @@ class B extends A { ]); } } - -@reflectiveTest -class MissingReturnWithNullSafetyTest extends PubPackageResolutionTest { - test_function_async_block_futureOrVoid() async { - await assertNoErrorsInCode(''' -import 'dart:async'; -FutureOr f() async {} -'''); - } - - test_function_async_block_void() async { - await assertNoErrorsInCode(''' -void f() async {} -'''); - } - - test_function_sync_block_dynamic() async { - await assertNoErrorsInCode(''' -dynamic f() {} -'''); - } - - test_function_sync_block_Never() async { - newFile('$testPackageLibPath/a.dart', content: r''' -Never foo() { - throw 0; -} -'''); - await assertNoErrorsInCode(r''' -// @dart = 2.8 -import 'a.dart'; - -int f() { - foo(); -} -'''); - } - - test_function_sync_block_Null() async { - await assertNoErrorsInCode(''' -Null f() {} -'''); - } - - test_function_sync_block_void() async { - await assertNoErrorsInCode(''' -void f() {} -'''); - } -} diff --git a/pkg/analyzer/test/src/diagnostics/mixin_inference_no_possible_substitution_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_inference_no_possible_substitution_test.dart index 6dc76c1b18810..2ba15574aa14d 100644 --- a/pkg/analyzer/test/src/diagnostics/mixin_inference_no_possible_substitution_test.dart +++ b/pkg/analyzer/test/src/diagnostics/mixin_inference_no_possible_substitution_test.dart @@ -9,36 +9,17 @@ import '../dart/resolution/resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(MixinInferenceNoPossibleSubstitutionTest); defineReflectiveTests( - MixinInferenceNoPossibleSubstitutionWithNullSafetyTest, + MixinInferenceNoPossibleSubstitutionTest, + ); + defineReflectiveTests( + MixinInferenceNoPossibleSubstitutionWithoutNullSafetyTest, ); }); } @reflectiveTest class MixinInferenceNoPossibleSubstitutionTest extends PubPackageResolutionTest - with - WithoutNullSafetyMixin, - MixinInferenceNoPossibleSubstitutionTestCases {} - -mixin MixinInferenceNoPossibleSubstitutionTestCases on ResolutionTest { - test_valid_single() async { - await assertNoErrorsInCode(r''' -class A {} - -mixin M on A {} - -class X extends A with M {} -'''); - - assertType(findNode.namedType('M {}'), 'M'); - } -} - -@reflectiveTest -class MixinInferenceNoPossibleSubstitutionWithNullSafetyTest - extends PubPackageResolutionTest with MixinInferenceNoPossibleSubstitutionTestCases { test_valid_nonNullableMixins_legacyApplication() async { newFile('$testPackageLibPath/a.dart', content: r''' @@ -59,3 +40,24 @@ class D extends A with B, C {} assertType(findNode.namedType('C {}'), 'C*'); } } + +mixin MixinInferenceNoPossibleSubstitutionTestCases on ResolutionTest { + test_valid_single() async { + await assertNoErrorsInCode(r''' +class A {} + +mixin M on A {} + +class X extends A with M {} +'''); + + assertType(findNode.namedType('M {}'), 'M'); + } +} + +@reflectiveTest +class MixinInferenceNoPossibleSubstitutionWithoutNullSafetyTest + extends PubPackageResolutionTest + with + WithoutNullSafetyMixin, + MixinInferenceNoPossibleSubstitutionTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart index 0d92e85dae14e..1d80a8d6588a8 100644 --- a/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart +++ b/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart @@ -10,95 +10,13 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(NoDefaultSuperConstructorTest); - defineReflectiveTests(NoDefaultSuperConstructorWithNullSafetyTest); + defineReflectiveTests(NoDefaultSuperConstructorWithoutNullSafetyTest); }); } @reflectiveTest class NoDefaultSuperConstructorTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, NoDefaultSuperConstructorTestCases { - test_super_requiredPositional_subclass_explicit() async { - await assertErrorsInCode(r''' -class A { - A(p); -} -class B extends A { - B(); -} -''', [ - error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, 42, 1), - ]); - } -} - -mixin NoDefaultSuperConstructorTestCases on PubPackageResolutionTest { - test_super_implicit_subclass_explicit() async { - await assertNoErrorsInCode(r''' -class A {} -class B extends A { - B(); -} -'''); - } - - test_super_implicit_subclass_implicit() async { - await assertNoErrorsInCode(r''' -class A {} -class B extends A {} -'''); - } - - test_super_noParameters() async { - await assertNoErrorsInCode(r''' -class A { - A(); -} -class B extends A { - B(); -} -'''); - } - - test_super_requiredPositional_subclass_explicit_language214() async { - await assertErrorsInCode(r''' -// @dart = 2.14 -class A { - A(p); -} -class B extends A { - B(); -} -''', [ - error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, 58, 1), - ]); - } - - test_super_requiredPositional_subclass_external() async { - await assertNoErrorsInCode(r''' -class A { - A(p); -} -class B extends A { - external B(); -} -'''); - } - - test_super_requiredPositional_subclass_implicit() async { - await assertErrorsInCode(r''' -class A { - A(p); -} -class B extends A {} -''', [ - error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 26, 1), - ]); - } -} - -@reflectiveTest -class NoDefaultSuperConstructorWithNullSafetyTest - extends PubPackageResolutionTest with NoDefaultSuperConstructorTestCases { + with NoDefaultSuperConstructorTestCases { test_super_optionalNamed_subclass_explicit() async { await assertNoErrorsInCode(r''' class A { @@ -310,3 +228,86 @@ class B extends A { '''); } } + +mixin NoDefaultSuperConstructorTestCases on PubPackageResolutionTest { + test_super_implicit_subclass_explicit() async { + await assertNoErrorsInCode(r''' +class A {} +class B extends A { + B(); +} +'''); + } + + test_super_implicit_subclass_implicit() async { + await assertNoErrorsInCode(r''' +class A {} +class B extends A {} +'''); + } + + test_super_noParameters() async { + await assertNoErrorsInCode(r''' +class A { + A(); +} +class B extends A { + B(); +} +'''); + } + + test_super_requiredPositional_subclass_explicit_language214() async { + await assertErrorsInCode(r''' +// @dart = 2.14 +class A { + A(p); +} +class B extends A { + B(); +} +''', [ + error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, 58, 1), + ]); + } + + test_super_requiredPositional_subclass_external() async { + await assertNoErrorsInCode(r''' +class A { + A(p); +} +class B extends A { + external B(); +} +'''); + } + + test_super_requiredPositional_subclass_implicit() async { + await assertErrorsInCode(r''' +class A { + A(p); +} +class B extends A {} +''', [ + error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 26, 1), + ]); + } +} + +@reflectiveTest +class NoDefaultSuperConstructorWithoutNullSafetyTest + extends PubPackageResolutionTest + with WithoutNullSafetyMixin, NoDefaultSuperConstructorTestCases { + test_super_requiredPositional_subclass_explicit() async { + await assertErrorsInCode(r''' +class A { + A(p); +} +class B extends A { + B(); +} +''', [ + error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, 42, 1), + ]); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/non_abstract_class_inherits_abstract_member_test.dart b/pkg/analyzer/test/src/diagnostics/non_abstract_class_inherits_abstract_member_test.dart index 5976ffd8532e6..028a5c4e27a04 100644 --- a/pkg/analyzer/test/src/diagnostics/non_abstract_class_inherits_abstract_member_test.dart +++ b/pkg/analyzer/test/src/diagnostics/non_abstract_class_inherits_abstract_member_test.dart @@ -9,881 +9,884 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(NonAbstractClassInheritsAbstractMemberTest); defineReflectiveTests( - NonAbstractClassInheritsAbstractMemberWithNullSafetyTest); + NonAbstractClassInheritsAbstractMemberTest, + ); + defineReflectiveTests( + NonAbstractClassInheritsAbstractMemberWithoutNullSafetyTest, + ); }); } @reflectiveTest class NonAbstractClassInheritsAbstractMemberTest extends PubPackageResolutionTest - with - WithoutNullSafetyMixin, - NonAbstractClassInheritsAbstractMemberTestCases {} - -mixin NonAbstractClassInheritsAbstractMemberTestCases - on PubPackageResolutionTest { - test_abstractsDontOverrideConcretes_getter() async { - await assertNoErrorsInCode(r''' -class A { - int get g => 0; -} -abstract class B extends A { - int get g; -} -class C extends B {} -'''); - } - - test_abstractsDontOverrideConcretes_method() async { - await assertNoErrorsInCode(r''' -class A { - m(p) {} -} -abstract class B extends A { - m(p); -} -class C extends B {} -'''); - } - - test_abstractsDontOverrideConcretes_setter() async { - await assertNoErrorsInCode(r''' -class A { - set s(v) {} -} -abstract class B extends A { - set s(v); -} -class C extends B {} -'''); - } - - test_classTypeAlias_interface() async { - // issue 15979 - await assertNoErrorsInCode(r''' -abstract class M {} -abstract class A {} -abstract class I { - m(); -} -abstract class B = A with M implements I; -'''); - } - - test_classTypeAlias_mixin() async { - // issue 15979 - await assertNoErrorsInCode(r''' -abstract class M { - m(); -} -abstract class A {} -abstract class B = A with M; -'''); - } - - test_classTypeAlias_superclass() async { - // issue 15979 - await assertNoErrorsInCode(r''' -class M {} + with NonAbstractClassInheritsAbstractMemberTestCases { + test_abstract_field_final_implement_getter() async { + await assertNoErrorsInCode(''' abstract class A { - m(); + abstract final int x; +} +class B implements A { + int get x => 0; } -abstract class B = A with M; '''); } - test_fivePlus() async { + test_abstract_field_final_implement_none() async { await assertErrorsInCode(''' abstract class A { - m(); - n(); - o(); - p(); - q(); -} -class C extends A { + abstract final int x; } +class B implements A {} ''', [ error( - CompileTimeErrorCode - .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, - 62, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 51, 1), ]); } - test_four() async { + test_abstract_field_implement_getter() async { await assertErrorsInCode(''' abstract class A { - m(); - n(); - o(); - p(); + abstract int x; } -class C extends A { +class B implements A { + int get x => 0; } ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, - 55, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 45, 1), ]); } - test_mixin_concreteGetter() async { - // issue 17034 - await assertNoErrorsInCode(r''' -class A { - var a; -} -abstract class M { - get a; -} -class B extends A with M {} -class C extends B {} -'''); - } - - test_mixin_concreteMethod() async { - await assertNoErrorsInCode(r''' -class A { - m() {} -} -abstract class M { - m(); -} -class B extends A with M {} -class C extends B {} -'''); - } - - test_mixin_concreteSetter() async { - await assertNoErrorsInCode(r''' -class A { - var a; + test_abstract_field_implement_getter_and_setter() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract int x; } -abstract class M { - set a(dynamic v); +class B implements A { + int get x => 0; + void set x(int value) {} } -class B extends A with M {} -class C extends B {} '''); } - test_noSuchMethod_concreteAccessor() async { - await assertNoErrorsInCode(r''' + test_abstract_field_implement_none() async { + await assertErrorsInCode(''' abstract class A { - int get g; -} -class B extends A { - noSuchMethod(v) => ''; + abstract int x; } -'''); +class B implements A {} +''', [ + error( + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, + 45, + 1), + ]); } - test_noSuchMethod_concreteMethod() async { - await assertNoErrorsInCode(r''' + test_abstract_field_implement_setter() async { + await assertErrorsInCode(''' abstract class A { - m(p); + abstract int x; } -class B extends A { - noSuchMethod(v) => ''; +class B implements A { + void set x(int value) {} } -'''); +''', [ + error( + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 45, + 1), + ]); } - test_noSuchMethod_mixin() async { - await assertNoErrorsInCode(r''' + test_enum_getter_fromInterface() async { + await assertErrorsInCode(''' class A { - noSuchMethod(v) => ''; -} -class B extends Object with A { - m(p); + int get foo => 0; } -'''); - } - test_noSuchMethod_superclass() async { - await assertNoErrorsInCode(r''' -class A { - noSuchMethod(v) => ''; -} -class B extends A { - m(p); +enum E implements A { + v; } -'''); +''', [ + error( + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 38, + 1), + ]); } - test_one_classTypeAlias_interface() async { - // issue 15979 + test_enum_getter_fromMixin() async { await assertErrorsInCode(''' -abstract class M {} -abstract class A {} -abstract class I { - m(); +mixin M { + int get foo; +} + +enum E with M { + v; } -class B = A with M implements I; ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 74, + 33, 1), ]); } - test_one_classTypeAlias_mixin() async { - // issue 15979 + test_enum_method_fromInterface() async { await assertErrorsInCode(''' -abstract class M { - m(); +class A { + void foo() {} +} + +enum E implements A { + v; } -abstract class A {} -class B = A with M; ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 54, + 34, 1), ]); } - test_one_classTypeAlias_superclass() async { - // issue 15979 + test_enum_method_fromMixin() async { await assertErrorsInCode(''' -class M {} -abstract class A { - m(); +mixin M { + void foo(); +} + +enum E with M { + v; } -class B = A with M; ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 45, + 32, 1), ]); } - test_one_getter_fromInterface() async { + test_enum_setter_fromInterface() async { await assertErrorsInCode(''' -class I { - int get g {return 1;} +class A { + set foo(int _) {} } -class C implements I { + +enum E implements A { + v; } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 42, + 38, 1), ]); } - test_one_getter_fromSuperclass() async { + test_enum_setter_fromMixin() async { await assertErrorsInCode(''' -abstract class A { - int get g; +mixin M { + set foo(int _); } -class C extends A { + +enum E with M { + v; } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 40, + 36, 1), ]); } - test_one_method_fromInterface() async { - await assertErrorsInCode(''' -class I { - m(p) {} + test_external_field_final_implement_getter() async { + await assertNoErrorsInCode(''' +class A { + external final int x; } -class C implements I { +class B implements A { + int get x => 0; +} +'''); + } + + test_external_field_final_implement_none() async { + await assertErrorsInCode(''' +class A { + external final int x; } +class B implements A {} ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 28, + 42, 1), ]); } - test_one_method_fromInterface_abstractNSM() async { + test_external_field_implement_getter() async { await assertErrorsInCode(''' -class I { - m(p) {} +class A { + external int x; } -class C implements I { - noSuchMethod(v); +class B implements A { + int get x => 0; } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 28, + 36, 1), ]); } - test_one_method_fromInterface_abstractOverrideNSM() async { + test_external_field_implement_getter_and_setter() async { await assertNoErrorsInCode(''' -class I { - m(p) {} -} -class B { - noSuchMethod(v) => null; +class A { + external int x; } -class C extends B implements I { - noSuchMethod(v); +class B implements A { + int get x => 0; + void set x(int value) {} } '''); } - test_one_method_fromInterface_ifcNSM() async { + test_external_field_implement_none() async { await assertErrorsInCode(''' -class I { - m(p) {} - noSuchMethod(v) => null; -} -class C implements I { +class A { + external int x; } +class B implements A {} ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 55, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, + 36, 1), ]); } - test_one_method_fromSuperclass() async { + test_external_field_implement_setter() async { await assertErrorsInCode(''' -abstract class A { - m(p); +class A { + external int x; } -class C extends A { +class B implements A { + void set x(int value) {} } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 35, + 36, 1), ]); } +} - test_one_method_optionalParamCount() async { - // issue 7640 - await assertErrorsInCode(''' -abstract class A { - int x(int a); +mixin NonAbstractClassInheritsAbstractMemberTestCases + on PubPackageResolutionTest { + test_abstractsDontOverrideConcretes_getter() async { + await assertNoErrorsInCode(r''' +class A { + int get g => 0; } -abstract class B { - int x(int a, [int b]); +abstract class B extends A { + int get g; } -class C implements A, B { +class C extends B {} +'''); + } + + test_abstractsDontOverrideConcretes_method() async { + await assertNoErrorsInCode(r''' +class A { + m(p) {} } -''', [ - error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 89, - 1), - ]); +abstract class B extends A { + m(p); +} +class C extends B {} +'''); } - test_one_mixinInherits_getter() async { - // issue 15001 + test_abstractsDontOverrideConcretes_setter() async { + await assertNoErrorsInCode(r''' +class A { + set s(v) {} +} +abstract class B extends A { + set s(v); +} +class C extends B {} +'''); + } + + test_classTypeAlias_interface() async { + // issue 15979 + await assertNoErrorsInCode(r''' +abstract class M {} +abstract class A {} +abstract class I { + m(); +} +abstract class B = A with M implements I; +'''); + } + + test_classTypeAlias_mixin() async { + // issue 15979 + await assertNoErrorsInCode(r''' +abstract class M { + m(); +} +abstract class A {} +abstract class B = A with M; +'''); + } + + test_classTypeAlias_superclass() async { + // issue 15979 + await assertNoErrorsInCode(r''' +class M {} +abstract class A { + m(); +} +abstract class B = A with M; +'''); + } + + test_fivePlus() async { await assertErrorsInCode(''' -abstract class A { get g1; get g2; } -abstract class B implements A { get g1 => 1; } -class C extends Object with B {} +abstract class A { + m(); + n(); + o(); + p(); + q(); +} +class C extends A { +} ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 90, + CompileTimeErrorCode + .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, + 62, 1), ]); } - test_one_mixinInherits_method() async { - // issue 15001 + test_four() async { await assertErrorsInCode(''' -abstract class A { m1(); m2(); } -abstract class B implements A { m1() => 1; } -class C extends Object with B {} +abstract class A { + m(); + n(); + o(); + p(); +} +class C extends A { +} ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 84, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, + 55, 1), ]); } - test_one_mixinInherits_setter() async { - // issue 15001 - await assertErrorsInCode(''' -abstract class A { set s1(v); set s2(v); } -abstract class B implements A { set s1(v) {} } -class C extends Object with B {} -''', [ - error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 96, - 1), - ]); + test_mixin_concreteGetter() async { + // issue 17034 + await assertNoErrorsInCode(r''' +class A { + var a; +} +abstract class M { + get a; +} +class B extends A with M {} +class C extends B {} +'''); } - test_one_noSuchMethod_interface() async { - // issue 15979 - await assertErrorsInCode(''' -class I { - noSuchMethod(v) => ''; + test_mixin_concreteMethod() async { + await assertNoErrorsInCode(r''' +class A { + m() {} } -abstract class A { +abstract class M { m(); } -class B extends A implements I { +class B extends A with M {} +class C extends B {} +'''); + } + + test_mixin_concreteSetter() async { + await assertNoErrorsInCode(r''' +class A { + var a; } -''', [ - error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 71, - 1), - ]); +abstract class M { + set a(dynamic v); +} +class B extends A with M {} +class C extends B {} +'''); } - test_one_setter_and_implicitSetter() async { - // test from language/override_inheritance_abstract_test_14.dart - await assertErrorsInCode(''' + test_noSuchMethod_concreteAccessor() async { + await assertNoErrorsInCode(r''' abstract class A { - set field(_); + int get g; } -abstract class I { - var field; +class B extends A { + noSuchMethod(v) => ''; } -class B extends A implements I { - get field => 0; +'''); + } + + test_noSuchMethod_concreteMethod() async { + await assertNoErrorsInCode(r''' +abstract class A { + m(p); } -''', [ - error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 77, - 1), - ]); +class B extends A { + noSuchMethod(v) => ''; +} +'''); } - test_one_setter_fromInterface() async { - await assertErrorsInCode(''' -class I { - set s(int i) {} + test_noSuchMethod_mixin() async { + await assertNoErrorsInCode(r''' +class A { + noSuchMethod(v) => ''; } -class C implements I { +class B extends Object with A { + m(p); } -''', [ - error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 36, - 1), - ]); +'''); } - test_one_setter_fromSuperclass() async { - await assertErrorsInCode(''' -abstract class A { - set s(int i); + test_noSuchMethod_superclass() async { + await assertNoErrorsInCode(r''' +class A { + noSuchMethod(v) => ''; } -class C extends A { +class B extends A { + m(p); +} +'''); + } + + test_one_classTypeAlias_interface() async { + // issue 15979 + await assertErrorsInCode(''' +abstract class M {} +abstract class A {} +abstract class I { + m(); } +class B = A with M implements I; ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 43, + 74, 1), ]); } - test_one_superclasses_interface() async { - // issue 11154 + test_one_classTypeAlias_mixin() async { + // issue 15979 await assertErrorsInCode(''' -class A { - get a => 'a'; -} -abstract class B implements A { - get b => 'b'; -} -class C extends B { +abstract class M { + m(); } +abstract class A {} +class B = A with M; ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 84, + 54, 1), ]); } - test_one_variable_fromInterface_missingGetter() async { - // issue 16133 + test_one_classTypeAlias_superclass() async { + // issue 15979 await assertErrorsInCode(''' -class I { - var v; -} -class C implements I { - set v(_) {} +class M {} +abstract class A { + m(); } +class B = A with M; ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 27, + 45, 1), ]); } - test_one_variable_fromInterface_missingSetter() async { - // issue 16133 + test_one_getter_fromInterface() async { await assertErrorsInCode(''' class I { - var v; + int get g {return 1;} } class C implements I { - get v => 1; } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 27, + 42, 1), ]); } - test_overridesConcreteMethodInObject() async { - await assertNoErrorsInCode(r''' -class A { - String toString([String prefix = '']) => '${prefix}Hello'; -} -class C {} -class B extends A with C {} -'''); - } - - test_three() async { + test_one_getter_fromSuperclass() async { await assertErrorsInCode(''' abstract class A { - m(); - n(); - o(); + int get g; } class C extends A { } ''', [ error( - CompileTimeErrorCode - .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, - 48, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 40, 1), ]); } - test_two() async { + test_one_method_fromInterface() async { await assertErrorsInCode(''' -abstract class A { - m(); - n(); +class I { + m(p) {} } -class C extends A { +class C implements I { } ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, - 41, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 28, 1), ]); } - test_two_fromInterface_missingBoth() async { - // issue 16133 + test_one_method_fromInterface_abstractNSM() async { await assertErrorsInCode(''' class I { - var v; + m(p) {} } class C implements I { + noSuchMethod(v); } ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, - 27, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 28, 1), ]); } -} -@reflectiveTest -class NonAbstractClassInheritsAbstractMemberWithNullSafetyTest - extends PubPackageResolutionTest - with NonAbstractClassInheritsAbstractMemberTestCases { - test_abstract_field_final_implement_getter() async { + test_one_method_fromInterface_abstractOverrideNSM() async { await assertNoErrorsInCode(''' -abstract class A { - abstract final int x; +class I { + m(p) {} } -class B implements A { - int get x => 0; +class B { + noSuchMethod(v) => null; +} +class C extends B implements I { + noSuchMethod(v); } '''); } - test_abstract_field_final_implement_none() async { + test_one_method_fromInterface_ifcNSM() async { await assertErrorsInCode(''' -abstract class A { - abstract final int x; +class I { + m(p) {} + noSuchMethod(v) => null; +} +class C implements I { } -class B implements A {} ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 51, + 55, 1), ]); } - test_abstract_field_implement_getter() async { + test_one_method_fromSuperclass() async { await assertErrorsInCode(''' abstract class A { - abstract int x; + m(p); } -class B implements A { - int get x => 0; +class C extends A { } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 45, + 35, 1), ]); } - test_abstract_field_implement_getter_and_setter() async { - await assertNoErrorsInCode(''' + test_one_method_optionalParamCount() async { + // issue 7640 + await assertErrorsInCode(''' abstract class A { - abstract int x; + int x(int a); } -class B implements A { - int get x => 0; - void set x(int value) {} +abstract class B { + int x(int a, [int b]); } -'''); - } - - test_abstract_field_implement_none() async { - await assertErrorsInCode(''' -abstract class A { - abstract int x; +class C implements A, B { } -class B implements A {} ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, - 45, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 89, 1), ]); } - test_abstract_field_implement_setter() async { + test_one_mixinInherits_getter() async { + // issue 15001 await assertErrorsInCode(''' -abstract class A { - abstract int x; -} -class B implements A { - void set x(int value) {} -} +abstract class A { get g1; get g2; } +abstract class B implements A { get g1 => 1; } +class C extends Object with B {} ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 45, + 90, 1), ]); } - test_enum_getter_fromInterface() async { + test_one_mixinInherits_method() async { + // issue 15001 await assertErrorsInCode(''' -class A { - int get foo => 0; -} - -enum E implements A { - v; -} +abstract class A { m1(); m2(); } +abstract class B implements A { m1() => 1; } +class C extends Object with B {} ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 38, + 84, 1), ]); } - test_enum_getter_fromMixin() async { + test_one_mixinInherits_setter() async { + // issue 15001 await assertErrorsInCode(''' -mixin M { - int get foo; -} - -enum E with M { - v; -} +abstract class A { set s1(v); set s2(v); } +abstract class B implements A { set s1(v) {} } +class C extends Object with B {} ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 33, + 96, 1), ]); } - test_enum_method_fromInterface() async { + test_one_noSuchMethod_interface() async { + // issue 15979 await assertErrorsInCode(''' -class A { - void foo() {} +class I { + noSuchMethod(v) => ''; } - -enum E implements A { - v; +abstract class A { + m(); +} +class B extends A implements I { } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 34, + 71, 1), ]); } - test_enum_method_fromMixin() async { + test_one_setter_and_implicitSetter() async { + // test from language/override_inheritance_abstract_test_14.dart await assertErrorsInCode(''' -mixin M { - void foo(); +abstract class A { + set field(_); } - -enum E with M { - v; +abstract class I { + var field; +} +class B extends A implements I { + get field => 0; } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 32, + 77, 1), ]); } - test_enum_setter_fromInterface() async { + test_one_setter_fromInterface() async { await assertErrorsInCode(''' -class A { - set foo(int _) {} +class I { + set s(int i) {} } - -enum E implements A { - v; +class C implements I { } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 38, + 36, 1), ]); } - test_enum_setter_fromMixin() async { + test_one_setter_fromSuperclass() async { await assertErrorsInCode(''' -mixin M { - set foo(int _); +abstract class A { + set s(int i); } - -enum E with M { - v; +class C extends A { } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 36, + 43, 1), ]); } - test_external_field_final_implement_getter() async { - await assertNoErrorsInCode(''' + test_one_superclasses_interface() async { + // issue 11154 + await assertErrorsInCode(''' class A { - external final int x; + get a => 'a'; } -class B implements A { - int get x => 0; +abstract class B implements A { + get b => 'b'; } -'''); +class C extends B { +} +''', [ + error( + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, + 84, + 1), + ]); } - test_external_field_final_implement_none() async { + test_one_variable_fromInterface_missingGetter() async { + // issue 16133 await assertErrorsInCode(''' -class A { - external final int x; +class I { + var v; +} +class C implements I { + set v(_) {} } -class B implements A {} ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 42, + 27, 1), ]); } - test_external_field_implement_getter() async { + test_one_variable_fromInterface_missingSetter() async { + // issue 16133 await assertErrorsInCode(''' -class A { - external int x; +class I { + var v; } -class B implements A { - int get x => 0; +class C implements I { + get v => 1; } ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 36, + 27, 1), ]); } - test_external_field_implement_getter_and_setter() async { - await assertNoErrorsInCode(''' + test_overridesConcreteMethodInObject() async { + await assertNoErrorsInCode(r''' class A { - external int x; -} -class B implements A { - int get x => 0; - void set x(int value) {} + String toString([String prefix = '']) => '${prefix}Hello'; } +class C {} +class B extends A with C {} '''); } - test_external_field_implement_none() async { + test_three() async { await assertErrorsInCode(''' -class A { - external int x; +abstract class A { + m(); + n(); + o(); +} +class C extends A { +} +''', [ + error( + CompileTimeErrorCode + .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, + 48, + 1), + ]); + } + + test_two() async { + await assertErrorsInCode(''' +abstract class A { + m(); + n(); +} +class C extends A { } -class B implements A {} ''', [ error( CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, - 36, + 41, 1), ]); } - test_external_field_implement_setter() async { + test_two_fromInterface_missingBoth() async { + // issue 16133 await assertErrorsInCode(''' -class A { - external int x; +class I { + var v; } -class B implements A { - void set x(int value) {} +class C implements I { } ''', [ error( - CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, - 36, + CompileTimeErrorCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, + 27, 1), ]); } } + +@reflectiveTest +class NonAbstractClassInheritsAbstractMemberWithoutNullSafetyTest + extends PubPackageResolutionTest + with + WithoutNullSafetyMixin, + NonAbstractClassInheritsAbstractMemberTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart index 3f99747535152..03a7c939a618b 100644 --- a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart +++ b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart @@ -9,16 +9,84 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(NonBoolConditionTest); + defineReflectiveTests(NonBoolConditionWithoutNullSafetyTest); defineReflectiveTests( NonBoolConditionWithoutNullSafetyAndNoImplicitCastsTest); - defineReflectiveTests(NonBoolConditionWithNullSafetyTest); + defineReflectiveTests(NonBoolConditionTest); defineReflectiveTests(NonBoolConditionWithStrictCastsTest); }); } @reflectiveTest -class NonBoolConditionTest extends PubPackageResolutionTest +class NonBoolConditionTest extends PubPackageResolutionTest { + test_if_null() async { + await assertErrorsInCode(r''' +void f(Null a) { + if (a) {} +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_CONDITION, 23, 1), + ]); + } + + test_ternary_condition_null() async { + await assertErrorsInCode(r''' +void f(Null a) { + a ? 0 : 1; +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_CONDITION, 19, 1), + ]); + } +} + +@reflectiveTest +class NonBoolConditionWithoutNullSafetyAndNoImplicitCastsTest + extends PubPackageResolutionTest + with WithoutNullSafetyMixin, WithNoImplicitCastsMixin { + test_map_ifElement_condition_dynamic() async { + await assertErrorsWithNoImplicitCasts(r''' +void f(dynamic c) { + {if (c) 0: 0}; +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_CONDITION, 37, 1), + ]); + } + + test_map_ifElement_condition_object() async { + await assertErrorsWithNoImplicitCasts(r''' +void f(Object c) { + {if (c) 0: 0}; +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_CONDITION, 36, 1), + ]); + } + + test_set_ifElement_condition_dynamic() async { + await assertErrorsWithNoImplicitCasts(r''' +void f(dynamic c) { + {if (c) 0}; +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_CONDITION, 32, 1), + ]); + } + + test_set_ifElement_condition_object() async { + await assertErrorsWithNoImplicitCasts(r''' +void f(Object c) { + {if (c) 0}; +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_CONDITION, 31, 1), + ]); + } +} + +@reflectiveTest +class NonBoolConditionWithoutNullSafetyTest extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_conditional() async { await assertErrorsInCode(''' @@ -215,74 +283,6 @@ f(Object o) { } } -@reflectiveTest -class NonBoolConditionWithNullSafetyTest extends PubPackageResolutionTest { - test_if_null() async { - await assertErrorsInCode(r''' -void f(Null a) { - if (a) {} -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_CONDITION, 23, 1), - ]); - } - - test_ternary_condition_null() async { - await assertErrorsInCode(r''' -void f(Null a) { - a ? 0 : 1; -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_CONDITION, 19, 1), - ]); - } -} - -@reflectiveTest -class NonBoolConditionWithoutNullSafetyAndNoImplicitCastsTest - extends PubPackageResolutionTest - with WithoutNullSafetyMixin, WithNoImplicitCastsMixin { - test_map_ifElement_condition_dynamic() async { - await assertErrorsWithNoImplicitCasts(r''' -void f(dynamic c) { - {if (c) 0: 0}; -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_CONDITION, 37, 1), - ]); - } - - test_map_ifElement_condition_object() async { - await assertErrorsWithNoImplicitCasts(r''' -void f(Object c) { - {if (c) 0: 0}; -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_CONDITION, 36, 1), - ]); - } - - test_set_ifElement_condition_dynamic() async { - await assertErrorsWithNoImplicitCasts(r''' -void f(dynamic c) { - {if (c) 0}; -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_CONDITION, 32, 1), - ]); - } - - test_set_ifElement_condition_object() async { - await assertErrorsWithNoImplicitCasts(r''' -void f(Object c) { - {if (c) 0}; -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_CONDITION, 31, 1), - ]); - } -} - @reflectiveTest class NonBoolConditionWithStrictCastsTest extends PubPackageResolutionTest with WithStrictCastsMixin { diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart index f0578adeab223..6b7c2c2958c15 100644 --- a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart +++ b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart @@ -10,14 +10,27 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(NonBoolNegationExpressionTest); - defineReflectiveTests(NonBoolNegationExpressionWithNullSafetyTest); + defineReflectiveTests(NonBoolNegationExpressionWithoutNullSafetyTest); defineReflectiveTests(NonBoolNegationExpressionWithStrictCastsTest); }); } @reflectiveTest -class NonBoolNegationExpressionTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { +class NonBoolNegationExpressionTest extends PubPackageResolutionTest { + test_null() async { + await assertErrorsInCode(''' +void m(Null x) { + !x; +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 20, 1), + ]); + } +} + +@reflectiveTest +class NonBoolNegationExpressionWithoutNullSafetyTest + extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_nonBool() async { await assertErrorsInCode(r''' f() { @@ -47,20 +60,6 @@ f(Object o) { } } -@reflectiveTest -class NonBoolNegationExpressionWithNullSafetyTest - extends PubPackageResolutionTest { - test_null() async { - await assertErrorsInCode(''' -void m(Null x) { - !x; -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 20, 1), - ]); - } -} - @reflectiveTest class NonBoolNegationExpressionWithStrictCastsTest extends PubPackageResolutionTest with WithStrictCastsMixin { diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart index 1b25120b3b592..027813b0ae93c 100644 --- a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart +++ b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart @@ -10,13 +10,38 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(NonBoolOperandTest); - defineReflectiveTests(NonBoolOperandWithNullSafetyTest); + defineReflectiveTests(NonBoolOperandWithoutNullSafetyTest); defineReflectiveTests(NonBoolOperandWithStrictCastsTest); }); } @reflectiveTest -class NonBoolOperandTest extends PubPackageResolutionTest +class NonBoolOperandTest extends PubPackageResolutionTest { + test_and_null() async { + await assertErrorsInCode(r''' +m() { + Null x; + if(x && true) {} +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_OPERAND, 21, 1), + ]); + } + + test_or_null() async { + await assertErrorsInCode(r''' +m() { + Null x; + if(x || false) {} +} +''', [ + error(CompileTimeErrorCode.NON_BOOL_OPERAND, 21, 1), + ]); + } +} + +@reflectiveTest +class NonBoolOperandWithoutNullSafetyTest extends PubPackageResolutionTest with WithoutNullSafetyMixin { test_and_left() async { await assertErrorsInCode(r''' @@ -87,31 +112,6 @@ bool f(bool left, double right) { } } -@reflectiveTest -class NonBoolOperandWithNullSafetyTest extends PubPackageResolutionTest { - test_and_null() async { - await assertErrorsInCode(r''' -m() { - Null x; - if(x && true) {} -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_OPERAND, 21, 1), - ]); - } - - test_or_null() async { - await assertErrorsInCode(r''' -m() { - Null x; - if(x || false) {} -} -''', [ - error(CompileTimeErrorCode.NON_BOOL_OPERAND, 21, 1), - ]); - } -} - @reflectiveTest class NonBoolOperandWithStrictCastsTest extends PubPackageResolutionTest with WithStrictCastsMixin { diff --git a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart index ef2d1d96050b3..b4dece1a0260e 100644 --- a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart +++ b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart @@ -10,12 +10,12 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(ReadWriteWithNullSafetyTest); + defineReflectiveTests(ReadWriteTest); }); } @reflectiveTest -class ReadWriteWithNullSafetyTest extends PubPackageResolutionTest { +class ReadWriteTest extends PubPackageResolutionTest { @override bool get retainDataForTesting => true; diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart index 2aea1940b5c13..3540ebc5775ac 100644 --- a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart +++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart @@ -11,764 +11,764 @@ main() { defineReflectiveSuite(() { defineReflectiveTests(TypeArgumentNotMatchingBoundsTest); defineReflectiveTests( - TypeArgumentNotMatchingBoundsWithNullSafetyTest, + TypeArgumentNotMatchingBoundsWithoutNullSafetyTest, ); }); } @reflectiveTest class TypeArgumentNotMatchingBoundsTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, TypeArgumentNotMatchingBoundsTestCases { - test_regression_42196_Null() async { - await assertNoErrorsInCode(r''' -typedef G = Function(X); -class A>, Y extends X> {} - -test() { print("OK"); } + with TypeArgumentNotMatchingBoundsTestCases { + test_enum_inferred() async { + await assertErrorsInCode(''' +enum E { + v(''); + const E(T t); +} +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 26, 1), + ]); + } -main() { - test>, dynamic>>(); + test_enum_superBounded() async { + await assertNoErrorsInCode(''' +enum E> { + v() } '''); } -} -mixin TypeArgumentNotMatchingBoundsTestCases on PubPackageResolutionTest { - test_classTypeAlias() async { - await assertErrorsInCode(r''' -class A {} -class B {} -class C {} -class G {} -class D = G with C; + test_enum_withTypeArguments() async { + await assertErrorsInCode(''' +enum E { + v() +} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 28, 6), ]); } - test_const() async { - await assertErrorsInCode(r''' -class A {} -class B {} -class G { - const G(); -} -f() { return const G(); } -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 81, 1), - ]); + test_extends_optIn_fromOptOut_Null() async { + newFile('$testPackageLibPath/a.dart', content: r''' +class A {} +'''); + + await assertNoErrorsInCode(r''' +// @dart=2.6 +import 'a.dart'; + +class A1 extends A {} +'''); } - test_const_matching() async { + test_extends_optIn_fromOptOut_otherTypeParameter() async { + newFile('$testPackageLibPath/a.dart', content: r''' +void foo() { +} +'''); + await assertNoErrorsInCode(r''' +// @dart=2.6 +import 'a.dart'; + class A {} class B extends A {} -class G { - const G(); + +main() { + foo(); } -f() { return const G(); } '''); } - test_extends() async { - await assertErrorsInCode(r''' -class A {} -class B {} -class G {} -class C extends G{} + test_functionReference() async { + await assertErrorsInCode(''' +void foo(T a) {} +void bar() { + foo; +} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 51, 6), ]); } - test_extends_regressionInIssue18468Fix() async { - // https://code.google.com/p/dart/issues/detail?id=18628 + test_functionReference_matching() async { + await assertNoErrorsInCode(''' +void foo(T a) {} +void bar() { + foo; +} +'''); + } + + test_functionReference_regularBounded() async { + await assertNoErrorsInCode(''' +void foo(T a) {} +void bar() { + foo; +} +'''); + } + + test_genericFunctionTypeArgument_invariant() async { await assertErrorsInCode(r''' -class X {} -class Y extends X {} +typedef F = T Function(T); +typedef FB = S Function(S); +class CB {} +void f(CB> a) {} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 119, 5, + contextMessages: [message('/home/test/lib/test.dart', 116, 9)]), ]); } - test_extensionOverride_hasTypeArguments() async { - await assertErrorsInCode(r''' -extension E on int { - void foo() {} + test_genericFunctionTypeArgument_regularBounded() async { + await assertNoErrorsInCode(r''' +typedef F1 = T Function(T); +typedef F2 = S Function(S); +class CB {} +void f(CB a) {} +'''); + } + + test_metadata_matching() async { + await assertNoErrorsInCode(r''' +class A { + const A(); } -void f() { - E(0).foo(); +@A() +void f() {} +'''); + } + + test_metadata_notMatching() async { + await assertErrorsInCode(r''' +class A { + const A(); } + +@A() +void f() {} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 70, 6), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 44, 6), ]); } - test_extensionOverride_hasTypeArguments_call() async { + test_metadata_notMatching_viaTypeAlias() async { await assertErrorsInCode(r''' -extension E on int { - void call() {} +class A { + const A(); } -void f() { - E(0)(); -} +typedef B = A; + +@B() +void f() {} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 6), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 66, 6), ]); } - test_fieldFormalParameter() async { + test_methodInvocation_genericFunctionTypeArgument_match() async { + await assertNoErrorsInCode(r''' +typedef F = void Function(); +void f()>() {} +void g() { + f(); +} +'''); + } + + test_methodInvocation_genericFunctionTypeArgument_mismatch() async { await assertErrorsInCode(r''' class A {} class B {} -class G {} -class C { - var f; - C(G this.f) {} +typedef F = void Function(); +void f()>() {} +void g() { + f(); } ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1, - contextMessages: [message('/home/test/lib/test.dart', 69, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 131, 1), ]); } - test_functionReturnType() async { + test_nonFunctionTypeAlias_body_typeArgument_mismatch() async { await assertErrorsInCode(r''' class A {} class B {} -class G {} -G f() => throw 0; +class G {} +typedef X = G; ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1, - contextMessages: [message('/home/test/lib/test.dart', 46, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1), ]); } - test_functionTypeAlias() async { + test_nonFunctionTypeAlias_body_typeArgument_regularBounded() async { + await assertNoErrorsInCode(r''' +class A {} +class B extends A {} +class G {} +typedef X = G; +'''); + } + + test_nonFunctionTypeAlias_body_typeArgument_superBounded() async { + await assertNoErrorsInCode(r''' +class A> {} +typedef X = List; +'''); + } + + test_nonFunctionTypeAlias_interfaceType_body_mismatch() async { await assertErrorsInCode(r''' class A {} class B {} -class G {} -typedef G f(); +class G {} +typedef X = G; ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1, - contextMessages: [message('/home/test/lib/test.dart', 54, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1), ]); } - test_functionTypedFormalParameter() async { + test_nonFunctionTypeAlias_interfaceType_body_regularBounded() async { + await assertNoErrorsInCode(r''' +class A {} +typedef X = A; +'''); + } + + test_nonFunctionTypeAlias_interfaceType_body_superBounded() async { await assertErrorsInCode(r''' -class A {} -class B {} -class G {} -f(G h()) {} +class A> {} +typedef X = A; ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1, - contextMessages: [message('/home/test/lib/test.dart', 48, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 42, 1, + contextMessages: [message('/home/test/lib/test.dart', 42, 1)]), ]); } - test_implements() async { + test_nonFunctionTypeAlias_interfaceType_parameter() async { await assertErrorsInCode(r''' class A {} -class B {} -class G {} -class C implements G{} +typedef X = Map; +void f(X a) {} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 58, 6, + contextMessages: [message('/home/test/lib/test.dart', 56, 9)]), ]); } - test_is() async { - await assertErrorsInCode(r''' + test_nonFunctionTypeAlias_interfaceType_parameter_regularBounded() async { + await assertNoErrorsInCode(r''' class A {} -class B {} -class G {} -var b = 1 is G; +class B extends A {} +typedef X = Map; +void f(X a) {} +'''); + } + + test_notRegularBounded_notSuperBounded_parameter_invariant() async { + await assertErrorsInCode(r''' +typedef A = X Function(X); +typedef G> = void Function(); +foo(G g) {} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1, - contextMessages: [message('/home/test/lib/test.dart', 59, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 92, 1, + contextMessages: [ + message('/home/test/lib/test.dart', 92, 1), + message('/home/test/lib/test.dart', 92, 1) + ]), ]); } - test_methodInvocation_localFunction() async { - await assertErrorsInCode(r''' -class Point { - Point(T x, T y); -} + test_regression_42196() async { + await assertNoErrorsInCode(r''' +typedef G = Function(X); +class A>, Y extends X> {} + +test() { print("OK"); } main() { - Point f(T x, T y) { - return new Point(x, y); - } - print(f('hello', 'world')); + test>, dynamic>>(); } -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6), - ]); +'''); } - test_methodInvocation_method() async { - await assertErrorsInCode(r''' -class Point { - Point(T x, T y); -} + test_regression_42196_object() async { + await assertNoErrorsInCode(r''' +typedef G = Function(X); +class A>, Y extends Never> {} -class PointFactory { - Point point(T x, T y) { - return new Point(x, y); - } -} +test() { print("OK"); } -f(PointFactory factory) { - print(factory.point('hello', 'world')); +main() { + test>, Object?>>(); } -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6), - ]); +'''); } - test_methodInvocation_topLevelFunction() async { - await assertErrorsInCode(r''' -class Point { - Point(T x, T y); -} + test_regression_42196_void() async { + await assertNoErrorsInCode(r''' +typedef G = Function(X); +class A>, Y extends Never> {} -Point f(T x, T y) { - return new Point(x, y); -} +test() { print("OK"); } main() { - print(f('hello', 'world')); + test>, void>>(); } -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6), - ]); +'''); } - test_methodReturnType() async { - await assertErrorsInCode(r''' -class A {} -class B {} -class G {} -class C { - G m() => throw 0; -} -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1, - contextMessages: [message('/home/test/lib/test.dart', 58, 4)]), - ]); + test_superBounded() async { + await assertNoErrorsInCode(r''' +class A> {} + +A get foo => throw 0; +'''); } - test_new() async { - await assertErrorsInCode(r''' -class A {} -class B {} -class G {} -f() { return new G(); } + test_typeLiteral_class() async { + await assertErrorsInCode(''' +class C {} +var t = C; ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 36, 6, + contextMessages: [message('/home/test/lib/test.dart', 34, 9)]), ]); } - test_new_matching() async { - await assertNoErrorsInCode(r''' -class A {} -class B extends A {} -class G {} -f() { return new G(); } -'''); - } - - test_new_superTypeOfUpperBound() async { - await assertErrorsInCode(r''' -class A {} -class B extends A {} -class C extends B {} -class G {} -f() { return new G(); } + test_typeLiteral_functionTypeAlias() async { + await assertErrorsInCode(''' +typedef Cb = void Function(); +var t = Cb; ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 6, + contextMessages: [message('/home/test/lib/test.dart', 53, 10)]), ]); } - test_not_matching_bounds() async { - // There should be an error, because Bar's type argument T is Foo, which - // doesn't extends Foo. + test_typeLiteral_typeAlias() async { await assertErrorsInCode(''' -class Foo {} -class Bar> {} -class Baz extends Bar {} -void main() {} +class C {} +typedef D = C; +var t = D; ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 3, - contextMessages: [message('/home/test/lib/test.dart', 65, 3)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 51, 6, + contextMessages: [message('/home/test/lib/test.dart', 49, 9)]), ]); - // Instantiate-to-bounds should have instantiated "Bar" to "Bar". - assertType(result.unit.declaredElement!.getType('Baz')!.supertype, - 'Bar>'); } +} - test_ofFunctionTypeAlias() async { +mixin TypeArgumentNotMatchingBoundsTestCases on PubPackageResolutionTest { + test_classTypeAlias() async { await assertErrorsInCode(r''' class A {} class B {} -typedef F(); -F fff = (throw 42); +class C {} +class G {} +class D = G with C; ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1, - contextMessages: [message('/home/test/lib/test.dart', 48, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1), ]); } - test_ofFunctionTypeAlias_hasBound2_matching() async { - await assertNoErrorsInCode(r''' -class MyClass {} -typedef MyFunction>(); -class A> { - MyFunction f = (throw 0); + test_const() async { + await assertErrorsInCode(r''' +class A {} +class B {} +class G { + const G(); } -'''); +f() { return const G(); } +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 81, 1), + ]); } - test_ofFunctionTypeAlias_hasBound_matching() async { + test_const_matching() async { await assertNoErrorsInCode(r''' class A {} class B extends A {} -typedef F(); -F fa = (throw 0); -F fb = (throw 0); -'''); - } - - test_ofFunctionTypeAlias_noBound_matching() async { - await assertNoErrorsInCode(r''' -typedef F(); -F f1 = (throw 0); -F f2 = (throw 0); +class G { + const G(); +} +f() { return const G(); } '''); } - test_parameter() async { + test_extends() async { await assertErrorsInCode(r''' class A {} class B {} class G {} -f(G g) {} +class C extends G{} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1, - contextMessages: [message('/home/test/lib/test.dart', 48, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1), ]); } - test_redirectingConstructor() async { + test_extends_regressionInIssue18468Fix() async { + // https://code.google.com/p/dart/issues/detail?id=18628 await assertErrorsInCode(r''' -class A {} -class B {} -class X { - X(int x, int y) {} - factory X.name(int x, int y) = X; +class X {} +class Y extends X {} +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1), + ]); + } + + test_extensionOverride_hasTypeArguments() async { + await assertErrorsInCode(r''' +extension E on int { + void foo() {} +} + +void f() { + E(0).foo(); } ''', [ - error(CompileTimeErrorCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4), - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 70, 6), ]); } - test_typeArgumentList() async { + test_extensionOverride_hasTypeArguments_call() async { await assertErrorsInCode(r''' -class A {} -class B {} -class C {} -class D {} -C> c = (throw 0); +extension E on int { + void call() {} +} + +void f() { + E(0)(); +} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1, - contextMessages: [message('/home/test/lib/test.dart', 62, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 6), ]); } - test_typeParameter() async { + test_fieldFormalParameter() async { await assertErrorsInCode(r''' class A {} class B {} -class C {} class G {} -class D> {} +class C { + var f; + C(G this.f) {} +} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1, - contextMessages: [message('/home/test/lib/test.dart', 75, 4)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1, + contextMessages: [message('/home/test/lib/test.dart', 69, 4)]), ]); } - test_variableDeclaration() async { + test_functionReturnType() async { await assertErrorsInCode(r''' class A {} class B {} class G {} -G g = (throw 0); +G f() => throw 0; ''', [ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1, contextMessages: [message('/home/test/lib/test.dart', 46, 4)]), ]); } - test_with() async { + test_functionTypeAlias() async { await assertErrorsInCode(r''' class A {} class B {} class G {} -class C extends Object with G{} +typedef G f(); ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1, + contextMessages: [message('/home/test/lib/test.dart', 54, 4)]), ]); } -} -@reflectiveTest -class TypeArgumentNotMatchingBoundsWithNullSafetyTest - extends PubPackageResolutionTest - with TypeArgumentNotMatchingBoundsTestCases { - test_enum_inferred() async { - await assertErrorsInCode(''' -enum E { - v(''); - const E(T t); -} + test_functionTypedFormalParameter() async { + await assertErrorsInCode(r''' +class A {} +class B {} +class G {} +f(G h()) {} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 26, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1, + contextMessages: [message('/home/test/lib/test.dart', 48, 4)]), ]); } - test_enum_superBounded() async { - await assertNoErrorsInCode(''' -enum E> { - v() -} -'''); - } - - test_enum_withTypeArguments() async { - await assertErrorsInCode(''' -enum E { - v() -} + test_implements() async { + await assertErrorsInCode(r''' +class A {} +class B {} +class G {} +class C implements G{} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 28, 6), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1), ]); } - test_extends_optIn_fromOptOut_Null() async { - newFile('$testPackageLibPath/a.dart', content: r''' -class A {} -'''); - - await assertNoErrorsInCode(r''' -// @dart=2.6 -import 'a.dart'; - -class A1 extends A {} -'''); + test_is() async { + await assertErrorsInCode(r''' +class A {} +class B {} +class G {} +var b = 1 is G; +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1, + contextMessages: [message('/home/test/lib/test.dart', 59, 4)]), + ]); } - test_extends_optIn_fromOptOut_otherTypeParameter() async { - newFile('$testPackageLibPath/a.dart', content: r''' -void foo() { + test_methodInvocation_localFunction() async { + await assertErrorsInCode(r''' +class Point { + Point(T x, T y); } -'''); - - await assertNoErrorsInCode(r''' -// @dart=2.6 -import 'a.dart'; - -class A {} -class B extends A {} main() { - foo(); -} -'''); + Point f(T x, T y) { + return new Point(x, y); } - - test_functionReference() async { - await assertErrorsInCode(''' -void foo(T a) {} -void bar() { - foo; + print(f('hello', 'world')); } ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 51, 6), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6), ]); } - test_functionReference_matching() async { - await assertNoErrorsInCode(''' -void foo(T a) {} -void bar() { - foo; + test_methodInvocation_method() async { + await assertErrorsInCode(r''' +class Point { + Point(T x, T y); } -'''); - } - test_functionReference_regularBounded() async { - await assertNoErrorsInCode(''' -void foo(T a) {} -void bar() { - foo; -} -'''); +class PointFactory { + Point point(T x, T y) { + return new Point(x, y); } +} - test_genericFunctionTypeArgument_invariant() async { - await assertErrorsInCode(r''' -typedef F = T Function(T); -typedef FB = S Function(S); -class CB {} -void f(CB> a) {} +f(PointFactory factory) { + print(factory.point('hello', 'world')); +} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 119, 5, - contextMessages: [message('/home/test/lib/test.dart', 116, 9)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6), ]); } - test_genericFunctionTypeArgument_regularBounded() async { - await assertNoErrorsInCode(r''' -typedef F1 = T Function(T); -typedef F2 = S Function(S); -class CB {} -void f(CB a) {} -'''); - } - - test_metadata_matching() async { - await assertNoErrorsInCode(r''' -class A { - const A(); + test_methodInvocation_topLevelFunction() async { + await assertErrorsInCode(r''' +class Point { + Point(T x, T y); } -@A() -void f() {} -'''); - } - - test_metadata_notMatching() async { - await assertErrorsInCode(r''' -class A { - const A(); +Point f(T x, T y) { + return new Point(x, y); } -@A() -void f() {} +main() { + print(f('hello', 'world')); +} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 44, 6), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6), ]); } - test_metadata_notMatching_viaTypeAlias() async { + test_methodReturnType() async { await assertErrorsInCode(r''' -class A { - const A(); +class A {} +class B {} +class G {} +class C { + G m() => throw 0; } +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1, + contextMessages: [message('/home/test/lib/test.dart', 58, 4)]), + ]); + } -typedef B = A; - -@B() -void f() {} + test_new() async { + await assertErrorsInCode(r''' +class A {} +class B {} +class G {} +f() { return new G(); } ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 66, 6), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1), ]); } - test_methodInvocation_genericFunctionTypeArgument_match() async { + test_new_matching() async { await assertNoErrorsInCode(r''' -typedef F = void Function(); -void f()>() {} -void g() { - f(); -} +class A {} +class B extends A {} +class G {} +f() { return new G(); } '''); } - test_methodInvocation_genericFunctionTypeArgument_mismatch() async { + test_new_superTypeOfUpperBound() async { await assertErrorsInCode(r''' class A {} -class B {} -typedef F = void Function(); -void f()>() {} -void g() { - f(); -} +class B extends A {} +class C extends B {} +class G {} +f() { return new G(); } ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 131, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1), ]); } - test_nonFunctionTypeAlias_body_typeArgument_mismatch() async { + test_not_matching_bounds() async { + // There should be an error, because Bar's type argument T is Foo, which + // doesn't extends Foo. + await assertErrorsInCode(''' +class Foo {} +class Bar> {} +class Baz extends Bar {} +void main() {} +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 3, + contextMessages: [message('/home/test/lib/test.dart', 65, 3)]), + ]); + // Instantiate-to-bounds should have instantiated "Bar" to "Bar". + assertType(result.unit.declaredElement!.getType('Baz')!.supertype, + 'Bar>'); + } + + test_ofFunctionTypeAlias() async { await assertErrorsInCode(r''' class A {} class B {} -class G {} -typedef X = G; +typedef F(); +F fff = (throw 42); ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1, + contextMessages: [message('/home/test/lib/test.dart', 48, 4)]), ]); } - test_nonFunctionTypeAlias_body_typeArgument_regularBounded() async { + test_ofFunctionTypeAlias_hasBound2_matching() async { + await assertNoErrorsInCode(r''' +class MyClass {} +typedef MyFunction>(); +class A> { + MyFunction f = (throw 0); +} +'''); + } + + test_ofFunctionTypeAlias_hasBound_matching() async { await assertNoErrorsInCode(r''' class A {} class B extends A {} -class G {} -typedef X = G; +typedef F(); +F fa = (throw 0); +F fb = (throw 0); '''); } - test_nonFunctionTypeAlias_body_typeArgument_superBounded() async { + test_ofFunctionTypeAlias_noBound_matching() async { await assertNoErrorsInCode(r''' -class A> {} -typedef X = List; +typedef F(); +F f1 = (throw 0); +F f2 = (throw 0); '''); } - test_nonFunctionTypeAlias_interfaceType_body_mismatch() async { + test_parameter() async { await assertErrorsInCode(r''' class A {} class B {} -class G {} -typedef X = G; +class G {} +f(G g) {} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1, + contextMessages: [message('/home/test/lib/test.dart', 48, 4)]), ]); } - test_nonFunctionTypeAlias_interfaceType_body_regularBounded() async { - await assertNoErrorsInCode(r''' -class A {} -typedef X = A; -'''); - } - - test_nonFunctionTypeAlias_interfaceType_body_superBounded() async { + test_redirectingConstructor() async { await assertErrorsInCode(r''' -class A> {} -typedef X = A; +class A {} +class B {} +class X { + X(int x, int y) {} + factory X.name(int x, int y) = X; +} ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 42, 1, - contextMessages: [message('/home/test/lib/test.dart', 42, 1)]), + error(CompileTimeErrorCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1), ]); } - test_nonFunctionTypeAlias_interfaceType_parameter() async { + test_typeArgumentList() async { await assertErrorsInCode(r''' class A {} -typedef X = Map; -void f(X a) {} +class B {} +class C {} +class D {} +C> c = (throw 0); ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 58, 6, - contextMessages: [message('/home/test/lib/test.dart', 56, 9)]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1, + contextMessages: [message('/home/test/lib/test.dart', 62, 4)]), ]); } - test_nonFunctionTypeAlias_interfaceType_parameter_regularBounded() async { - await assertNoErrorsInCode(r''' + test_typeParameter() async { + await assertErrorsInCode(r''' class A {} -class B extends A {} -typedef X = Map; -void f(X a) {} -'''); +class B {} +class C {} +class G {} +class D> {} +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1, + contextMessages: [message('/home/test/lib/test.dart', 75, 4)]), + ]); } - test_notRegularBounded_notSuperBounded_parameter_invariant() async { + test_variableDeclaration() async { await assertErrorsInCode(r''' -typedef A = X Function(X); -typedef G> = void Function(); -foo(G g) {} +class A {} +class B {} +class G {} +G g = (throw 0); ''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 92, 1, - contextMessages: [ - message('/home/test/lib/test.dart', 92, 1), - message('/home/test/lib/test.dart', 92, 1) - ]), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1, + contextMessages: [message('/home/test/lib/test.dart', 46, 4)]), ]); } - test_regression_42196() async { - await assertNoErrorsInCode(r''' -typedef G = Function(X); -class A>, Y extends X> {} - -test() { print("OK"); } - -main() { - test>, dynamic>>(); -} -'''); + test_with() async { + await assertErrorsInCode(r''' +class A {} +class B {} +class G {} +class C extends Object with G{} +''', [ + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1), + ]); } - - test_regression_42196_object() async { - await assertNoErrorsInCode(r''' -typedef G = Function(X); -class A>, Y extends Never> {} - -test() { print("OK"); } - -main() { - test>, Object?>>(); } -'''); - } - test_regression_42196_void() async { +@reflectiveTest +class TypeArgumentNotMatchingBoundsWithoutNullSafetyTest + extends PubPackageResolutionTest + with WithoutNullSafetyMixin, TypeArgumentNotMatchingBoundsTestCases { + test_regression_42196_Null() async { await assertNoErrorsInCode(r''' typedef G = Function(X); -class A>, Y extends Never> {} +class A>, Y extends X> {} test() { print("OK"); } main() { - test>, void>>(); + test>, dynamic>>(); } '''); } - - test_superBounded() async { - await assertNoErrorsInCode(r''' -class A> {} - -A get foo => throw 0; -'''); - } - - test_typeLiteral_class() async { - await assertErrorsInCode(''' -class C {} -var t = C; -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 36, 6, - contextMessages: [message('/home/test/lib/test.dart', 34, 9)]), - ]); - } - - test_typeLiteral_functionTypeAlias() async { - await assertErrorsInCode(''' -typedef Cb = void Function(); -var t = Cb; -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 6, - contextMessages: [message('/home/test/lib/test.dart', 53, 10)]), - ]); - } - - test_typeLiteral_typeAlias() async { - await assertErrorsInCode(''' -class C {} -typedef D = C; -var t = D; -''', [ - error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 51, 6, - contextMessages: [message('/home/test/lib/test.dart', 49, 9)]), - ]); - } } diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart index ae2410cbf5f90..2f1bacbdcb37b 100644 --- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart +++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart @@ -11,13 +11,181 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(UndefinedGetterTest); - defineReflectiveTests(UndefinedGetterWithNullSafetyTest); + defineReflectiveTests(UndefinedGetterWithoutNullSafetyTest); }); } @reflectiveTest class UndefinedGetterTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, UndefinedGetterTestCases {} + with UndefinedGetterTestCases { + test_functionAlias_typeInstantiated_getter() async { + await assertErrorsInCode(''' +typedef Fn = void Function(T); + +void bar() { + Fn.foo; +} + +extension E on Type { + int get foo => 1; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE, 58, 3), + ]); + } + + test_functionAlias_typeInstantiated_getter_parenthesized() async { + await assertNoErrorsInCode(''' +typedef Fn = void Function(T); + +void bar() { + (Fn).foo; +} + +extension E on Type { + int get foo => 1; +} +'''); + } + + test_get_from_abstract_field_final_valid() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract final int x; +} +int f(A a) => a.x; +'''); + } + + test_get_from_abstract_field_valid() async { + await assertNoErrorsInCode(''' +abstract class A { + abstract int x; +} +int f(A a) => a.x; +'''); + } + + test_get_from_external_field_final_valid() async { + await assertNoErrorsInCode(''' +class A { + external final int x; +} +int f(A a) => a.x; +'''); + } + + test_get_from_external_field_valid() async { + await assertNoErrorsInCode(''' +class A { + external int x; +} +int f(A a) => a.x; +'''); + } + + test_get_from_external_static_field_final_valid() async { + await assertNoErrorsInCode(''' +class A { + external static final int x; +} +int f() => A.x; +'''); + } + + test_get_from_external_static_field_valid() async { + await assertNoErrorsInCode(''' +class A { + external static int x; +} +int f() => A.x; +'''); + } + + test_new_cascade() async { + await assertErrorsInCode(''' +class C {} + +f(C? c) { + c..new; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 27, 3), + ]); + } + + test_new_dynamic() async { + await assertErrorsInCode(''' +f(dynamic d) { + d.new; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 19, 3), + ]); + } + + test_new_expression() async { + await assertErrorsInCode(''' +class C {} + +f(C? c1, C c2) { + (c1 ?? c2).new; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 42, 3), + ]); + } + + test_new_nullAware() async { + await assertErrorsInCode(''' +class C {} + +f(C? c) { + c?.new; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 27, 3), + ]); + } + + test_new_prefixedIdentifier() async { + await assertErrorsInCode(''' +class C {} + +abstract class D { + C get c; +} + +f(D d) { + d.c.new; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 60, 3), + ]); + } + + test_new_simpleIdentifier() async { + await assertErrorsInCode(''' +class C {} + +f(C c) { + c.new; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 25, 3), + ]); + } + + test_new_typeVariable() async { + await assertErrorsInCode(''' +f(T t) { + t.new; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_GETTER, 16, 3), + ]); + } +} mixin UndefinedGetterTestCases on PubPackageResolutionTest { test_compoundAssignment_hasSetter_instance() async { @@ -386,173 +554,5 @@ class B extends A { } @reflectiveTest -class UndefinedGetterWithNullSafetyTest extends PubPackageResolutionTest - with UndefinedGetterTestCases { - test_functionAlias_typeInstantiated_getter() async { - await assertErrorsInCode(''' -typedef Fn = void Function(T); - -void bar() { - Fn.foo; -} - -extension E on Type { - int get foo => 1; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE, 58, 3), - ]); - } - - test_functionAlias_typeInstantiated_getter_parenthesized() async { - await assertNoErrorsInCode(''' -typedef Fn = void Function(T); - -void bar() { - (Fn).foo; -} - -extension E on Type { - int get foo => 1; -} -'''); - } - - test_get_from_abstract_field_final_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract final int x; -} -int f(A a) => a.x; -'''); - } - - test_get_from_abstract_field_valid() async { - await assertNoErrorsInCode(''' -abstract class A { - abstract int x; -} -int f(A a) => a.x; -'''); - } - - test_get_from_external_field_final_valid() async { - await assertNoErrorsInCode(''' -class A { - external final int x; -} -int f(A a) => a.x; -'''); - } - - test_get_from_external_field_valid() async { - await assertNoErrorsInCode(''' -class A { - external int x; -} -int f(A a) => a.x; -'''); - } - - test_get_from_external_static_field_final_valid() async { - await assertNoErrorsInCode(''' -class A { - external static final int x; -} -int f() => A.x; -'''); - } - - test_get_from_external_static_field_valid() async { - await assertNoErrorsInCode(''' -class A { - external static int x; -} -int f() => A.x; -'''); - } - - test_new_cascade() async { - await assertErrorsInCode(''' -class C {} - -f(C? c) { - c..new; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 27, 3), - ]); - } - - test_new_dynamic() async { - await assertErrorsInCode(''' -f(dynamic d) { - d.new; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 19, 3), - ]); - } - - test_new_expression() async { - await assertErrorsInCode(''' -class C {} - -f(C? c1, C c2) { - (c1 ?? c2).new; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 42, 3), - ]); - } - - test_new_nullAware() async { - await assertErrorsInCode(''' -class C {} - -f(C? c) { - c?.new; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 27, 3), - ]); - } - - test_new_prefixedIdentifier() async { - await assertErrorsInCode(''' -class C {} - -abstract class D { - C get c; -} - -f(D d) { - d.c.new; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 60, 3), - ]); - } - - test_new_simpleIdentifier() async { - await assertErrorsInCode(''' -class C {} - -f(C c) { - c.new; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 25, 3), - ]); - } - - test_new_typeVariable() async { - await assertErrorsInCode(''' -f(T t) { - t.new; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_GETTER, 16, 3), - ]); - } -} +class UndefinedGetterWithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin, UndefinedGetterTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart index a577c7ffbc0c9..df6bcf489906e 100644 --- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart +++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart @@ -10,140 +10,12 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(UndefinedSetterTest); - defineReflectiveTests(UndefinedSetterWithNullSafetyTest); + defineReflectiveTests(UndefinedSetterWithoutNullSafetyTest); }); } @reflectiveTest class UndefinedSetterTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin, UndefinedSetterTestCases {} - -mixin UndefinedSetterTestCases on PubPackageResolutionTest { - test_importWithPrefix_defined() async { - newFile('$testPackageLibPath/lib.dart', content: r''' -library lib; -set y(int value) {}'''); - await assertNoErrorsInCode(r''' -import 'lib.dart' as x; -main() { - x.y = 0; -} -'''); - } - - test_instance_undefined() async { - await assertErrorsInCode(r''' -class T {} -f(T e1) { e1.m = 0; } -''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 24, 1, - messageContains: ["the type 'T'"]), - ]); - } - - test_instance_undefined_mixin() async { - await assertErrorsInCode(r''' -mixin M { - f() { this.m = 0; } -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 23, 1), - ]); - } - - test_inSubtype() async { - await assertErrorsInCode(r''' -class A {} -class B extends A { - set b(x) {} -} -f(var a) { - if (a is A) { - a.b = 0; - } -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 80, 1), - ]); - } - - test_inType() async { - await assertErrorsInCode(r''' -class A {} -f(var a) { - if(a is A) { - a.m = 0; - } -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 43, 1), - ]); - } - - test_static_conditionalAccess_defined() async { - // The conditional access operator '?.' can be used to access static - // fields. - await assertNoErrorsInCode(''' -class A { - static var x; -} -f() { A?.x = 1; } -'''); - } - - test_static_definedInSuperclass() async { - await assertErrorsInCode(''' -class S { - static set s(int i) {} -} -class C extends S {} -f(var p) { - f(C.s = 1); -}''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 75, 1, - messageContains: ["type 'C'"]), - ]); - } - - test_static_undefined() async { - await assertErrorsInCode(r''' -class A {} -f() { A.B = 0;} -''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 19, 1), - ]); - } - - test_typeLiteral_cascadeTarget() async { - await assertErrorsInCode(r''' -class T { - static void set foo(_) {} -} -main() { - T..foo = 42; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 54, 3), - ]); - } - - test_withExtension() async { - await assertErrorsInCode(r''' -class C {} - -extension E on C {} - -f(C c) { - c.a = 1; -} -''', [ - error(CompileTimeErrorCode.UNDEFINED_SETTER, 46, 1), - ]); - } -} - -@reflectiveTest -class UndefinedSetterWithNullSafetyTest extends PubPackageResolutionTest with UndefinedSetterTestCases { test_functionAlias_typeInstantiated() async { await assertErrorsInCode(''' @@ -276,3 +148,131 @@ void f(int x) { '''); } } + +mixin UndefinedSetterTestCases on PubPackageResolutionTest { + test_importWithPrefix_defined() async { + newFile('$testPackageLibPath/lib.dart', content: r''' +library lib; +set y(int value) {}'''); + await assertNoErrorsInCode(r''' +import 'lib.dart' as x; +main() { + x.y = 0; +} +'''); + } + + test_instance_undefined() async { + await assertErrorsInCode(r''' +class T {} +f(T e1) { e1.m = 0; } +''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 24, 1, + messageContains: ["the type 'T'"]), + ]); + } + + test_instance_undefined_mixin() async { + await assertErrorsInCode(r''' +mixin M { + f() { this.m = 0; } +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 23, 1), + ]); + } + + test_inSubtype() async { + await assertErrorsInCode(r''' +class A {} +class B extends A { + set b(x) {} +} +f(var a) { + if (a is A) { + a.b = 0; + } +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 80, 1), + ]); + } + + test_inType() async { + await assertErrorsInCode(r''' +class A {} +f(var a) { + if(a is A) { + a.m = 0; + } +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 43, 1), + ]); + } + + test_static_conditionalAccess_defined() async { + // The conditional access operator '?.' can be used to access static + // fields. + await assertNoErrorsInCode(''' +class A { + static var x; +} +f() { A?.x = 1; } +'''); + } + + test_static_definedInSuperclass() async { + await assertErrorsInCode(''' +class S { + static set s(int i) {} +} +class C extends S {} +f(var p) { + f(C.s = 1); +}''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 75, 1, + messageContains: ["type 'C'"]), + ]); + } + + test_static_undefined() async { + await assertErrorsInCode(r''' +class A {} +f() { A.B = 0;} +''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 19, 1), + ]); + } + + test_typeLiteral_cascadeTarget() async { + await assertErrorsInCode(r''' +class T { + static void set foo(_) {} +} +main() { + T..foo = 42; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 54, 3), + ]); + } + + test_withExtension() async { + await assertErrorsInCode(r''' +class C {} + +extension E on C {} + +f(C c) { + c.a = 1; +} +''', [ + error(CompileTimeErrorCode.UNDEFINED_SETTER, 46, 1), + ]); + } +} + +@reflectiveTest +class UndefinedSetterWithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin, UndefinedSetterTestCases {} diff --git a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart index fb070cc2ecd20..b1d7f0a1b428f 100644 --- a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart +++ b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart @@ -11,119 +11,51 @@ import '../dart/resolution/context_collection_resolution.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(UnusedElementTest); - defineReflectiveTests(UnusedElementWithNullSafetyTest); + defineReflectiveTests(UnusedElementWithoutNullSafetyTest); }); } @reflectiveTest -class UnusedElementTest extends PubPackageResolutionTest - with WithoutNullSafetyMixin { - test_class_isUsed_extends() async { - await assertNoErrorsInCode(r''' -class _A {} -class B extends _A {} -'''); - } - - test_class_isUsed_fieldDeclaration() async { - await assertNoErrorsInCode(r''' -class Foo { - _Bar x; -} - -class _Bar { -} -'''); - } - - test_class_isUsed_implements() async { - await assertNoErrorsInCode(r''' -class _A {} -class B implements _A {} -'''); - } - - test_class_isUsed_instanceCreation() async { - await assertNoErrorsInCode(r''' +class UnusedElementTest extends PubPackageResolutionTest { + test_class_isUsed_isExpression_expression() async { + await assertNoErrorsInCode(''' class _A {} -main() { - new _A(); -} -'''); - } - - test_class_isUsed_staticFieldAccess() async { - await assertNoErrorsInCode(r''' -class _A { - static const F = 42; -} -main() { - _A.F; -} -'''); - } - - test_class_isUsed_staticMethodInvocation() async { - await assertNoErrorsInCode(r''' -class _A { - static m() {} -} -main() { - _A.m(); -} -'''); +void f(Object p) { + if (_A() is int) { } - - test_class_isUsed_typeArgument() async { - await assertNoErrorsInCode(r''' -class _A {} -main() { - var v = new List<_A>(); - print(v); } '''); } - test_class_isUsed_with() async { - await assertNoErrorsInCode(r''' -class _A {} -class B with _A {} -'''); - } - - test_class_notUsed_inClassMember() async { + test_class_notUsed_isExpression_typeArgument() async { await assertErrorsInCode(r''' -class _A { - static staticMethod() { - new _A(); - } - instanceMethod() { - new _A(); +class _A {} +void f(Object p) { + if (p is List<_A>) { } } ''', [ error(HintCode.UNUSED_ELEMENT, 6, 2), - error(HintCode.UNUSED_ELEMENT, 20, 12), ]); } - test_class_notUsed_inConstructorName() async { + test_class_notUsed_isExpression_typeInFunctionType() async { await assertErrorsInCode(r''' -class _A { - _A() {} - _A.named() {} +class _A {} +void f(Object p) { + if (p is void Function(_A)) { + } } ''', [ error(HintCode.UNUSED_ELEMENT, 6, 2), - error(HintCode.UNUSED_ELEMENT, 26, 5), ]); } - test_class_notUsed_isExpression() async { + test_class_notUsed_isExpression_typeInTypeParameter() async { await assertErrorsInCode(r''' class _A {} -main(p) { - if (p is _A) { +void f(Object p) { + if (p is void Function()) { } } ''', [ @@ -131,21 +63,24 @@ main(p) { ]); } - test_class_notUsed_noReference() async { - await assertErrorsInCode(r''' + test_class_notUsed_variableDeclaration() async { + await assertErrorsInCode(''' class _A {} -main() { +void f() { + _A? v; + print(v); } +print(x) {} ''', [ error(HintCode.UNUSED_ELEMENT, 6, 2), ]); } - test_class_notUsed_variableDeclaration() async { - await assertErrorsInCode(r''' + test_class_notUsed_variableDeclaration_typeArgument() async { + await assertErrorsInCode(''' class _A {} main() { - _A v; + List<_A>? v; print(v); } print(x) {} @@ -154,1833 +89,1898 @@ print(x) {} ]); } - test_classGetterSetter_isUsed_assignmentExpression_compound() async { - await assertNoErrorsInCode(r''' -class A { - int get _foo => 0; - set _foo(int _) {} - - void f() { - _foo += 2; - } + test_optionalParameter_isUsed_genericConstructor() async { + await assertNoErrorsInCode(''' +class C { + C._([int? x]); +} +void foo() { + C._(7); } '''); } - test_classSetter_isUsed_assignmentExpression_simple() async { - await assertNoErrorsInCode(r''' -class A { - set _foo(int _) {} - - void f() { - _foo = 0; - } + test_optionalParameter_isUsed_genericFunction() async { + await assertNoErrorsInCode(''' +void _f([int? x]) {} +void foo() { + _f(7); } '''); } - test_constructor_isUsed_asRedirectee() async { - await assertNoErrorsInCode(r''' -class A { - A._constructor(); - factory A.b() = A._constructor; + test_optionalParameter_isUsed_genericMethod() async { + await assertNoErrorsInCode(''' +class C { + void _m([int? x]) {} +} +void foo() { + C()._m(7); } '''); } - test_constructor_isUsed_asRedirectee_viaInitializer() async { + test_optionalParameter_isUsed_overrideRequiredNamed() async { await assertNoErrorsInCode(r''' class A { - A._constructor(); - A() : this._constructor(); + void _m({required int a}) {} +} +class B implements A { + void _m({int a = 0}) {} } +f() => A()._m(a: 0); '''); } - test_constructor_isUsed_asRedirectee_viaSuper() async { - await assertNoErrorsInCode(r''' -class A { - A._constructor(); + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47839') + test_optionalParameter_notUsed_genericConstructor() async { + // TODO(srawlins): Change to assertErrorsInCode when this is fixed. + addTestFile(''' +class C { + C._([int? x]); } - -class B extends A { - B() : super._constructor(); +void foo() { + C._(); } '''); + await resolveTestFile(); + expect(result.errors, isNotEmpty); } - test_constructor_isUsed_explicit() async { - await assertNoErrorsInCode(r''' -class A { - A._constructor(); + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47839') + test_optionalParameter_notUsed_genericFunction() async { + // TODO(srawlins): Change to assertErrorsInCode when this is fixed. + addTestFile(''' +void _f([int? x]) {} +void foo() { + _f(); } -A f() => A._constructor(); '''); + await resolveTestFile(); + expect(result.errors, isNotEmpty); } - test_constructor_notUsed_multiple() async { - await assertErrorsInCode(r''' -class A { - A._constructor(); - A(); + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47839') + test_optionalParameter_notUsed_genericMethod() async { + // TODO(srawlins): Change to assertErrorsInCode when this is fixed. + addTestFile(''' +class C { + void _m([int? x]) {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 14, 12), - ]); +void foo() { + C()._m(); +} +'''); + await resolveTestFile(); + expect(result.errors, isNotEmpty); } - test_constructor_notUsed_single() async { + test_parameter_optionalNamed_fieldFormal_isUsed_constructorInvocation() async { await assertNoErrorsInCode(r''' -class A { - A._constructor(); +class _A { + final int? f; + _A({this.f}); } +f() => _A(f: 0); '''); } - test_enum_isUsed_fieldReference() async { + test_parameter_optionalNamed_fieldFormal_isUsed_factoryRedirect() async { await assertNoErrorsInCode(r''' -enum _MyEnum {A} -main() { - _MyEnum.A; +class _A { + final int? f; + _A({this.f}); + factory _A.named({int? f}) = _A; } +f() => _A.named(f: 0); '''); } - test_enum_notUsed_noReference() async { + test_parameter_optionalNamed_fieldFormal_notUsed() async { await assertErrorsInCode(r''' -enum _MyEnum {A, B} -void f(d) { - d.A; - d.B; +class _A { + final int? f; + _A({this.f}); } +f() => _A(); ''', [ - error(HintCode.UNUSED_ELEMENT, 5, 7), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), ]); } - test_factoryConstructor_notUsed_multiple() async { + test_parameter_optionalNamed_fieldFormal_notUsed_factoryRedirect() async { await assertErrorsInCode(r''' -class A { - factory A._factory() => A(); - A(); +class _A { + final int? f; + _A({this.f}); + factory _A.named() = _A; } +f() => _A.named(); ''', [ - error(HintCode.UNUSED_ELEMENT, 22, 8), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), ]); } - test_factoryConstructor_notUsed_single() async { + test_parameter_optionalPositional_fieldFormal_isUsed_constructorInvocation() async { await assertNoErrorsInCode(r''' -class A { - factory A._factory() => throw 0; +class _A { + final int? f; + _A([this.f]); } +f() => _A(0); '''); } - test_fieldImplicitGetter_isUsed() async { + test_parameter_optionalPositional_fieldFormal_isUsed_factoryRedirect() async { await assertNoErrorsInCode(r''' -class A { - int _g; - int get g => this._g; +class _A { + final int? f; + _A([this.f]); + factory _A.named([int a]) = _A; } +f() => _A.named(0); '''); } - test_functionLocal_isUsed_closure() async { - await assertNoErrorsInCode(r''' -main() { - print(() {}); + test_parameter_optionalPositional_fieldFormal_notUsed() async { + await assertErrorsInCode(r''' +class _A { + final int? f; + _A([this.f]); } -print(x) {} -'''); +f() => _A(); +''', [ + error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), + ]); } - test_functionLocal_isUsed_invocation() async { + test_parameter_optionalPositional_fieldFormal_notUsed_factoryRedirect() async { + await assertErrorsInCode(r''' +class _A { + final int? f; + _A([this.f]); + factory _A.named() = _A; +} +f() => _A.named(); +''', [ + error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), + ]); + } + + test_typeAlias_interfaceType_isUsed_typeName_isExpression() async { await assertNoErrorsInCode(r''' -main() { - f() {} - f(); +typedef _A = List; + +void f(a) { + a is _A; } '''); } - test_functionLocal_isUsed_reference() async { + test_typeAlias_interfaceType_isUsed_typeName_parameter() async { await assertNoErrorsInCode(r''' -main() { - f() {} - print(f); -} -print(x) {} +typedef _A = List; + +void f(_A a) {} '''); } - test_functionLocal_notUsed_noReference() async { - await assertErrorsInCode(r''' -main() { - f() {} + test_typeAlias_interfaceType_isUsed_typeName_typeArgument() async { + await assertNoErrorsInCode(r''' +typedef _A = List; + +void f() { + Map<_A, int>(); } -''', [ - error(HintCode.UNUSED_ELEMENT, 11, 1), - ]); +'''); } - test_functionLocal_notUsed_referenceFromItself() async { + test_typeAlias_interfaceType_notUsed() async { await assertErrorsInCode(r''' -main() { - _f(int p) { - _f(p - 1); - } -} +typedef _A = List; ''', [ - error(HintCode.UNUSED_ELEMENT, 11, 2), + error(HintCode.UNUSED_ELEMENT, 8, 2), ]); } +} - test_functionTypeAlias_isUsed_isExpression() async { +@reflectiveTest +class UnusedElementWithoutNullSafetyTest extends PubPackageResolutionTest + with WithoutNullSafetyMixin { + test_class_isUsed_extends() async { await assertNoErrorsInCode(r''' -typedef _F(a, b); -main(f) { - if (f is _F) { - print('F'); +class _A {} +class B extends _A {} +'''); } + + test_class_isUsed_fieldDeclaration() async { + await assertNoErrorsInCode(r''' +class Foo { + _Bar x; +} + +class _Bar { } '''); } - test_functionTypeAlias_isUsed_reference() async { + test_class_isUsed_implements() async { await assertNoErrorsInCode(r''' -typedef _F(a, b); -main(_F f) { -} +class _A {} +class B implements _A {} '''); } - test_functionTypeAlias_isUsed_typeArgument() async { + test_class_isUsed_instanceCreation() async { await assertNoErrorsInCode(r''' -typedef _F(a, b); +class _A {} main() { - var v = new List<_F>(); - print(v); + new _A(); } '''); } - test_functionTypeAlias_isUsed_variableDeclaration() async { + test_class_isUsed_staticFieldAccess() async { await assertNoErrorsInCode(r''' -typedef _F(a, b); -class A { - _F f; +class _A { + static const F = 42; +} +main() { + _A.F; } '''); } - test_functionTypeAlias_notUsed_noReference() async { - await assertErrorsInCode(r''' -typedef _F(a, b); + test_class_isUsed_staticMethodInvocation() async { + await assertNoErrorsInCode(r''' +class _A { + static m() {} +} main() { + _A.m(); } -''', [ - error(HintCode.UNUSED_ELEMENT, 8, 2), - ]); +'''); } - test_getter_isUsed_invocation_deepSubclass() async { + test_class_isUsed_typeArgument() async { await assertNoErrorsInCode(r''' -abstract class A { - String get _debugName; - - String toString() { - return _debugName; - } -} - -class B extends A { - @override - String get _debugName => "B"; +class _A {} +main() { + var v = new List<_A>(); + print(v); } +'''); + } -class C extends B { - String get _debugName => "C"; -} + test_class_isUsed_with() async { + await assertNoErrorsInCode(r''' +class _A {} +class B with _A {} '''); } - test_getter_isUsed_invocation_implicitThis() async { + test_class_notUsed_inClassMember() async { await assertErrorsInCode(r''' -class A { - get _g => null; - useGetter() { - var v = _g; +class _A { + static staticMethod() { + new _A(); + } + instanceMethod() { + new _A(); } } ''', [ - error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 1), + error(HintCode.UNUSED_ELEMENT, 6, 2), + error(HintCode.UNUSED_ELEMENT, 20, 12), ]); } - test_getter_isUsed_invocation_parameterized() async { - await assertNoErrorsInCode(r''' -class A { - List _list = List(1); - int get _item => _list.first; - set _item(int item) => _list[0] = item; -} -class B { - A a; -} -void main() { - B b = B(); - b.a._item = 3; - print(b.a._item == 7); + test_class_notUsed_inConstructorName() async { + await assertErrorsInCode(r''' +class _A { + _A() {} + _A.named() {} } -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 6, 2), + error(HintCode.UNUSED_ELEMENT, 26, 5), + ]); } - test_getter_isUsed_invocation_parameterized_subclass() async { - await assertNoErrorsInCode(r''' -abstract class A { - T get _defaultThing; - T _thing; - - void main() { - _thing ??= _defaultThing; - print(_thing); + test_class_notUsed_isExpression() async { + await assertErrorsInCode(r''' +class _A {} +main(p) { + if (p is _A) { } } -class B extends A { - @override - int get _defaultThing => 7; -} -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 6, 2), + ]); } - test_getter_isUsed_invocation_prefixedIdentifier() async { + test_class_notUsed_noReference() async { await assertErrorsInCode(r''' -class A { - get _g => null; -} -main(A a) { - var v = a._g; +class _A {} +main() { } ''', [ - error(HintCode.UNUSED_LOCAL_VARIABLE, 48, 1), + error(HintCode.UNUSED_ELEMENT, 6, 2), ]); } - test_getter_isUsed_invocation_propertyAccess() async { + test_class_notUsed_variableDeclaration() async { await assertErrorsInCode(r''' -class A { - get _g => null; -} +class _A {} main() { - var v = new A()._g; + _A v; + print(v); } +print(x) {} ''', [ - error(HintCode.UNUSED_LOCAL_VARIABLE, 45, 1), + error(HintCode.UNUSED_ELEMENT, 6, 2), ]); } - test_getter_isUsed_invocation_subclass_plusPlus() async { + test_classGetterSetter_isUsed_assignmentExpression_compound() async { await assertNoErrorsInCode(r''' class A { - int __a = 0; - int get _a => __a; - void set _a(int val) { - __a = val; + int get _foo => 0; + set _foo(int _) {} + + void f() { + _foo += 2; } - int b() => _a++; -} -class B extends A { - @override - int get _a => 3; } '''); } - test_getter_notUsed_invocation_subclass() async { - await assertErrorsInCode(r''' + test_classSetter_isUsed_assignmentExpression_simple() async { + await assertNoErrorsInCode(r''' class A { - int __a = 0; - int get _a => __a; - void set _a(int val) { - __a = val; + set _foo(int _) {} + + void f() { + _foo = 0; } - int b() => _a = 7; -} -class B extends A { - @override - int get _a => 3; } -''', [ - error(HintCode.UNUSED_ELEMENT, 35, 2), - error(HintCode.UNUSED_ELEMENT, 155, 2), - ]); +'''); } - test_getter_notUsed_noReference() async { - await assertErrorsInCode(r''' + test_constructor_isUsed_asRedirectee() async { + await assertNoErrorsInCode(r''' class A { - get _g => null; + A._constructor(); + factory A.b() = A._constructor; } -''', [ - error(HintCode.UNUSED_ELEMENT, 16, 2), - ]); +'''); } - test_getter_notUsed_referenceFromItself() async { - await assertErrorsInCode(r''' + test_constructor_isUsed_asRedirectee_viaInitializer() async { + await assertNoErrorsInCode(r''' class A { - get _g { - return _g; - } + A._constructor(); + A() : this._constructor(); } -''', [ - error(HintCode.UNUSED_ELEMENT, 16, 2), - ]); +'''); } - test_method_isUsed_hasPragma_vmEntryPoint() async { - pragma; + test_constructor_isUsed_asRedirectee_viaSuper() async { await assertNoErrorsInCode(r''' class A { - @pragma('vm:entry-point') - void _foo() {} + A._constructor(); +} + +class B extends A { + B() : super._constructor(); } '''); } - test_method_isUsed_hasReference_implicitThis() async { + test_constructor_isUsed_explicit() async { await assertNoErrorsInCode(r''' class A { - _m() {} - useMethod() { - print(_m); - } + A._constructor(); } -print(x) {} +A f() => A._constructor(); '''); } - test_method_isUsed_hasReference_implicitThis_subclass() async { - await assertNoErrorsInCode(r''' + test_constructor_notUsed_multiple() async { + await assertErrorsInCode(r''' class A { - _m() {} - useMethod() { - print(_m); - } -} -class B extends A { - _m() {} + A._constructor(); + A(); } -print(x) {} -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 14, 12), + ]); } - test_method_isUsed_hasReference_prefixedIdentifier() async { + test_constructor_notUsed_single() async { await assertNoErrorsInCode(r''' class A { - _m() {} -} -main(A a) { - a._m; + A._constructor(); } '''); } - test_method_isUsed_hasReference_propertyAccess() async { + test_enum_isUsed_fieldReference() async { await assertNoErrorsInCode(r''' -class A { - _m() {} -} +enum _MyEnum {A} main() { - new A()._m; + _MyEnum.A; } '''); } - test_method_isUsed_invocation_fromMixinApplication() async { - await assertNoErrorsInCode(r''' -mixin A { - _m() {} + test_enum_notUsed_noReference() async { + await assertErrorsInCode(r''' +enum _MyEnum {A, B} +void f(d) { + d.A; + d.B; } -class C with A { - useMethod() { - _m(); +''', [ + error(HintCode.UNUSED_ELEMENT, 5, 7), + ]); } + + test_factoryConstructor_notUsed_multiple() async { + await assertErrorsInCode(r''' +class A { + factory A._factory() => A(); + A(); } -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 22, 8), + ]); } - test_method_isUsed_invocation_fromMixinWithConstraint() async { + test_factoryConstructor_notUsed_single() async { await assertNoErrorsInCode(r''' class A { - _m() {} -} -mixin M on A { - useMethod() { - _m(); - } + factory A._factory() => throw 0; } '''); } - test_method_isUsed_invocation_implicitThis() async { + test_fieldImplicitGetter_isUsed() async { await assertNoErrorsInCode(r''' class A { - _m() {} - useMethod() { - _m(); - } + int _g; + int get g => this._g; } '''); } - test_method_isUsed_invocation_implicitThis_subclass() async { + test_functionLocal_isUsed_closure() async { await assertNoErrorsInCode(r''' -class A { - _m() {} - useMethod() { - _m(); - } -} -class B extends A { - _m() {} +main() { + print(() {}); } +print(x) {} '''); } - test_method_isUsed_invocation_memberElement() async { + test_functionLocal_isUsed_invocation() async { await assertNoErrorsInCode(r''' -class A { - _m(T t) {} -} -main(A a) { - a._m(0); +main() { + f() {} + f(); } '''); } - test_method_isUsed_invocation_propagated() async { + test_functionLocal_isUsed_reference() async { await assertNoErrorsInCode(r''' -class A { - _m() {} -} main() { - var a = new A(); - a._m(); + f() {} + print(f); } +print(x) {} '''); } - test_method_isUsed_invocation_static() async { - await assertNoErrorsInCode(r''' -class A { - _m() {} + test_functionLocal_notUsed_noReference() async { + await assertErrorsInCode(r''' +main() { + f() {} } +''', [ + error(HintCode.UNUSED_ELEMENT, 11, 1), + ]); + } + + test_functionLocal_notUsed_referenceFromItself() async { + await assertErrorsInCode(r''' main() { - A a = new A(); - a._m(); + _f(int p) { + _f(p - 1); + } } -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 11, 2), + ]); } - test_method_isUsed_invocation_subclass() async { + test_functionTypeAlias_isUsed_isExpression() async { await assertNoErrorsInCode(r''' -class A { - _m() {} -} -class B extends A { - _m() {} -} -main(A a) { - a._m(); +typedef _F(a, b); +main(f) { + if (f is _F) { + print('F'); + } } '''); } - test_method_isUsed_privateExtension() async { + test_functionTypeAlias_isUsed_reference() async { await assertNoErrorsInCode(r''' -extension _A on String { - void m() {} -} -void main() { - "hello".m(); +typedef _F(a, b); +main(_F f) { } '''); } - test_method_isUsed_privateExtension_binaryOperator() async { + test_functionTypeAlias_isUsed_typeArgument() async { await assertNoErrorsInCode(r''' -extension _A on String { - int operator -(int other) => other; -} -void main() { - "hello" - 3; +typedef _F(a, b); +main() { + var v = new List<_F>(); + print(v); } '''); } - test_method_isUsed_privateExtension_generic_binaryOperator() async { + test_functionTypeAlias_isUsed_variableDeclaration() async { await assertNoErrorsInCode(r''' -class A {} -extension _A on A { - int operator -(int other) => other; -} -void f(A a) { - a - 3; +typedef _F(a, b); +class A { + _F f; } '''); } - test_method_isUsed_privateExtension_generic_indexEqOperator() async { - await assertNoErrorsInCode(r''' -class A {} -extension _A on A { - void operator []=(int index, T value) { -}} -void f(A a) { - a[0] = 1; + test_functionTypeAlias_notUsed_noReference() async { + await assertErrorsInCode(r''' +typedef _F(a, b); +main() { } -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 8, 2), + ]); } - test_method_isUsed_privateExtension_generic_indexOperator() async { + test_getter_isUsed_invocation_deepSubclass() async { await assertNoErrorsInCode(r''' -class A {} -extension _A on A { - A operator [](int index) => throw 0; +abstract class A { + String get _debugName; + + String toString() { + return _debugName; + } } -void f(A a) { - a[0]; + +class B extends A { + @override + String get _debugName => "B"; +} + +class C extends B { + String get _debugName => "C"; } '''); } - test_method_isUsed_privateExtension_generic_method() async { + test_getter_isUsed_invocation_implicitThis() async { + await assertErrorsInCode(r''' +class A { + get _g => null; + useGetter() { + var v = _g; + } +} +''', [ + error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 1), + ]); + } + + test_getter_isUsed_invocation_parameterized() async { await assertNoErrorsInCode(r''' -class A {} -extension _A on A { - A foo() => throw 0; +class A { + List _list = List(1); + int get _item => _list.first; + set _item(int item) => _list[0] = item; } -void f(A a) { - a.foo(); +class B { + A a; +} +void main() { + B b = B(); + b.a._item = 3; + print(b.a._item == 7); } '''); } - test_method_isUsed_privateExtension_generic_postfixOperator() async { + test_getter_isUsed_invocation_parameterized_subclass() async { await assertNoErrorsInCode(r''' -class A {} -extension _A on A { - A operator -(int i) => throw 0; +abstract class A { + T get _defaultThing; + T _thing; + + void main() { + _thing ??= _defaultThing; + print(_thing); + } } -void f(A a) { - a--; +class B extends A { + @override + int get _defaultThing => 7; } '''); } - test_method_isUsed_privateExtension_generic_prefixOperator() async { - await assertNoErrorsInCode(r''' -class A {} -extension _A on A { - T operator ~() => throw 0; + test_getter_isUsed_invocation_prefixedIdentifier() async { + await assertErrorsInCode(r''' +class A { + get _g => null; } -void f(A a) { - ~a; +main(A a) { + var v = a._g; } -'''); +''', [ + error(HintCode.UNUSED_LOCAL_VARIABLE, 48, 1), + ]); } - test_method_isUsed_privateExtension_indexEqOperator() async { - await assertNoErrorsInCode(r''' -extension _A on bool { - operator []=(int index, int value) {} + test_getter_isUsed_invocation_propertyAccess() async { + await assertErrorsInCode(r''' +class A { + get _g => null; } -void main() { - false[0] = 1; +main() { + var v = new A()._g; } -'''); +''', [ + error(HintCode.UNUSED_LOCAL_VARIABLE, 45, 1), + ]); } - test_method_isUsed_privateExtension_indexOperator() async { + test_getter_isUsed_invocation_subclass_plusPlus() async { await assertNoErrorsInCode(r''' -extension _A on bool { - int operator [](int index) => 7; +class A { + int __a = 0; + int get _a => __a; + void set _a(int val) { + __a = val; + } + int b() => _a++; } -void main() { - false[3]; +class B extends A { + @override + int get _a => 3; } '''); } - test_method_isUsed_privateExtension_methodCall() async { - await assertNoErrorsInCode(r''' -extension _E on int { - void call() {} + test_getter_notUsed_invocation_subclass() async { + await assertErrorsInCode(r''' +class A { + int __a = 0; + int get _a => __a; + void set _a(int val) { + __a = val; + } + int b() => _a = 7; } - -void f() { - 0(); +class B extends A { + @override + int get _a => 3; } -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 35, 2), + error(HintCode.UNUSED_ELEMENT, 155, 2), + ]); } - test_method_isUsed_privateExtension_operator_assignment() async { - await assertNoErrorsInCode(r''' -extension _A on String { - String operator -(int other) => this; + test_getter_notUsed_noReference() async { + await assertErrorsInCode(r''' +class A { + get _g => null; } -void f(String s) { - s -= 3; +''', [ + error(HintCode.UNUSED_ELEMENT, 16, 2), + ]); + } + + test_getter_notUsed_referenceFromItself() async { + await assertErrorsInCode(r''' +class A { + get _g { + return _g; + } } -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 16, 2), + ]); } - test_method_isUsed_privateExtension_postfixOperator() async { + test_method_isUsed_hasPragma_vmEntryPoint() async { + pragma; await assertNoErrorsInCode(r''' -extension _A on String { - String operator -(int i) => this; -} -void f(String a) { - a--; +class A { + @pragma('vm:entry-point') + void _foo() {} } '''); } - test_method_isUsed_privateExtension_prefixOperator() async { + test_method_isUsed_hasReference_implicitThis() async { await assertNoErrorsInCode(r''' -extension _A on String { - int operator ~() => 7; -} -void main() { - ~"hello"; +class A { + _m() {} + useMethod() { + print(_m); + } } +print(x) {} '''); } - test_method_isUsed_public() async { + test_method_isUsed_hasReference_implicitThis_subclass() async { await assertNoErrorsInCode(r''' class A { - m() {} + _m() {} + useMethod() { + print(_m); + } } -main() { +class B extends A { + _m() {} } +print(x) {} '''); } - test_method_isUsed_staticInvocation() async { + test_method_isUsed_hasReference_prefixedIdentifier() async { await assertNoErrorsInCode(r''' class A { - static _m() {} + _m() {} } -main() { - A._m(); +main(A a) { + a._m; } '''); } - test_method_isUsed_unnamedExtension() async { + test_method_isUsed_hasReference_propertyAccess() async { await assertNoErrorsInCode(r''' -extension on String { - void m() {} +class A { + _m() {} } -void main() { - "hello".m(); +main() { + new A()._m; } '''); } - test_method_isUsed_unnamedExtension_methodCall() async { + test_method_isUsed_invocation_fromMixinApplication() async { await assertNoErrorsInCode(r''' -extension on int { - void call() {} +mixin A { + _m() {} } - -void f() { - 0(); +class C with A { + useMethod() { + _m(); + } } '''); } - test_method_isUsed_unnamedExtension_operator() async { + test_method_isUsed_invocation_fromMixinWithConstraint() async { await assertNoErrorsInCode(r''' -extension on String { - int operator -(int other) => other; +class A { + _m() {} } -void main() { - "hello" - 3; +mixin M on A { + useMethod() { + _m(); + } } '''); } - test_method_notUsed_hasSameNameAsUsed() async { - await assertErrorsInCode(r''' + test_method_isUsed_invocation_implicitThis() async { + await assertNoErrorsInCode(r''' class A { - void _m1() {} -} -class B { - void public() => _m1(); - void _m1() {} + _m() {} + useMethod() { + _m(); + } } -''', [ - error(HintCode.UNUSED_ELEMENT, 17, 3), - ]); +'''); } - test_method_notUsed_noReference() async { - await assertErrorsInCode(r''' + test_method_isUsed_invocation_implicitThis_subclass() async { + await assertNoErrorsInCode(r''' class A { - static _m() {} -} -''', [ - error(HintCode.UNUSED_ELEMENT, 19, 2), - ]); + _m() {} + useMethod() { + _m(); } - - test_method_notUsed_privateExtension() async { - await assertErrorsInCode(r''' -extension _A on String { - void m() {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 32, 1), - ]); - } - - /// Postfix operators can only be called, not defined. The "notUsed" sibling to - /// this test is the test on a binary operator. - test_method_notUsed_privateExtension_indexEqOperator() async { - await assertErrorsInCode(r''' -extension _A on bool { - operator []=(int index, int value) {} +class B extends A { + _m() {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 34, 3), - ]); +'''); } - test_method_notUsed_privateExtension_indexOperator() async { - await assertErrorsInCode(r''' -extension _A on bool { - int operator [](int index) => 7; + test_method_isUsed_invocation_memberElement() async { + await assertNoErrorsInCode(r''' +class A { + _m(T t) {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 38, 2), - ]); - } - - test_method_notUsed_privateExtension_methodCall() async { - await assertErrorsInCode(r''' -extension _E on int { - void call() {} +main(A a) { + a._m(0); } -''', [ - error(HintCode.UNUSED_ELEMENT, 29, 4), - ]); +'''); } - /// Assignment operators can only be called, not defined. The "notUsed" sibling - /// to this test is the test on a binary operator. - test_method_notUsed_privateExtension_operator() async { - await assertErrorsInCode(r''' -extension _A on String { - int operator -(int other) => other; + test_method_isUsed_invocation_propagated() async { + await assertNoErrorsInCode(r''' +class A { + _m() {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 40, 1), - ]); - } - - test_method_notUsed_privateExtension_prefixOperator() async { - await assertErrorsInCode(r''' -extension _A on String { - int operator ~() => 7; +main() { + var a = new A(); + a._m(); } -''', [ - error(HintCode.UNUSED_ELEMENT, 40, 1), - ]); +'''); } - test_method_notUsed_referenceFromItself() async { - await assertErrorsInCode(r''' + test_method_isUsed_invocation_static() async { + await assertNoErrorsInCode(r''' class A { - static _m(int p) { - _m(p - 1); - } + _m() {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 19, 2), - ]); +main() { + A a = new A(); + a._m(); +} +'''); } - test_method_notUsed_referenceInComment() async { - await assertErrorsInCode(r''' -/// [A] has a method, [_f]. + test_method_isUsed_invocation_subclass() async { + await assertNoErrorsInCode(r''' class A { - int _f(int p) => 7; + _m() {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 44, 2), - ]); +class B extends A { + _m() {} +} +main(A a) { + a._m(); +} +'''); } - test_method_notUsed_referenceInComment_outsideEnclosingClass() async { - await assertErrorsInCode(r''' -class A { - int _f(int p) => 7; + test_method_isUsed_privateExtension() async { + await assertNoErrorsInCode(r''' +extension _A on String { + void m() {} } -/// This is similar to [A._f]. -int g() => 7; -''', [ - error(HintCode.UNUSED_ELEMENT, 16, 2), - ]); +void main() { + "hello".m(); +} +'''); } - test_method_notUsed_unnamedExtension() async { - await assertErrorsInCode(r''' -extension on String { - void m() {} + test_method_isUsed_privateExtension_binaryOperator() async { + await assertNoErrorsInCode(r''' +extension _A on String { + int operator -(int other) => other; } -''', [ - error(HintCode.UNUSED_ELEMENT, 29, 1), - ]); +void main() { + "hello" - 3; +} +'''); } - test_method_notUsed_unnamedExtension_operator() async { - await assertErrorsInCode(r''' -extension on String { + test_method_isUsed_privateExtension_generic_binaryOperator() async { + await assertNoErrorsInCode(r''' +class A {} +extension _A on A { int operator -(int other) => other; } -''', [ - error(HintCode.UNUSED_ELEMENT, 37, 1), - ]); +void f(A a) { + a - 3; +} +'''); } - test_mixin_isUsed_with() async { + test_method_isUsed_privateExtension_generic_indexEqOperator() async { await assertNoErrorsInCode(r''' -mixin _M {} -class C with _M {} +class A {} +extension _A on A { + void operator []=(int index, T value) { +}} +void f(A a) { + a[0] = 1; +} '''); } - test_mixin_notUsed() async { - await assertErrorsInCode(r''' -mixin _M {} -''', [ - error(HintCode.UNUSED_ELEMENT, 6, 2), - ]); + test_method_isUsed_privateExtension_generic_indexOperator() async { + await assertNoErrorsInCode(r''' +class A {} +extension _A on A { + A operator [](int index) => throw 0; +} +void f(A a) { + a[0]; +} +'''); } - test_optionalParameter_isUsed_constructor() async { + test_method_isUsed_privateExtension_generic_method() async { await assertNoErrorsInCode(r''' -class _A { - _A([int a = 0]); +class A {} +extension _A on A { + A foo() => throw 0; +} +void f(A a) { + a.foo(); } -f() => _A(0); '''); } - test_optionalParameter_isUsed_functionTearoff() async { + test_method_isUsed_privateExtension_generic_postfixOperator() async { await assertNoErrorsInCode(r''' -f() { - void _m([int a]) {} - _m; +class A {} +extension _A on A { + A operator -(int i) => throw 0; +} +void f(A a) { + a--; } '''); } - test_optionalParameter_isUsed_local() async { + test_method_isUsed_privateExtension_generic_prefixOperator() async { await assertNoErrorsInCode(r''' -f() { - void _m([int a]) {} - _m(1); +class A {} +extension _A on A { + T operator ~() => throw 0; +} +void f(A a) { + ~a; } '''); } - test_optionalParameter_isUsed_methodTearoff() async { + test_method_isUsed_privateExtension_indexEqOperator() async { await assertNoErrorsInCode(r''' -class A { - void _m([int a]) {} +extension _A on bool { + operator []=(int index, int value) {} +} +void main() { + false[0] = 1; } -f() => A()._m; '''); } - test_optionalParameter_isUsed_named() async { + test_method_isUsed_privateExtension_indexOperator() async { await assertNoErrorsInCode(r''' -class A { - void _m({int a = 0}) {} +extension _A on bool { + int operator [](int index) => 7; +} +void main() { + false[3]; } -f() => A()._m(a: 0); '''); } - test_optionalParameter_isUsed_overridden() async { - await assertErrorsInCode(r''' -class A { - void _m([int a]) {} + test_method_isUsed_privateExtension_methodCall() async { + await assertNoErrorsInCode(r''' +extension _E on int { + void call() {} } -class B implements A { - void _m([int a]) {} + +void f() { + 0(); } -f() { - A()._m(); - B()._m(0); +'''); + } + + test_method_isUsed_privateExtension_operator_assignment() async { + await assertNoErrorsInCode(r''' +extension _A on String { + String operator -(int other) => this; } -''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 25, 1), - ]); +void f(String s) { + s -= 3; +} +'''); } - test_optionalParameter_isUsed_override() async { + test_method_isUsed_privateExtension_postfixOperator() async { await assertNoErrorsInCode(r''' -class A { - void _m([int a]) {} +extension _A on String { + String operator -(int i) => this; } -class B implements A { - void _m([int a]) {} +void f(String a) { + a--; } -f() => A()._m(0); '''); } - test_optionalParameter_isUsed_override_renamed() async { + test_method_isUsed_privateExtension_prefixOperator() async { await assertNoErrorsInCode(r''' -class A { - void _m([int a]) {} +extension _A on String { + int operator ~() => 7; } -class B implements A { - void _m([int b]) {} +void main() { + ~"hello"; } -f() => A()._m(0); '''); } - test_optionalParameter_isUsed_overrideRequired() async { + test_method_isUsed_public() async { await assertNoErrorsInCode(r''' class A { - void _m(int a) {} + m() {} } -class B implements A { - void _m([int a]) {} +main() { } -f() => A()._m(0); '''); } - test_optionalParameter_isUsed_positional() async { + test_method_isUsed_staticInvocation() async { await assertNoErrorsInCode(r''' class A { - void _m([int a]) {} + static _m() {} +} +main() { + A._m(); } -f() => A()._m(0); '''); } - test_optionalParameter_isUsed_publicMethod() async { + test_method_isUsed_unnamedExtension() async { await assertNoErrorsInCode(r''' -class A { - void m([int a]) {} +extension on String { + void m() {} +} +void main() { + "hello".m(); } -f() => A().m(); '''); } - test_optionalParameter_isUsed_publicMethod_extension() async { + test_method_isUsed_unnamedExtension_methodCall() async { await assertNoErrorsInCode(r''' -extension E on String { - void m([int a]) {} +extension on int { + void call() {} +} + +void f() { + 0(); } -f() => "hello".m(); '''); } - test_optionalParameter_isUsed_requiredPositional() async { + test_method_isUsed_unnamedExtension_operator() async { await assertNoErrorsInCode(r''' -class A { - void _m(int a) {} +extension on String { + int operator -(int other) => other; +} +void main() { + "hello" - 3; } -f() => A()._m(0); '''); } - test_optionalParameter_notUsed_constructor_named() async { + test_method_notUsed_hasSameNameAsUsed() async { await assertErrorsInCode(r''' class A { - A._([int a]); + void _m1() {} +} +class B { + void public() => _m1(); + void _m1() {} } -f() => A._(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1), + error(HintCode.UNUSED_ELEMENT, 17, 3), ]); } - test_optionalParameter_notUsed_constructor_unnamed() async { + test_method_notUsed_noReference() async { await assertErrorsInCode(r''' -class _A { - _A([int a]); +class A { + static _m() {} } -f() => _A(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1), + error(HintCode.UNUSED_ELEMENT, 19, 2), ]); } - test_optionalParameter_notUsed_extension() async { + test_method_notUsed_privateExtension() async { await assertErrorsInCode(r''' -extension E on String { - void _m([int a]) {} +extension _A on String { + void m() {} } -f() => "hello"._m(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 39, 1), + error(HintCode.UNUSED_ELEMENT, 32, 1), ]); } - test_optionalParameter_notUsed_named() async { + /// Postfix operators can only be called, not defined. The "notUsed" sibling to + /// this test is the test on a binary operator. + test_method_notUsed_privateExtension_indexEqOperator() async { await assertErrorsInCode(r''' -class A { - void _m({int a}) {} +extension _A on bool { + operator []=(int index, int value) {} } -f() => A()._m(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 25, 1), + error(HintCode.UNUSED_ELEMENT, 34, 3), ]); } - test_optionalParameter_notUsed_override_added() async { + test_method_notUsed_privateExtension_indexOperator() async { await assertErrorsInCode(r''' -class A { - void _m() {} -} -class B implements A { - void _m([int a]) {} +extension _A on bool { + int operator [](int index) => 7; } -f() => A()._m(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 65, 1), + error(HintCode.UNUSED_ELEMENT, 38, 2), ]); } - test_optionalParameter_notUsed_positional() async { + test_method_notUsed_privateExtension_methodCall() async { await assertErrorsInCode(r''' -class A { - void _m([int a]) {} +extension _E on int { + void call() {} } -f() => A()._m(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 25, 1), + error(HintCode.UNUSED_ELEMENT, 29, 4), ]); } - test_optionalParameter_notUsed_publicMethod_privateExtension() async { + /// Assignment operators can only be called, not defined. The "notUsed" sibling + /// to this test is the test on a binary operator. + test_method_notUsed_privateExtension_operator() async { await assertErrorsInCode(r''' -extension _E on String { - void m([int a]) {} +extension _A on String { + int operator -(int other) => other; } -f() => "hello".m(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 39, 1), + error(HintCode.UNUSED_ELEMENT, 40, 1), ]); } - test_optionalParameter_notUsed_publicMethod_unnamedExtension() async { + test_method_notUsed_privateExtension_prefixOperator() async { await assertErrorsInCode(r''' -extension on String { - void m([int a]) {} +extension _A on String { + int operator ~() => 7; } -f() => "hello".m(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 36, 1), + error(HintCode.UNUSED_ELEMENT, 40, 1), ]); } - test_optionalParameter_static_notUsed() async { + test_method_notUsed_referenceFromItself() async { await assertErrorsInCode(r''' class A { - static void _m([int a]) {} -} -f() => A._m(); -''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 32, 1), - ]); + static _m(int p) { + _m(p - 1); } - - test_optionalParameter_staticPublic_notUsed_privateClass() async { - await assertErrorsInCode(r''' -class _A { - static void m([int a]) {} } -f() => _A.m(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 32, 1), + error(HintCode.UNUSED_ELEMENT, 19, 2), ]); } - test_optionalParameter_topLevel_isUsed() async { - await assertNoErrorsInCode(r''' -void _m([int a]) {} -f() => _m(1); -'''); - } - - test_optionalParameter_topLevel_notUsed() async { + test_method_notUsed_referenceInComment() async { await assertErrorsInCode(r''' -void _m([int a]) {} -f() => _m(); +/// [A] has a method, [_f]. +class A { + int _f(int p) => 7; +} ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 13, 1), + error(HintCode.UNUSED_ELEMENT, 44, 2), ]); } - test_optionalParameter_topLevelPublic_isUsed() async { - await assertNoErrorsInCode(r''' -void m([int a]) {} -f() => m(); -'''); - } - - test_publicStaticMethod_privateClass_isUsed() async { - await assertNoErrorsInCode(r''' -class _A { - static void m() {} -} -void main() { - _A.m(); -} -'''); - } - - test_publicStaticMethod_privateClass_notUsed() async { + test_method_notUsed_referenceInComment_outsideEnclosingClass() async { await assertErrorsInCode(r''' -class _A { - static void m() {} +class A { + int _f(int p) => 7; } -void f(_A a) {} +/// This is similar to [A._f]. +int g() => 7; ''', [ - error(HintCode.UNUSED_ELEMENT, 25, 1), + error(HintCode.UNUSED_ELEMENT, 16, 2), ]); } - test_publicStaticMethod_privateExtension_isUsed() async { - await assertNoErrorsInCode(r''' -extension _A on String { - static void m() {} -} -void main() { - _A.m(); + test_method_notUsed_unnamedExtension() async { + await assertErrorsInCode(r''' +extension on String { + void m() {} } -'''); +''', [ + error(HintCode.UNUSED_ELEMENT, 29, 1), + ]); } - test_publicStaticMethod_privateExtension_notUsed() async { + test_method_notUsed_unnamedExtension_operator() async { await assertErrorsInCode(r''' -extension _A on String { - static void m() {} +extension on String { + int operator -(int other) => other; } ''', [ - error(HintCode.UNUSED_ELEMENT, 39, 1), + error(HintCode.UNUSED_ELEMENT, 37, 1), ]); } - test_publicStaticMethod_privateMixin_isUsed() async { + test_mixin_isUsed_with() async { await assertNoErrorsInCode(r''' -mixin _A { - static void m() {} -} -void main() { - _A.m(); -} +mixin _M {} +class C with _M {} '''); } - test_publicStaticMethod_privateMixin_notUsed() async { + test_mixin_notUsed() async { await assertErrorsInCode(r''' -mixin _A { - static void m() {} -} -void main() { - _A; -} +mixin _M {} ''', [ - error(HintCode.UNUSED_ELEMENT, 25, 1), + error(HintCode.UNUSED_ELEMENT, 6, 2), ]); } - test_publicTopLevelFunction_notUsed() async { + test_optionalParameter_isUsed_constructor() async { await assertNoErrorsInCode(r''' -int get a => 1; +class _A { + _A([int a = 0]); +} +f() => _A(0); '''); } - test_setter_isUsed_invocation_implicitThis() async { + test_optionalParameter_isUsed_functionTearoff() async { await assertNoErrorsInCode(r''' -class A { - set _s(x) {} - useSetter() { - _s = 42; +f() { + void _m([int a]) {} + _m; +} +'''); } + + test_optionalParameter_isUsed_local() async { + await assertNoErrorsInCode(r''' +f() { + void _m([int a]) {} + _m(1); } '''); } - test_setter_isUsed_invocation_PrefixedIdentifier() async { + test_optionalParameter_isUsed_methodTearoff() async { await assertNoErrorsInCode(r''' class A { - set _s(x) {} -} -main(A a) { - a._s = 42; + void _m([int a]) {} } +f() => A()._m; '''); } - test_setter_isUsed_invocation_PropertyAccess() async { + test_optionalParameter_isUsed_named() async { await assertNoErrorsInCode(r''' class A { - set _s(x) {} -} -main() { - new A()._s = 42; + void _m({int a = 0}) {} } +f() => A()._m(a: 0); '''); } - test_setter_notUsed_noReference() async { + test_optionalParameter_isUsed_overridden() async { await assertErrorsInCode(r''' class A { - set _s(x) {} + void _m([int a]) {} +} +class B implements A { + void _m([int a]) {} +} +f() { + A()._m(); + B()._m(0); } ''', [ - error(HintCode.UNUSED_ELEMENT, 16, 2), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 25, 1), ]); } - test_setter_notUsed_referenceFromItself() async { - await assertErrorsInCode(r''' + test_optionalParameter_isUsed_override() async { + await assertNoErrorsInCode(r''' class A { - set _s(int x) { - if (x > 5) { - _s = x - 1; - } + void _m([int a]) {} +} +class B implements A { + void _m([int a]) {} +} +f() => A()._m(0); +'''); } + + test_optionalParameter_isUsed_override_renamed() async { + await assertNoErrorsInCode(r''' +class A { + void _m([int a]) {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 16, 2), - ]); +class B implements A { + void _m([int b]) {} +} +f() => A()._m(0); +'''); } - test_topLevelAccessors_isUsed_questionQuestionEqual() async { + test_optionalParameter_isUsed_overrideRequired() async { await assertNoErrorsInCode(r''' -int get _c => 1; -void set _c(int x) {} -int f() { - return _c ??= 7; +class A { + void _m(int a) {} } +class B implements A { + void _m([int a]) {} +} +f() => A()._m(0); '''); } - test_topLevelFunction_isUsed_hasPragma_vmEntryPoint() async { + test_optionalParameter_isUsed_positional() async { await assertNoErrorsInCode(r''' -@pragma('vm:entry-point') -void _f() {} +class A { + void _m([int a]) {} +} +f() => A()._m(0); '''); } - test_topLevelFunction_isUsed_invocation() async { + test_optionalParameter_isUsed_publicMethod() async { await assertNoErrorsInCode(r''' -_f() {} -main() { - _f(); +class A { + void m([int a]) {} } +f() => A().m(); '''); } - test_topLevelFunction_isUsed_reference() async { + test_optionalParameter_isUsed_publicMethod_extension() async { await assertNoErrorsInCode(r''' -_f() {} -main() { - print(_f); +extension E on String { + void m([int a]) {} } -print(x) {} +f() => "hello".m(); '''); } - test_topLevelFunction_notUsed_noReference() async { - await assertErrorsInCode(r''' -_f() {} -main() { + test_optionalParameter_isUsed_requiredPositional() async { + await assertNoErrorsInCode(r''' +class A { + void _m(int a) {} } -''', [ - error(HintCode.UNUSED_ELEMENT, 0, 2), - ]); +f() => A()._m(0); +'''); } - test_topLevelFunction_notUsed_referenceFromItself() async { + test_optionalParameter_notUsed_constructor_named() async { await assertErrorsInCode(r''' -_f(int p) { - _f(p - 1); -} -main() { +class A { + A._([int a]); } +f() => A._(); ''', [ - error(HintCode.UNUSED_ELEMENT, 0, 2), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1), ]); } - test_topLevelFunction_notUsed_referenceInComment() async { + test_optionalParameter_notUsed_constructor_unnamed() async { await assertErrorsInCode(r''' -/// [_f] is a great function. -_f(int p) => 7; +class _A { + _A([int a]); +} +f() => _A(); ''', [ - error(HintCode.UNUSED_ELEMENT, 30, 2), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1), ]); } - test_topLevelGetterSetter_isUsed_assignmentExpression_compound() async { - await assertNoErrorsInCode(r''' -int get _foo => 0; -set _foo(int _) {} - -void f() { - _foo += 2; -} -'''); - } - - test_topLevelGetterSetter_isUsed_postfixExpression_increment() async { - await assertNoErrorsInCode(r''' -int get _foo => 0; -set _foo(int _) {} - -void f() { - _foo++; -} -'''); - } - - test_topLevelGetterSetter_isUsed_prefixExpression_increment() async { - await assertNoErrorsInCode(r''' -int get _foo => 0; -set _foo(int _) {} - -void f() { - ++_foo; + test_optionalParameter_notUsed_extension() async { + await assertErrorsInCode(r''' +extension E on String { + void _m([int a]) {} } -'''); +f() => "hello"._m(); +''', [ + error(HintCode.UNUSED_ELEMENT_PARAMETER, 39, 1), + ]); } - test_topLevelSetter_isUsed_assignmentExpression_simple() async { - await assertNoErrorsInCode(r''' -set _foo(int _) {} - -void f() { - _foo = 0; + test_optionalParameter_notUsed_named() async { + await assertErrorsInCode(r''' +class A { + void _m({int a}) {} } -'''); +f() => A()._m(); +''', [ + error(HintCode.UNUSED_ELEMENT_PARAMETER, 25, 1), + ]); } - test_topLevelSetter_notUsed() async { + test_optionalParameter_notUsed_override_added() async { await assertErrorsInCode(r''' -set _foo(int _) {} +class A { + void _m() {} +} +class B implements A { + void _m([int a]) {} +} +f() => A()._m(); ''', [ - error(HintCode.UNUSED_ELEMENT, 4, 4), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 65, 1), ]); } - test_topLevelVariable_isUsed() async { - await assertNoErrorsInCode(r''' -int _a = 1; -main() { - _a; + test_optionalParameter_notUsed_positional() async { + await assertErrorsInCode(r''' +class A { + void _m([int a]) {} } -'''); +f() => A()._m(); +''', [ + error(HintCode.UNUSED_ELEMENT_PARAMETER, 25, 1), + ]); } - test_topLevelVariable_isUsed_plusPlus() async { - await assertNoErrorsInCode(r''' -int _a = 0; -main() { - var b = _a++; - b; + test_optionalParameter_notUsed_publicMethod_privateExtension() async { + await assertErrorsInCode(r''' +extension _E on String { + void m([int a]) {} } -'''); +f() => "hello".m(); +''', [ + error(HintCode.UNUSED_ELEMENT_PARAMETER, 39, 1), + ]); } - test_topLevelVariable_isUsed_questionQuestionEqual() async { - await assertNoErrorsInCode(r''' -int _a; -f() { - _a ??= 1; + test_optionalParameter_notUsed_publicMethod_unnamedExtension() async { + await assertErrorsInCode(r''' +extension on String { + void m([int a]) {} } -'''); +f() => "hello".m(); +''', [ + error(HintCode.UNUSED_ELEMENT_PARAMETER, 36, 1), + ]); } - test_topLevelVariable_notUsed() async { + test_optionalParameter_static_notUsed() async { await assertErrorsInCode(r''' -int _a = 1; -main() { - _a = 2; +class A { + static void _m([int a]) {} } +f() => A._m(); ''', [ - error(HintCode.UNUSED_ELEMENT, 4, 2), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 32, 1), ]); } - test_topLevelVariable_notUsed_compoundAssign() async { + test_optionalParameter_staticPublic_notUsed_privateClass() async { await assertErrorsInCode(r''' -int _a = 1; -f() { - _a += 1; +class _A { + static void m([int a]) {} } +f() => _A.m(); ''', [ - error(HintCode.UNUSED_ELEMENT, 4, 2), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 32, 1), ]); } - test_topLevelVariable_notUsed_referenceInComment() async { + test_optionalParameter_topLevel_isUsed() async { + await assertNoErrorsInCode(r''' +void _m([int a]) {} +f() => _m(1); +'''); + } + + test_optionalParameter_topLevel_notUsed() async { await assertErrorsInCode(r''' -/// [_a] is a great variable. -int _a = 7; +void _m([int a]) {} +f() => _m(); ''', [ - error(HintCode.UNUSED_ELEMENT, 34, 2), + error(HintCode.UNUSED_ELEMENT_PARAMETER, 13, 1), ]); } - test_typeAlias_functionType_isUsed_isExpression() async { + test_optionalParameter_topLevelPublic_isUsed() async { await assertNoErrorsInCode(r''' -typedef _F = void Function(); -main(f) { - if (f is _F) { - print('F'); - } -} +void m([int a]) {} +f() => m(); '''); } - test_typeAlias_functionType_isUsed_reference() async { + test_publicStaticMethod_privateClass_isUsed() async { await assertNoErrorsInCode(r''' -typedef _F = void Function(); -main(_F f) { +class _A { + static void m() {} +} +void main() { + _A.m(); } '''); } - test_typeAlias_functionType_isUsed_typeArgument() async { - await assertNoErrorsInCode(r''' -typedef _F = void Function(); -main() { - var v = new List<_F>(); - print(v); + test_publicStaticMethod_privateClass_notUsed() async { + await assertErrorsInCode(r''' +class _A { + static void m() {} } -'''); +void f(_A a) {} +''', [ + error(HintCode.UNUSED_ELEMENT, 25, 1), + ]); } - test_typeAlias_functionType_isUsed_variableDeclaration() async { + test_publicStaticMethod_privateExtension_isUsed() async { await assertNoErrorsInCode(r''' -typedef _F = void Function(); -class A { - _F f; +extension _A on String { + static void m() {} +} +void main() { + _A.m(); } '''); } - test_typeAlias_functionType_notUsed_noReference() async { + test_publicStaticMethod_privateExtension_notUsed() async { await assertErrorsInCode(r''' -typedef _F = void Function(); -main() { +extension _A on String { + static void m() {} } ''', [ - error(HintCode.UNUSED_ELEMENT, 8, 2), + error(HintCode.UNUSED_ELEMENT, 39, 1), ]); } -} -@reflectiveTest -class UnusedElementWithNullSafetyTest extends PubPackageResolutionTest { - test_class_isUsed_isExpression_expression() async { - await assertNoErrorsInCode(''' -class _A {} -void f(Object p) { - if (_A() is int) { - } + test_publicStaticMethod_privateMixin_isUsed() async { + await assertNoErrorsInCode(r''' +mixin _A { + static void m() {} +} +void main() { + _A.m(); } '''); } - test_class_notUsed_isExpression_typeArgument() async { + test_publicStaticMethod_privateMixin_notUsed() async { await assertErrorsInCode(r''' -class _A {} -void f(Object p) { - if (p is List<_A>) { - } +mixin _A { + static void m() {} +} +void main() { + _A; } ''', [ - error(HintCode.UNUSED_ELEMENT, 6, 2), + error(HintCode.UNUSED_ELEMENT, 25, 1), ]); } - test_class_notUsed_isExpression_typeInFunctionType() async { - await assertErrorsInCode(r''' -class _A {} -void f(Object p) { - if (p is void Function(_A)) { - } -} -''', [ - error(HintCode.UNUSED_ELEMENT, 6, 2), - ]); + test_publicTopLevelFunction_notUsed() async { + await assertNoErrorsInCode(r''' +int get a => 1; +'''); } - test_class_notUsed_isExpression_typeInTypeParameter() async { - await assertErrorsInCode(r''' -class _A {} -void f(Object p) { - if (p is void Function()) { + test_setter_isUsed_invocation_implicitThis() async { + await assertNoErrorsInCode(r''' +class A { + set _s(x) {} + useSetter() { + _s = 42; } } -''', [ - error(HintCode.UNUSED_ELEMENT, 6, 2), - ]); +'''); } - test_class_notUsed_variableDeclaration() async { - await assertErrorsInCode(''' -class _A {} -void f() { - _A? v; - print(v); + test_setter_isUsed_invocation_PrefixedIdentifier() async { + await assertNoErrorsInCode(r''' +class A { + set _s(x) {} } -print(x) {} -''', [ - error(HintCode.UNUSED_ELEMENT, 6, 2), - ]); +main(A a) { + a._s = 42; +} +'''); } - test_class_notUsed_variableDeclaration_typeArgument() async { - await assertErrorsInCode(''' -class _A {} + test_setter_isUsed_invocation_PropertyAccess() async { + await assertNoErrorsInCode(r''' +class A { + set _s(x) {} +} main() { - List<_A>? v; - print(v); + new A()._s = 42; +} +'''); + } + + test_setter_notUsed_noReference() async { + await assertErrorsInCode(r''' +class A { + set _s(x) {} } -print(x) {} ''', [ - error(HintCode.UNUSED_ELEMENT, 6, 2), + error(HintCode.UNUSED_ELEMENT, 16, 2), ]); } - test_optionalParameter_isUsed_genericConstructor() async { - await assertNoErrorsInCode(''' -class C { - C._([int? x]); + test_setter_notUsed_referenceFromItself() async { + await assertErrorsInCode(r''' +class A { + set _s(int x) { + if (x > 5) { + _s = x - 1; + } + } } -void foo() { - C._(7); +''', [ + error(HintCode.UNUSED_ELEMENT, 16, 2), + ]); + } + + test_topLevelAccessors_isUsed_questionQuestionEqual() async { + await assertNoErrorsInCode(r''' +int get _c => 1; +void set _c(int x) {} +int f() { + return _c ??= 7; } '''); } - test_optionalParameter_isUsed_genericFunction() async { - await assertNoErrorsInCode(''' -void _f([int? x]) {} -void foo() { - _f(7); -} + test_topLevelFunction_isUsed_hasPragma_vmEntryPoint() async { + await assertNoErrorsInCode(r''' +@pragma('vm:entry-point') +void _f() {} '''); } - test_optionalParameter_isUsed_genericMethod() async { - await assertNoErrorsInCode(''' -class C { - void _m([int? x]) {} -} -void foo() { - C()._m(7); + test_topLevelFunction_isUsed_invocation() async { + await assertNoErrorsInCode(r''' +_f() {} +main() { + _f(); } '''); } - test_optionalParameter_isUsed_overrideRequiredNamed() async { + test_topLevelFunction_isUsed_reference() async { await assertNoErrorsInCode(r''' -class A { - void _m({required int a}) {} -} -class B implements A { - void _m({int a = 0}) {} +_f() {} +main() { + print(_f); } -f() => A()._m(a: 0); +print(x) {} '''); } - @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47839') - test_optionalParameter_notUsed_genericConstructor() async { - // TODO(srawlins): Change to assertErrorsInCode when this is fixed. - addTestFile(''' -class C { - C._([int? x]); + test_topLevelFunction_notUsed_noReference() async { + await assertErrorsInCode(r''' +_f() {} +main() { } -void foo() { - C._(); +''', [ + error(HintCode.UNUSED_ELEMENT, 0, 2), + ]); + } + + test_topLevelFunction_notUsed_referenceFromItself() async { + await assertErrorsInCode(r''' +_f(int p) { + _f(p - 1); } -'''); - await resolveTestFile(); - expect(result.errors, isNotEmpty); +main() { +} +''', [ + error(HintCode.UNUSED_ELEMENT, 0, 2), + ]); } - @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47839') - test_optionalParameter_notUsed_genericFunction() async { - // TODO(srawlins): Change to assertErrorsInCode when this is fixed. - addTestFile(''' -void _f([int? x]) {} -void foo() { - _f(); + test_topLevelFunction_notUsed_referenceInComment() async { + await assertErrorsInCode(r''' +/// [_f] is a great function. +_f(int p) => 7; +''', [ + error(HintCode.UNUSED_ELEMENT, 30, 2), + ]); + } + + test_topLevelGetterSetter_isUsed_assignmentExpression_compound() async { + await assertNoErrorsInCode(r''' +int get _foo => 0; +set _foo(int _) {} + +void f() { + _foo += 2; } '''); - await resolveTestFile(); - expect(result.errors, isNotEmpty); } - @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47839') - test_optionalParameter_notUsed_genericMethod() async { - // TODO(srawlins): Change to assertErrorsInCode when this is fixed. - addTestFile(''' -class C { - void _m([int? x]) {} -} -void foo() { - C()._m(); + test_topLevelGetterSetter_isUsed_postfixExpression_increment() async { + await assertNoErrorsInCode(r''' +int get _foo => 0; +set _foo(int _) {} + +void f() { + _foo++; } '''); - await resolveTestFile(); - expect(result.errors, isNotEmpty); } - test_parameter_optionalNamed_fieldFormal_isUsed_constructorInvocation() async { + test_topLevelGetterSetter_isUsed_prefixExpression_increment() async { await assertNoErrorsInCode(r''' -class _A { - final int? f; - _A({this.f}); +int get _foo => 0; +set _foo(int _) {} + +void f() { + ++_foo; } -f() => _A(f: 0); '''); } - test_parameter_optionalNamed_fieldFormal_isUsed_factoryRedirect() async { + test_topLevelSetter_isUsed_assignmentExpression_simple() async { await assertNoErrorsInCode(r''' -class _A { - final int? f; - _A({this.f}); - factory _A.named({int? f}) = _A; +set _foo(int _) {} + +void f() { + _foo = 0; } -f() => _A.named(f: 0); '''); } - test_parameter_optionalNamed_fieldFormal_notUsed() async { + test_topLevelSetter_notUsed() async { await assertErrorsInCode(r''' -class _A { - final int? f; - _A({this.f}); -} -f() => _A(); +set _foo(int _) {} ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), + error(HintCode.UNUSED_ELEMENT, 4, 4), ]); } - test_parameter_optionalNamed_fieldFormal_notUsed_factoryRedirect() async { - await assertErrorsInCode(r''' -class _A { - final int? f; - _A({this.f}); - factory _A.named() = _A; + test_topLevelVariable_isUsed() async { + await assertNoErrorsInCode(r''' +int _a = 1; +main() { + _a; } -f() => _A.named(); -''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), - ]); +'''); } - test_parameter_optionalPositional_fieldFormal_isUsed_constructorInvocation() async { + test_topLevelVariable_isUsed_plusPlus() async { await assertNoErrorsInCode(r''' -class _A { - final int? f; - _A([this.f]); +int _a = 0; +main() { + var b = _a++; + b; } -f() => _A(0); '''); } - test_parameter_optionalPositional_fieldFormal_isUsed_factoryRedirect() async { + test_topLevelVariable_isUsed_questionQuestionEqual() async { await assertNoErrorsInCode(r''' -class _A { - final int? f; - _A([this.f]); - factory _A.named([int a]) = _A; +int _a; +f() { + _a ??= 1; } -f() => _A.named(0); '''); } - test_parameter_optionalPositional_fieldFormal_notUsed() async { + test_topLevelVariable_notUsed() async { await assertErrorsInCode(r''' -class _A { - final int? f; - _A([this.f]); +int _a = 1; +main() { + _a = 2; } -f() => _A(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), + error(HintCode.UNUSED_ELEMENT, 4, 2), ]); } - test_parameter_optionalPositional_fieldFormal_notUsed_factoryRedirect() async { + test_topLevelVariable_notUsed_compoundAssign() async { await assertErrorsInCode(r''' -class _A { - final int? f; - _A([this.f]); - factory _A.named() = _A; +int _a = 1; +f() { + _a += 1; } -f() => _A.named(); ''', [ - error(HintCode.UNUSED_ELEMENT_PARAMETER, 38, 1), + error(HintCode.UNUSED_ELEMENT, 4, 2), ]); } - test_typeAlias_interfaceType_isUsed_typeName_isExpression() async { - await assertNoErrorsInCode(r''' -typedef _A = List; + test_topLevelVariable_notUsed_referenceInComment() async { + await assertErrorsInCode(r''' +/// [_a] is a great variable. +int _a = 7; +''', [ + error(HintCode.UNUSED_ELEMENT, 34, 2), + ]); + } -void f(a) { - a is _A; + test_typeAlias_functionType_isUsed_isExpression() async { + await assertNoErrorsInCode(r''' +typedef _F = void Function(); +main(f) { + if (f is _F) { + print('F'); + } } '''); } - test_typeAlias_interfaceType_isUsed_typeName_parameter() async { + test_typeAlias_functionType_isUsed_reference() async { await assertNoErrorsInCode(r''' -typedef _A = List; - -void f(_A a) {} +typedef _F = void Function(); +main(_F f) { +} '''); } - test_typeAlias_interfaceType_isUsed_typeName_typeArgument() async { + test_typeAlias_functionType_isUsed_typeArgument() async { await assertNoErrorsInCode(r''' -typedef _A = List; +typedef _F = void Function(); +main() { + var v = new List<_F>(); + print(v); +} +'''); + } -void f() { - Map<_A, int>(); + test_typeAlias_functionType_isUsed_variableDeclaration() async { + await assertNoErrorsInCode(r''' +typedef _F = void Function(); +class A { + _F f; } '''); } - test_typeAlias_interfaceType_notUsed() async { + test_typeAlias_functionType_notUsed_noReference() async { await assertErrorsInCode(r''' -typedef _A = List; +typedef _F = void Function(); +main() { +} ''', [ error(HintCode.UNUSED_ELEMENT, 8, 2), ]); From 6c494313d716e1156f577e84329c6e3bbb8d1c60 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 10 Feb 2022 04:29:17 +0000 Subject: [PATCH 3/4] Remove duplicate of toLegacyTypeIfOptOut() in TypeSystemImpl. Change-Id: I2d58f82a1cf9fa754713288665587e8ee2e296a5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232235 Reviewed-by: Samuel Rawlins Commit-Queue: Konstantin Shcheglov --- .../src/dart/constant/constant_verifier.dart | 2 +- .../lib/src/dart/constant/evaluation.dart | 2 +- .../lib/src/dart/element/class_hierarchy.dart | 2 +- .../lib/src/dart/element/least_upper_bound.dart | 2 +- .../lib/src/dart/element/type_system.dart | 17 +++++------------ .../lib/src/dart/element/well_bounded.dart | 2 +- .../src/dart/resolver/named_type_resolver.dart | 2 +- .../lib/src/summary2/named_type_builder.dart | 4 ++-- 8 files changed, 13 insertions(+), 20 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart index 29b2ae2ab571b..1202cc6e58468 100644 --- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart +++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart @@ -623,7 +623,7 @@ class ConstantVerifier extends RecursiveAstVisitor { .NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY, ); - var expressionValueType = _typeSystem.toLegacyType( + var expressionValueType = _typeSystem.toLegacyTypeIfOptOut( expressionValue.type, ); diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart index 72131f5d75f58..0e8ee0aa7d30c 100644 --- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart +++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart @@ -2605,7 +2605,7 @@ extension RuntimeExtensions on TypeSystemImpl { DartType type, ) { if (!isNonNullableByDefault) { - type = toLegacyType(type); + type = toLegacyTypeIfOptOut(type); } var objType = obj.type; return isSubtypeOf(objType, type); diff --git a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart index 0a44e08f53b1d..1a8a0ca9869a1 100644 --- a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart +++ b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart @@ -183,7 +183,7 @@ class _ClassInterfaceType { ); } } else { - var legacyType = _typeSystem.toLegacyType(type) as InterfaceType; + var legacyType = _typeSystem.toLegacyTypeIfOptOut(type) as InterfaceType; if (_currentResult == null) { _currentResult = legacyType; } else { diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart index df0e9e2849736..94dd226c05580 100644 --- a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart +++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart @@ -248,7 +248,7 @@ class InterfaceLeastUpperBoundHelper { return result; } else { return result.map((e) { - return e.mapArguments(typeSystem.toLegacyType); + return e.mapArguments(typeSystem.toLegacyTypeIfOptOut); }).toSet(); } } diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart index f12c60237fc81..1b41aeb5486f9 100644 --- a/pkg/analyzer/lib/src/dart/element/type_system.dart +++ b/pkg/analyzer/lib/src/dart/element/type_system.dart @@ -544,7 +544,7 @@ class TypeSystemImpl implements TypeSystem { typeArguments: typeArguments, nullabilitySuffix: nullabilitySuffix, ); - type = toLegacyType(type) as InterfaceType; + type = toLegacyTypeIfOptOut(type) as InterfaceType; return type; } else if (typeAliasElement != null) { var typeParameters = typeAliasElement.typeParameters; @@ -553,7 +553,7 @@ class TypeSystemImpl implements TypeSystem { typeArguments: typeArguments, nullabilitySuffix: nullabilitySuffix, ); - type = toLegacyType(type); + type = toLegacyTypeIfOptOut(type); return type; } else { throw ArgumentError('Missing element'); @@ -1295,8 +1295,8 @@ class TypeSystemImpl implements TypeSystem { // TODO(scheglov) waiting for the spec // https://github.com/dart-lang/sdk/issues/42605 } else { - srcType = toLegacyType(srcType); - destType = toLegacyType(destType); + srcType = toLegacyTypeIfOptOut(srcType); + destType = toLegacyTypeIfOptOut(destType); } if (srcType != destType) { // Failed to find an appropriate substitution @@ -1480,17 +1480,10 @@ class TypeSystemImpl implements TypeSystem { return RuntimeTypeEqualityHelper(this).equal(T1, T2); } - DartType toLegacyType(DartType type) { - if (isNonNullableByDefault) return type; - return NullabilityEliminator.perform(typeProvider, type); - } - /// If a legacy library, return the legacy version of the [type]. /// Otherwise, return the original type. DartType toLegacyTypeIfOptOut(DartType type) { - if (isNonNullableByDefault) { - return type; - } + if (isNonNullableByDefault) return type; return NullabilityEliminator.perform(typeProvider, type); } diff --git a/pkg/analyzer/lib/src/dart/element/well_bounded.dart b/pkg/analyzer/lib/src/dart/element/well_bounded.dart index 35185ec6ef8d8..9ca8629044918 100644 --- a/pkg/analyzer/lib/src/dart/element/well_bounded.dart +++ b/pkg/analyzer/lib/src/dart/element/well_bounded.dart @@ -101,7 +101,7 @@ class TypeBoundedHelper { continue; } - bound = typeSystem.toLegacyType(bound); + bound = typeSystem.toLegacyTypeIfOptOut(bound); bound = substitution.substituteType(bound); if (!typeSystem.isSubtypeOf(typeArgument, bound)) { diff --git a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart index 969d189f7573a..5063c861e25b0 100644 --- a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart +++ b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart @@ -213,7 +213,7 @@ class NamedTypeResolver { typeArguments: typeArguments, nullabilitySuffix: nullability, ); - type = typeSystem.toLegacyType(type); + type = typeSystem.toLegacyTypeIfOptOut(type); return _verifyTypeAliasForContext(node, element, type); } else if (_isInstanceCreation(node)) { _ErrorHelper(errorReporter).reportNewWithNonType(node); diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart index e6cd97a54dbb6..9b4f698c523e9 100644 --- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart +++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart @@ -103,7 +103,7 @@ class NamedTypeBuilder extends TypeBuilder { typeArguments: arguments, nullabilitySuffix: nullabilitySuffix, ); - type = typeSystem.toLegacyType(type) as InterfaceType; + type = typeSystem.toLegacyTypeIfOptOut(type) as InterfaceType; _type = type; } else if (element is TypeAliasElementImpl) { var aliasedType = _getAliasedType(element); @@ -114,7 +114,7 @@ class NamedTypeBuilder extends TypeBuilder { typeArguments: arguments, nullabilitySuffix: nullabilitySuffix, ); - type = typeSystem.toLegacyType(type); + type = typeSystem.toLegacyTypeIfOptOut(type); _type = type; } else if (element is NeverElementImpl) { if (typeSystem.isNonNullableByDefault) { From 7605a36ab3e1601ee561758fc6936c707c0f90c0 Mon Sep 17 00:00:00 2001 From: Sai Sandeep Mutyala Date: Thu, 10 Feb 2022 06:03:59 +0000 Subject: [PATCH 4/4] Add fix for sort_constructors_first lint. Bug: https://github.com/dart-lang/sdk/issues/47953 Change-Id: I0c927714f55eddd30d0c3770a3315118f64a160b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232141 Reviewed-by: Brian Wilkerson Commit-Queue: Brian Wilkerson --- .../dart/sort_constructor_first.dart | 49 ++++++++++ .../lib/src/services/correction/fix.dart | 10 ++ .../src/services/correction/fix_internal.dart | 4 + .../fix/sort_constructor_first_test.dart | 97 +++++++++++++++++++ .../src/services/correction/fix/test_all.dart | 2 + 5 files changed, 162 insertions(+) create mode 100644 pkg/analysis_server/lib/src/services/correction/dart/sort_constructor_first.dart create mode 100644 pkg/analysis_server/test/src/services/correction/fix/sort_constructor_first_test.dart diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_constructor_first.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_constructor_first.dart new file mode 100644 index 0000000000000..3eb4641fb6ca3 --- /dev/null +++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_constructor_first.dart @@ -0,0 +1,49 @@ +// Copyright (c) 2022, 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:analysis_server/src/services/correction/dart/abstract_producer.dart'; +import 'package:analysis_server/src/services/correction/fix.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; +import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +import 'package:analyzer_plugin/utilities/range_factory.dart'; + +class SortConstructorFirst extends CorrectionProducer { + @override + bool get canBeAppliedInBulk => true; + + @override + bool get canBeAppliedToFile => true; + + @override + FixKind get fixKind => DartFixKind.SORT_CONSTRUCTOR_FIRST; + + @override + FixKind get multiFixKind => DartFixKind.SORT_CONSTRUCTOR_FIRST_MULTI; + + @override + Future compute(ChangeBuilder builder) async { + var constructor = coveredNode?.parent; + var clazz = constructor?.parent; + if (clazz is! ClassDeclaration || constructor is! ConstructorDeclaration) { + return; + } + + await builder.addDartFileEdit(file, (builder) { + var deletionRange = range.endEnd( + constructor.beginToken.previous!, + constructor.endToken, + ); + + builder.addDeletion(deletionRange); + builder.addSimpleInsertion( + clazz.leftBracket.end, + utils.getRangeText(deletionRange), + ); + }); + } + + /// Return an instance of this class. Used as a tear-off in `FixProcessor`. + static SortConstructorFirst newInstance() => SortConstructorFirst(); +} diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart index 8a91925ccddb2..874bbdb60f890 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix.dart @@ -1440,6 +1440,16 @@ class DartFixKind { DartFixKindPriority.IN_FILE, 'Move child properties to ends of arguments everywhere in file', ); + static const SORT_CONSTRUCTOR_FIRST = FixKind( + 'dart.fix.sort.sortConstructorFirst', + DartFixKindPriority.DEFAULT, + 'Move before other members', + ); + static const SORT_CONSTRUCTOR_FIRST_MULTI = FixKind( + 'dart.fix.sort.sortConstructorFirst.multi', + DartFixKindPriority.DEFAULT, + 'Move all constructors before other members', + ); static const SORT_UNNAMED_CONSTRUCTOR_FIRST = FixKind( 'dart.fix.sort.sortUnnamedConstructorFirst', DartFixKindPriority.DEFAULT, diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart index a09d76c2dea50..6f03b72504696 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart @@ -170,6 +170,7 @@ import 'package:analysis_server/src/services/correction/dart/replace_with_null_a import 'package:analysis_server/src/services/correction/dart/replace_with_tear_off.dart'; import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart'; import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart'; +import 'package:analysis_server/src/services/correction/dart/sort_constructor_first.dart'; import 'package:analysis_server/src/services/correction/dart/sort_unnamed_constructor_first.dart'; import 'package:analysis_server/src/services/correction/dart/update_sdk_constraints.dart'; import 'package:analysis_server/src/services/correction/dart/use_const.dart'; @@ -572,6 +573,9 @@ class FixProcessor extends BaseProcessor { LintNames.sort_child_properties_last: [ SortChildPropertyLast.newInstance, ], + LintNames.sort_constructors_first: [ + SortConstructorFirst.newInstance, + ], LintNames.sort_unnamed_constructors_first: [ SortUnnamedConstructorFirst.newInstance, ], diff --git a/pkg/analysis_server/test/src/services/correction/fix/sort_constructor_first_test.dart b/pkg/analysis_server/test/src/services/correction/fix/sort_constructor_first_test.dart new file mode 100644 index 0000000000000..a1f240ba977b9 --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/sort_constructor_first_test.dart @@ -0,0 +1,97 @@ +// Copyright (c) 2022, 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:analysis_server/src/services/correction/fix.dart'; +import 'package:analysis_server/src/services/linter/lint_names.dart'; +import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'fix_processor.dart'; + +void main() { + defineReflectiveSuite(() { + defineReflectiveTests(SortConstructorFirstBulkTest); + defineReflectiveTests(SortConstructorFirstTest); + }); +} + +@reflectiveTest +class SortConstructorFirstBulkTest extends BulkFixProcessorTest { + @override + String get lintCode => LintNames.sort_constructors_first; + + Future test_multiple_classes() async { + await resolveTestCode(''' +class A { + X() {} + A(); +} + +class B { + Y() {} + B(); +} +'''); + await assertHasFix(''' +class A { + A(); + X() {} +} + +class B { + B(); + Y() {} +} +'''); + } + + Future test_single_class() async { + await resolveTestCode(''' +class A { + X() {} + + A(); + + Y() {} + + A._(); +} +'''); + await assertHasFix(''' +class A { + + A(); + + A._(); + X() {} + + Y() {} +} +'''); + } +} + +@reflectiveTest +class SortConstructorFirstTest extends FixProcessorLintTest { + @override + FixKind get kind => DartFixKind.SORT_CONSTRUCTOR_FIRST; + + @override + String get lintCode => LintNames.sort_constructors_first; + + Future test_one_fix() async { + await resolveTestCode(''' +class A { + X() {} + A(); +} +'''); + await assertHasFix(''' +class A { + A(); + X() {} +} +'''); + } +} diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart index 419611848d510..c61f1a5206c4a 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart @@ -207,6 +207,7 @@ import 'replace_with_null_aware_test.dart' as replace_with_null_aware; import 'replace_with_tear_off_test.dart' as replace_with_tear_off; import 'replace_with_var_test.dart' as replace_with_var; import 'sort_child_property_last_test.dart' as sort_properties_last; +import 'sort_constructor_first_test.dart' as sort_constructor_first_test; import 'sort_unnamed_constructor_first_test.dart' as sort_unnamed_constructor_first_test; import 'update_sdk_constraints_test.dart' as update_sdk_constraints; @@ -400,6 +401,7 @@ void main() { replace_with_tear_off.main(); replace_with_var.main(); sort_properties_last.main(); + sort_constructor_first_test.main(); sort_unnamed_constructor_first_test.main(); update_sdk_constraints.main(); use_const.main();