diff --git a/test/rules/all.dart b/test/rules/all.dart index 192610b7e..7914b6fba 100644 --- a/test/rules/all.dart +++ b/test/rules/all.dart @@ -7,6 +7,7 @@ import 'avoid_function_literals_in_foreach_calls.dart' import 'avoid_init_to_null.dart' as avoid_init_to_null; import 'missing_whitespace_between_adjacent_strings.dart' as missing_whitespace_between_adjacent_strings; +import 'null_closures.dart' as null_closures; import 'overridden_fields.dart' as overridden_fields; import 'prefer_asserts_in_initializer_lists.dart' as prefer_asserts_in_initializer_lists; @@ -14,22 +15,28 @@ import 'prefer_collection_literals.dart' as prefer_collection_literals; import 'prefer_const_constructors.dart' as prefer_const_constructors; import 'prefer_const_constructors_in_immutables.dart' as prefer_const_constructors_in_immutables; +import 'prefer_const_literals_to_create_immutables.dart' + as prefer_const_literals_to_create_immutables; import 'prefer_contains.dart' as prefer_contains; import 'prefer_spread_collections.dart' as prefer_spread_collections; import 'type_init_formals.dart' as type_init_formals; +import 'unawaited_futures.dart' as unawaited_futures; import 'void_checks.dart' as void_checks; void main() { avoid_function_literals_in_foreach_calls.main(); avoid_init_to_null.main(); missing_whitespace_between_adjacent_strings.main(); + null_closures.main(); overridden_fields.main(); prefer_asserts_in_initializer_lists.main(); prefer_collection_literals.main(); prefer_const_constructors.main(); prefer_const_constructors_in_immutables.main(); + prefer_const_literals_to_create_immutables.main(); prefer_contains.main(); prefer_spread_collections.main(); type_init_formals.main(); + unawaited_futures.main(); void_checks.main(); } diff --git a/test/rules/null_closures.dart b/test/rules/null_closures.dart new file mode 100644 index 000000000..518dc3acf --- /dev/null +++ b/test/rules/null_closures.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2021, 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:test_reflective_loader/test_reflective_loader.dart'; + +import '../rule_test_support.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(NullClosuresTest); + }); +} + +@reflectiveTest +class NullClosuresTest extends LintRuleTest { + @override + String get lintRule => 'null_closures'; + + ///https://github.com/dart-lang/linter/issues/1414 + test_recursiveInterfaceInheritance() async { + await assertDiagnostics(r''' +class A extends B { + A(int x); +} + +class B extends A {} + +void test_cycle() { + A(null); +} +''', [ + // No lint + error(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, 6, 1), + error(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, 41, 1), + error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 41, 1), + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 81, 4), + ]); + } +} diff --git a/test/rules/prefer_const_literals_to_create_immutables.dart b/test/rules/prefer_const_literals_to_create_immutables.dart new file mode 100644 index 000000000..8ea207e55 --- /dev/null +++ b/test/rules/prefer_const_literals_to_create_immutables.dart @@ -0,0 +1,50 @@ +// Copyright (c) 2021, 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:test_reflective_loader/test_reflective_loader.dart'; + +import '../rule_test_support.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(PreferConstLiteralsToCreateImmutablesTest); + }); +} + +@reflectiveTest +class PreferConstLiteralsToCreateImmutablesTest extends LintRuleTest { + @override + bool get addMetaPackageDep => true; + + @override + String get lintRule => 'prefer_const_literals_to_create_immutables.dart'; + + test_missingRequiredArgument() async { + await assertDiagnostics(r''' +import 'package:meta/meta.dart'; + +@immutable +class K { + final List<K> children; + const K({required this.children}); +} + +final k = K( + children: <K>[for (var i = 0; i < 5; ++i) K()], // OK +); +''', [ + // No lint + error(CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT, 178, 1), + ]); + } + + test_newWithNonType() async { + await assertDiagnostics(r''' +var e1 = new B([]); // OK +''', [ + // No lint + error(CompileTimeErrorCode.NEW_WITH_NON_TYPE, 13, 1), + ]); + } +} diff --git a/test/rules/unawaited_futures.dart b/test/rules/unawaited_futures.dart new file mode 100644 index 000000000..8a3a84bed --- /dev/null +++ b/test/rules/unawaited_futures.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2021, 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:test_reflective_loader/test_reflective_loader.dart'; + +import '../rule_test_support.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(UnawaitedFuturesTest); + }); +} + +@reflectiveTest +class UnawaitedFuturesTest extends LintRuleTest { + @override + String get lintRule => 'unawaited_futures'; + + test_undefinedIdentifier() async { + await assertDiagnostics(r''' +f() async { + Duration d = Duration(); + Future.delayed(d, bar); +} +''', [ + // No lint + error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 59, 3), + ]); + } +} diff --git a/test_data/rules/experiments/nnbd/rules/null_closures.dart b/test_data/rules/experiments/nnbd/rules/null_closures.dart index b88915a4c..870bc03bd 100644 --- a/test_data/rules/experiments/nnbd/rules/null_closures.dart +++ b/test_data/rules/experiments/nnbd/rules/null_closures.dart @@ -7,16 +7,6 @@ import 'dart:async'; import 'dart:core'; -class A extends B { - A(int x); -} -class B extends A {} - -//https://github.com/dart-lang/linter/issues/1414 -void test_cycle() { - new A(null); -} - void list_firstWhere() { // firstWhere has a _named_ closure argument. <int>[2, 4, 6].firstWhere((e) => e.isEven, orElse: null); // LINT diff --git a/test_data/rules/experiments/nnbd/rules/overridden_fields.dart b/test_data/rules/experiments/nnbd/rules/overridden_fields.dart index 13bcfb74e..966c9ace7 100644 --- a/test_data/rules/experiments/nnbd/rules/overridden_fields.dart +++ b/test_data/rules/experiments/nnbd/rules/overridden_fields.dart @@ -26,7 +26,7 @@ class Bad3 extends Object with Base { } class Ok extends Base { - Object newField; // OK + Object newField = 0; // OK final Object newFinal = 'ignore'; // OK } @@ -36,7 +36,7 @@ class OK2 implements Base { Object something = 'done'; // OK @override - Object field; + Object field = 0; } abstract class OK3 implements Base { @@ -121,7 +121,7 @@ class Sub1 extends Super1 { } class Super2 { - int x, y; + int x = 0, y = 0; } class Sub2 extends Super2 { @@ -130,15 +130,15 @@ class Sub2 extends Super2 { } class Super3 { - int x; + int x = 0; } class Sub3 extends Super3 { - int x; // LINT + int x = 0; // LINT } class A1 { - int f; + int f = 0; } class B1 extends A1 {} @@ -147,27 +147,27 @@ abstract class C1 implements A1 {} class D1 extends B1 implements C1 { @override - int f; // LINT + int f = 0; // LINT } class A extends B {} class B extends A { - int field; + int field = 0; } class StaticsNo { - static int a; + static int a = 0; } class VerifyStatic extends StaticsNo { - static int a; + static int a = 0; } mixin M on A1 { @override - int f; // LINT + int f = 0; // LINT - int g; // OK + int g = 0; // OK } abstract class BB { @@ -177,12 +177,12 @@ abstract class BB { class AA extends BB { /// Overriding abstracts in NNBD is OK. @override - String s; // OK + String s = ''; // OK } class AAA with BB { @override - String s; // OK + String s = ''; // OK } abstract class BBB { @@ -191,5 +191,5 @@ abstract class BBB { class AAA extends BBB { @override - String s; // OK + String s = ''; // OK } diff --git a/test_data/rules/invariant_booleans.dart b/test_data/rules/invariant_booleans.dart index 4f178ee32..be8a27e0b 100644 --- a/test_data/rules/invariant_booleans.dart +++ b/test_data/rules/invariant_booleans.dart @@ -170,16 +170,16 @@ int bar = 1; int baz = 2; int foo = 0; -bool setting; +bool setting = false; class A { - bool foo; - int fooNumber; + bool foo = false; + int fooNumber = 0; } class B { - bool bar; - int barNumber; + bool bar = false; + int barNumber = 0; } A a = new A(); @@ -358,7 +358,7 @@ someFunction() { } class Foo { - bool bar; + bool bar = false; void sayHello() { if (bar ?? false) print('hello'); } @@ -453,7 +453,7 @@ void test337_5() { } void bug658() { - String text; + String? text; if ((text?.length ?? 0) != 0) {} } diff --git a/test_data/rules/null_closures.dart b/test_data/rules/null_closures.dart index 2c57116bb..7d7a6aceb 100644 --- a/test_data/rules/null_closures.dart +++ b/test_data/rules/null_closures.dart @@ -7,16 +7,6 @@ import 'dart:async'; import 'dart:core'; -class A extends B { - A(int x); -} -class B extends A {} - -//https://github.com/dart-lang/linter/issues/1414 -void test_cycle() { - new A(null); -} - void list_firstWhere() { // firstWhere has a _named_ closure argument. <int>[2, 4, 6].firstWhere((e) => e.isEven, orElse: null); // LINT diff --git a/test_data/rules/prefer_const_literals_to_create_immutables.dart b/test_data/rules/prefer_const_literals_to_create_immutables.dart index 01c6130c9..bcd62d184 100644 --- a/test_data/rules/prefer_const_literals_to_create_immutables.dart +++ b/test_data/rules/prefer_const_literals_to_create_immutables.dart @@ -74,19 +74,7 @@ var m13 = new A({1: 1.0}); // LINT var m14 = new A({1: ''}); // LINT var m15 = new A({1: null}); // LINT -// ignore: undefined_class -var e1 = new B([]); // OK - // optional new class C {} var m16 = A([C()]); // OK -@immutable -class K { - final List<K> children; - const K({this.children}); -} - -final k = K( - children: <K>[for (var i = 0; i < 5; ++i) K()], // OK -); diff --git a/test_data/rules/prefer_void_to_null.dart b/test_data/rules/prefer_void_to_null.dart index 661570006..a3cebabf9 100644 --- a/test_data/rules/prefer_void_to_null.dart +++ b/test_data/rules/prefer_void_to_null.dart @@ -7,6 +7,8 @@ // TODO(mfairhurst) test void with a prefix, except that causes bugs. // TODO(mfairhurst) test defining a class named Null (requires a 2nd file) +// ignore_for_file: unused_local_variable + import 'dart:async'; import 'dart:core'; import 'dart:core' as core; @@ -52,9 +54,9 @@ class F implements E { void void_; // OK Null null_; // LINT core.Null core_null; // LINT -Future<void> future_void; // OK -Future<Null> future_null; // LINT -Future<core.Null> future_core_null; // LINT +Future<void>? future_void; // OK +Future<Null>? future_null; // LINT +Future<core.Null>? future_core_null; // LINT void void_f() {} // OK Null null_f() {} // LINT @@ -63,21 +65,21 @@ f_void(void x) {} // OK f_null(Null x) {} // LINT f_core_null(core.Null x) {} // LINT -void Function(Null) voidFunctionNull; // OK -Null Function() nullFunctionVoid; // OK -Future<Null> Function() FutureNullFunction; // LINT -void Function(Future<Null>) voidFunctionFutureNull; // LINT +void Function(Null)? voidFunctionNull; // OK +Null Function()? nullFunctionVoid; // OK +Future<Null> Function()? FutureNullFunction; // LINT +void Function(Future<Null>)? voidFunctionFutureNull; // LINT usage() { void void_; // OK Null null_; // LINT core.Null core_null; // LINT - Future<void> future_void; // OK + Future<void>? future_void; // OK Future<Null> future_null; // LINT Future<core.Null> future_core_null; // LINT - future_void.then<Null>((_) {}); // LINT - future_void.then<void>((_) {}); // OK + future_void?.then<Null>((_) {}); // LINT + future_void?.then<void>((_) {}); // OK } void inference() { @@ -100,10 +102,10 @@ void emptyLiterals() { <Null, Null>{}; // OK <int, Null>{1: null}; // LINT <String, Null>{"foo": null}; // LINT - <Object, Null>{null: null}; // LINT + <Object?, Null>{null: null}; // LINT <Null, int>{null: 1}; // LINT <Null, String>{null: "foo"}; // LINT - <Null, Object>{null: null}; // LINT + <Null, Object?>{null: null}; // LINT <Null, // LINT Null>{null: null}; // LINT <int, void>{}; // OK @@ -115,10 +117,10 @@ void emptyLiterals() { <void, void>{}; // OK <int, void>{1: null}; // OK <String, void>{"foo": null}; // OK - <Object, void>{null: null}; // OK + <Object?, void>{null: null}; // OK <void, int>{null: 1}; // OK <void, String>{null: "foo"}; // OK - <void, Object>{null: null}; // OK + <void, Object?>{null: null}; // OK <void, void>{null: null}; // OK // TODO(mfairhurst): is it worth handling more complex literals? @@ -137,9 +139,9 @@ class AsMembers { void void_; // OK Null null_; // LINT core.Null core_null; // LINT - Future<void> future_void; // OK - Future<Null> future_null; // LINT - Future<core.Null> future_core_null; // LINT + Future<void>? future_void; // OK + Future<Null>? future_null; // LINT + Future<core.Null>? future_core_null; // LINT void void_f() {} // OK Null null_f() {} // LINT @@ -152,12 +154,12 @@ class AsMembers { void void_; // OK Null null_; // LINT core.Null core_null; // LINT - Future<void> future_void; // OK + Future<void>? future_void; // OK Future<Null> future_null; // LINT Future<core.Null> future_core_null; // LINT - future_void.then<Null>((_) {}); // LINT - future_void.then<void>((_) {}); // OK + future_void?.then<Null>((_) {}); // LINT + future_void?.then<void>((_) {}); // OK } parameterNamedNull(Object Null) { diff --git a/test_data/rules/unawaited_futures.dart b/test_data/rules/unawaited_futures.dart index 72067faa1..41688940c 100644 --- a/test_data/rules/unawaited_futures.dart +++ b/test_data/rules/unawaited_futures.dart @@ -6,7 +6,7 @@ import 'dart:async'; -Future fut() => null; +Future fut() => Future.value(0); foo1() { fut(); @@ -25,16 +25,17 @@ foo3() async { foo4() async { var x = fut(); + return x; } foo5() async { + Duration d = Duration(); new Future.delayed(d); //LINT - new Future.delayed(d, bar); } foo6() async { var map = <String, Future>{}; - map.putIfAbsent('foo', fut()); + map.putIfAbsent('foo', () => fut()); } foo7() async { @@ -57,12 +58,12 @@ foo9() async { foo10() async { _Foo() - ..futureListField[0] = fut(); + ..futureListField?[0] = fut(); } foo11() async { _Foo() - ..bar.futureField = fut(); + ..bar?.futureField = fut(); } foo12() async { @@ -71,13 +72,13 @@ foo12() async { } class _Bar { - Future<void> futureField; + Future<void>? futureField; } class _Foo { - Future<void> futureField; - List<Future<void>> futureListField; - _Bar bar; + Future<void>? futureField; + List<Future<void>>? futureListField = []; + _Bar? bar; Future<void> doAsync() async {} void doSync() => null; Future<void> get asyncProperty => doAsync(); @@ -85,9 +86,12 @@ class _Foo { } /// https://github.com/dart-lang/linter/issues/2211 -class Future2 extends Future {} +class Future2 implements Future { + @override + noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} -Future2 fut2() => null; +Future2 fut2() => Future2(); f2() async { fut2(); //LINT diff --git a/test_data/rules/unnecessary_getters_setters.dart b/test_data/rules/unnecessary_getters_setters.dart index 337bfc371..6484a7ec5 100644 --- a/test_data/rules/unnecessary_getters_setters.dart +++ b/test_data/rules/unnecessary_getters_setters.dart @@ -38,7 +38,7 @@ class Box3 { class Box4 { var _contents; - get contents { + int get contents { return _contents; } set contents(int value) // OK -- notice the type diff --git a/test_data/rules/unnecessary_statements.dart b/test_data/rules/unnecessary_statements.dart index ba2fc79f1..157046689 100644 --- a/test_data/rules/unnecessary_statements.dart +++ b/test_data/rules/unnecessary_statements.dart @@ -16,7 +16,7 @@ void constructorTearOffs() { String f(Object o) { // See: https://github.com/dart-lang/linter/issues/2163 o as int; // OK - return null; + return ''; } notReturned() { @@ -178,7 +178,7 @@ inOtherStatements() { bool someBool = true; bool foo() => true; get getter => true; -int field; +int field = 0; class MyClass { int field = 0;