From 88ef529e57098084deaa7d5739e4cb928ded1ef2 Mon Sep 17 00:00:00 2001 From: byshy <33957976+byshy@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:10:02 +0300 Subject: [PATCH 1/2] - Add prefer-first-or-null rule to the lint analyzers --- example/analysis_options.yaml | 1 + .../lint_analyzer/rules/rules_factory.dart | 2 + .../prefer_first_or_null_rule.dart | 65 ++++ .../prefer_first_or_null/visitor.dart | 48 +++ ...k_line_before_single_return_rule_test.dart | 2 +- .../examples/example.dart | 171 +++++++++++ .../prefer_first_or_null_rule_test.dart | 280 ++++++++++++++++++ 7 files changed, 568 insertions(+), 1 deletion(-) create mode 100644 lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart create mode 100644 lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/visitor.dart create mode 100644 test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart create mode 100644 test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 2a0615f7..fb6c9544 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -52,6 +52,7 @@ dart_code_linter: - avoid-unnecessary-type-casts - avoid-unused-parameters - newline-before-return + - prefer-first-or-null - no-blank-line-before-single-return - no-boolean-literal-compare - no-empty-block diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart b/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart index c8ac366b..ab2b08ff 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart @@ -63,6 +63,7 @@ import 'rules_list/prefer_define_hero_tag/prefer_define_hero_tag_rule.dart'; import 'rules_list/prefer_enums_by_name/prefer_enums_by_name_rule.dart'; import 'rules_list/prefer_extracting_callbacks/prefer_extracting_callbacks_rule.dart'; import 'rules_list/prefer_first/prefer_first_rule.dart'; +import 'rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart'; import 'rules_list/prefer_immediate_return/prefer_immediate_return_rule.dart'; import 'rules_list/prefer_intl_name/prefer_intl_name_rule.dart'; import 'rules_list/prefer_iterable_of/prefer_iterable_of_rule.dart'; @@ -132,6 +133,7 @@ final _implementedRules = )>{ MissingTestAssertionRule.ruleId: MissingTestAssertionRule.new, NewlineBeforeReturnRule.ruleId: NewlineBeforeReturnRule.new, NoBlankLineBeforeSingleReturnRule.ruleId: NoBlankLineBeforeSingleReturnRule.new, + PreferFirstOrNullRule.ruleId: PreferFirstOrNullRule.new, NoBooleanLiteralCompareRule.ruleId: NoBooleanLiteralCompareRule.new, NoEmptyBlockRule.ruleId: NoEmptyBlockRule.new, NoEqualArgumentsRule.ruleId: NoEqualArgumentsRule.new, diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart new file mode 100644 index 00000000..d902fe3c --- /dev/null +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart @@ -0,0 +1,65 @@ +// ignore_for_file: public_member_api_docs + +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/element/type.dart'; + +import '../../../../../utils/dart_types_utils.dart'; +import '../../../../../utils/node_utils.dart'; +import '../../../lint_utils.dart'; +import '../../../models/internal_resolved_unit_result.dart'; +import '../../../models/issue.dart'; +import '../../../models/replacement.dart'; +import '../../../models/severity.dart'; +import '../../models/dart_rule.dart'; +import '../../rule_utils.dart'; + +part 'visitor.dart'; + +class PreferFirstOrNullRule extends DartRule { + static const ruleId = 'prefer-first-or-null'; + static const warningMessage = 'Use first instead of accessing the element at zero index or using first.'; + static const replaceComment = "Replace with 'firstOrNull'."; + + PreferFirstOrNullRule([Map config = const {}]) + : super( + id: ruleId, + severity: readSeverity(config, Severity.style), + excludes: readExcludes(config), + includes: readIncludes(config), + ); + + @override + Iterable check(InternalResolvedUnitResult source) { + final visitor = _Visitor(); + source.unit.visitChildren(visitor); + + return visitor.expressions + .map((expression) => createIssue( + rule: this, + location: nodeLocation(node: expression, source: source), + message: warningMessage, + replacement: _createReplacement(expression), + )) + .toList(growable: false); + } + + Replacement _createReplacement(Expression expression) { + String replacement; + + if (expression is MethodInvocation) { + replacement = expression.isCascaded ? '..firstOrNull' : '${expression.target ?? ''}.firstOrNull'; + } else if (expression is IndexExpression) { + replacement = expression.isCascaded ? '..firstOrNull' : '${expression.target ?? ''}.firstOrNull'; + } else if (expression is PrefixedIdentifier) { + replacement = '${expression.prefix.token.lexeme}.firstOrNull'; + } else { + replacement = '.firstOrNull'; + } + + return Replacement( + comment: replaceComment, + replacement: replacement, + ); + } +} diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/visitor.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/visitor.dart new file mode 100644 index 00000000..67b0e56c --- /dev/null +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/visitor.dart @@ -0,0 +1,48 @@ +part of 'prefer_first_or_null_rule.dart'; + +class _Visitor extends RecursiveAstVisitor { + final _expressions = []; + + Iterable get expressions => _expressions; + + @override + void visitPrefixedIdentifier(PrefixedIdentifier node) { + super.visitPrefixedIdentifier(node); + + final targetType = node.prefix.staticType; + + if (node.identifier.name == 'first' && targetType is InterfaceType && isIterableOrSubclass(targetType)) { + _expressions.add(node); + } + } + + @override + void visitMethodInvocation(MethodInvocation node) { + super.visitMethodInvocation(node); + + if (isIterableOrSubclass(node.realTarget?.staticType)) { + if (node.methodName.name == 'elementAt') { + final arg = node.argumentList.arguments.first; + + if (arg is IntegerLiteral && arg.value == 0) { + _expressions.add(node); + } + } else if (node.methodName.name == 'first') { + _expressions.add(node); + } + } + } + + @override + void visitIndexExpression(IndexExpression node) { + super.visitIndexExpression(node); + + if (isListOrSubclass(node.realTarget.staticType)) { + final index = node.index; + + if (index is IntegerLiteral && index.value == 0) { + _expressions.add(node); + } + } + } +} diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/no_blank_line_before_single_return/no_blank_line_before_single_return_rule_test.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/no_blank_line_before_single_return/no_blank_line_before_single_return_rule_test.dart index e2e2433a..d4e94497 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_list/no_blank_line_before_single_return/no_blank_line_before_single_return_rule_test.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/no_blank_line_before_single_return/no_blank_line_before_single_return_rule_test.dart @@ -23,7 +23,7 @@ void main() { final unit = await RuleTestHelper.resolveFromFile(_examplePath); final issues = NoBlankLineBeforeSingleReturnRule().check(unit); - List startLines = [79, 85, 92, 100, 106, 113, 122]; + final startLines = [79, 85, 92, 100, 106, 113, 122]; RuleTestHelper.verifyIssues( issues: issues, diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart new file mode 100644 index 00000000..b183b38c --- /dev/null +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart @@ -0,0 +1,171 @@ +// ignore_for_file: unnecessary_cast, unused_local_variable + +import 'dart:collection'; + +const _array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + +void func() { + const iterable = _array as Iterable; + + final firstOfIterable = iterable.first; // LINT + final firstElementOfIterable = iterable.elementAt(0); // LINT + final secondElementOfIterable = iterable.elementAt(1); + + iterable + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + const list = _array; + + final firstOfList = list.first; // LINT + final firstElementOfList1 = list.elementAt(0); // LINT + final firstElementOfList2 = list[0]; // LINT + final secondElementOfList1 = list.elementAt(1); + final secondElementOfList2 = list[1]; + + list + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1) + ..[2] + ..[0] // LINT + ..[1]; + + (list + ..[2] + ..[0]) // LINT + .length; + + list + ..[2].toDouble() + ..[0].toDouble(); // LINT + +//////////////////////////////////////////////////////////////////////////////// + + final set = _array.toSet(); + + final firstOfSet = set.first; // LINT + final firstElementOfSet = set.elementAt(0); // LINT + final secondElementOfSet = set.elementAt(1); + + set + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + final doubleLinkedQueue = DoubleLinkedQueue.of(_array); + + final firstOfDoubleLinkedQueue = doubleLinkedQueue.first; // LINT + final firstElementOfDoubleLinkedQueue = + doubleLinkedQueue.elementAt(0); // LINT + final secondElementOfDoubleLinkedQueue = doubleLinkedQueue.elementAt(1); + + doubleLinkedQueue + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + final hashSet = HashSet.of(_array); + + final firstOfHashSet = hashSet.first; // LINT + final firstElementOfHashSet = hashSet.elementAt(0); // LINT + final secondElementOfHashSet = hashSet.elementAt(1); + + hashSet + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + final linkedHashSet = LinkedHashSet.of(_array); + + final firstOfLinkedHashSet = linkedHashSet.first; // LINT + final firstElementOfLinkedHashSet = linkedHashSet.elementAt(0); // LINT + final secondElementOfLinkedHashSet = linkedHashSet.elementAt(1); + + linkedHashSet + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + final listQueue = ListQueue.of(_array); + + final firstOfListQueue = listQueue.first; // LINT + final firstElementOfListQueue = listQueue.elementAt(0); // LINT + final secondElementOfListQueue = listQueue.elementAt(1); + + listQueue + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + final queue = Queue.of(_array); + + final firstOfQueue = queue.first; // LINT + final firstElementOfQueue = queue.elementAt(0); // LINT + final secondElementOfQueue = queue.elementAt(1); + + queue + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + final splayTreeSet = SplayTreeSet.of(_array); + + final firstOfSplayTreeSet = splayTreeSet.first; // LINT + final firstElementOfSplayTreeSet = splayTreeSet.elementAt(0); // LINT + final secondElementOfSplayTreeSet = splayTreeSet.elementAt(1); + + splayTreeSet + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); + +//////////////////////////////////////////////////////////////////////////////// + + final unmodifiableListView = UnmodifiableListView(_array); + + final firstOfUnmodifiableListView = unmodifiableListView.first; // LINT + final firstElementOfUnmodifiableListView1 = + unmodifiableListView.elementAt(0); // LINT + final firstElementOfUnmodifiableListView2 = unmodifiableListView[0]; // LINT + final secondElementOfUnmodifiableListView1 = + unmodifiableListView.elementAt(1); + final secondElementOfUnmodifiableListView2 = unmodifiableListView[1]; + + unmodifiableListView + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1) + ..[2] + ..[0] // LINT + ..[1]; + +//////////////////////////////////////////////////////////////////////////////// + + final unmodifiableSetView = UnmodifiableSetView(_array.toSet()); + + final firstOfUnmodifiableSetView = unmodifiableSetView.first; // LINT + final firstElementOfUnmodifiableSetView = + unmodifiableSetView.elementAt(0); // LINT + final secondElementOfUnmodifiableSetView = unmodifiableSetView.elementAt(1); + + unmodifiableSetView + ..elementAt(2) + ..elementAt(0) // LINT + ..elementAt(1); +} diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart new file mode 100644 index 00000000..50ae32b6 --- /dev/null +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart @@ -0,0 +1,280 @@ +import 'package:dart_code_linter/src/analyzers/lint_analyzer/models/severity.dart'; +import 'package:dart_code_linter/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart'; +import 'package:test/test.dart'; + +import '../../../../../helpers/rule_test_helper.dart'; + +const _examplePath = 'prefer_first_or_null/examples/example.dart'; + +void main() { + group( + 'PreferFirstOrNullRule', + () { + test('initialization', () async { + final unit = await RuleTestHelper.resolveFromFile(_examplePath); + final issues = PreferFirstOrNullRule().check(unit); + + RuleTestHelper.verifyInitialization( + issues: issues, + ruleId: PreferFirstOrNullRule.ruleId, + severity: Severity.style, + ); + }); + + test('reports about found issues', () async { + final unit = await RuleTestHelper.resolveFromFile(_examplePath); + final issues = PreferFirstOrNullRule().check(unit); + + RuleTestHelper.verifyIssues( + issues: issues, + startLines: [ + 10, + 11, + 16, + 23, + 24, + 25, + 31, + 34, + 39, + 44, + 50, + 51, + 56, + 63, + 65, + 70, + 77, + 78, + 83, + 90, + 91, + 96, + 103, + 104, + 109, + 116, + 117, + 122, + 129, + 130, + 135, + 142, + 144, + 145, + 152, + 155, + 162, + 164, + 169, + ], + startColumns: [ + 27, + 34, + 5, + 23, + 31, + 31, + 5, + 5, + 9, + 5, + 22, + 29, + 5, + 36, + 7, + 5, + 26, + 33, + 5, + 32, + 39, + 5, + 28, + 35, + 5, + 24, + 31, + 5, + 31, + 38, + 5, + 39, + 7, + 47, + 5, + 5, + 38, + 7, + 5, + ], + messages: [ + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + PreferFirstOrNullRule.warningMessage, + ], + replacementComments: [ + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + PreferFirstOrNullRule.replaceComment, + ], + replacements: [ + 'iterable.firstOrNull', + 'iterable.firstOrNull', + '..firstOrNull', + 'list.firstOrNull', + 'list.firstOrNull', + 'list.firstOrNull', + '..firstOrNull', + '..firstOrNull', + '..firstOrNull', + '..firstOrNull', + 'set.firstOrNull', + 'set.firstOrNull', + '..firstOrNull', + 'doubleLinkedQueue.firstOrNull', + 'doubleLinkedQueue.firstOrNull', + '..firstOrNull', + 'hashSet.firstOrNull', + 'hashSet.firstOrNull', + '..firstOrNull', + 'linkedHashSet.firstOrNull', + 'linkedHashSet.firstOrNull', + '..firstOrNull', + 'listQueue.firstOrNull', + 'listQueue.firstOrNull', + '..firstOrNull', + 'queue.firstOrNull', + 'queue.firstOrNull', + '..firstOrNull', + 'splayTreeSet.firstOrNull', + 'splayTreeSet.firstOrNull', + '..firstOrNull', + 'unmodifiableListView.firstOrNull', + 'unmodifiableListView.firstOrNull', + 'unmodifiableListView.firstOrNull', + '..firstOrNull', + '..firstOrNull', + 'unmodifiableSetView.firstOrNull', + 'unmodifiableSetView.firstOrNull', + '..firstOrNull', + ], + locationTexts: [ + 'iterable.first', + 'iterable.elementAt(0)', + '..elementAt(0)', + 'list.first', + 'list.elementAt(0)', + 'list[0]', + '..elementAt(0)', + '..[0]', + '..[0]', + '..[0]', + 'set.first', + 'set.elementAt(0)', + '..elementAt(0)', + 'doubleLinkedQueue.first', + 'doubleLinkedQueue.elementAt(0)', + '..elementAt(0)', + 'hashSet.first', + 'hashSet.elementAt(0)', + '..elementAt(0)', + 'linkedHashSet.first', + 'linkedHashSet.elementAt(0)', + '..elementAt(0)', + 'listQueue.first', + 'listQueue.elementAt(0)', + '..elementAt(0)', + 'queue.first', + 'queue.elementAt(0)', + '..elementAt(0)', + 'splayTreeSet.first', + 'splayTreeSet.elementAt(0)', + '..elementAt(0)', + 'unmodifiableListView.first', + 'unmodifiableListView.elementAt(0)', + 'unmodifiableListView[0]', + '..elementAt(0)', + '..[0]', + 'unmodifiableSetView.first', + 'unmodifiableSetView.elementAt(0)', + '..elementAt(0)', + ], + ); + }); + }, + ); +} From d6c6fdb6d9b7ec38d3aadd3cd81d69d0b2355e04 Mon Sep 17 00:00:00 2001 From: byshy <33957976+byshy@users.noreply.github.com> Date: Wed, 6 Nov 2024 08:49:47 +0200 Subject: [PATCH 2/2] - Edit the PreferFirstOrNull rule warning message - Use the firstOrNull in the test example --- .../prefer_first_or_null_rule.dart | 2 +- .../examples/example.dart | 24 ++++++++ .../prefer_first_or_null_rule_test.dart | 60 +++++++++---------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart index d902fe3c..b4563263 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule.dart @@ -18,7 +18,7 @@ part 'visitor.dart'; class PreferFirstOrNullRule extends DartRule { static const ruleId = 'prefer-first-or-null'; - static const warningMessage = 'Use first instead of accessing the element at zero index or using first.'; + static const warningMessage = 'Use firstOrNull instead of accessing the element at zero index or using first.'; static const replaceComment = "Replace with 'firstOrNull'."; PreferFirstOrNullRule([Map config = const {}]) diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart index b183b38c..1f53be3f 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/examples/example.dart @@ -8,10 +8,12 @@ void func() { const iterable = _array as Iterable; final firstOfIterable = iterable.first; // LINT + final firstOrNullOfIterable = iterable.firstOrNull; final firstElementOfIterable = iterable.elementAt(0); // LINT final secondElementOfIterable = iterable.elementAt(1); iterable + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -21,12 +23,14 @@ void func() { const list = _array; final firstOfList = list.first; // LINT + final firstOrNullOfList = list.firstOrNull; final firstElementOfList1 = list.elementAt(0); // LINT final firstElementOfList2 = list[0]; // LINT final secondElementOfList1 = list.elementAt(1); final secondElementOfList2 = list[1]; list + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1) @@ -35,11 +39,13 @@ void func() { ..[1]; (list + ..firstOrNull ..[2] ..[0]) // LINT .length; list + ..firstOrNull ..[2].toDouble() ..[0].toDouble(); // LINT @@ -48,10 +54,12 @@ void func() { final set = _array.toSet(); final firstOfSet = set.first; // LINT + final firstOrNullOfSet = set.firstOrNull; final firstElementOfSet = set.elementAt(0); // LINT final secondElementOfSet = set.elementAt(1); set + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -61,11 +69,13 @@ void func() { final doubleLinkedQueue = DoubleLinkedQueue.of(_array); final firstOfDoubleLinkedQueue = doubleLinkedQueue.first; // LINT + final firstOrNullOfDoubleLinkedQueue = doubleLinkedQueue.firstOrNull; final firstElementOfDoubleLinkedQueue = doubleLinkedQueue.elementAt(0); // LINT final secondElementOfDoubleLinkedQueue = doubleLinkedQueue.elementAt(1); doubleLinkedQueue + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -75,10 +85,12 @@ void func() { final hashSet = HashSet.of(_array); final firstOfHashSet = hashSet.first; // LINT + final firstOrNullOfHashSet = hashSet.firstOrNull; final firstElementOfHashSet = hashSet.elementAt(0); // LINT final secondElementOfHashSet = hashSet.elementAt(1); hashSet + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -88,10 +100,12 @@ void func() { final linkedHashSet = LinkedHashSet.of(_array); final firstOfLinkedHashSet = linkedHashSet.first; // LINT + final firstOrNullOfLinkedHashSet = linkedHashSet.firstOrNull; final firstElementOfLinkedHashSet = linkedHashSet.elementAt(0); // LINT final secondElementOfLinkedHashSet = linkedHashSet.elementAt(1); linkedHashSet + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -101,10 +115,12 @@ void func() { final listQueue = ListQueue.of(_array); final firstOfListQueue = listQueue.first; // LINT + final firstOrNullOfListQueue = listQueue.firstOrNull; final firstElementOfListQueue = listQueue.elementAt(0); // LINT final secondElementOfListQueue = listQueue.elementAt(1); listQueue + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -114,10 +130,12 @@ void func() { final queue = Queue.of(_array); final firstOfQueue = queue.first; // LINT + final firstOrNullOfQueue = queue.firstOrNull; final firstElementOfQueue = queue.elementAt(0); // LINT final secondElementOfQueue = queue.elementAt(1); queue + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -127,10 +145,12 @@ void func() { final splayTreeSet = SplayTreeSet.of(_array); final firstOfSplayTreeSet = splayTreeSet.first; // LINT + final firstOrNullOfSplayTreeSet = splayTreeSet.firstOrNull; final firstElementOfSplayTreeSet = splayTreeSet.elementAt(0); // LINT final secondElementOfSplayTreeSet = splayTreeSet.elementAt(1); splayTreeSet + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); @@ -140,6 +160,7 @@ void func() { final unmodifiableListView = UnmodifiableListView(_array); final firstOfUnmodifiableListView = unmodifiableListView.first; // LINT + final firstOrNullOfUnmodifiableListView = unmodifiableListView.firstOrNull; final firstElementOfUnmodifiableListView1 = unmodifiableListView.elementAt(0); // LINT final firstElementOfUnmodifiableListView2 = unmodifiableListView[0]; // LINT @@ -148,6 +169,7 @@ void func() { final secondElementOfUnmodifiableListView2 = unmodifiableListView[1]; unmodifiableListView + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1) @@ -160,11 +182,13 @@ void func() { final unmodifiableSetView = UnmodifiableSetView(_array.toSet()); final firstOfUnmodifiableSetView = unmodifiableSetView.first; // LINT + final firstOrNullOfUnmodifiableSetView = unmodifiableSetView.firstOrNull; final firstElementOfUnmodifiableSetView = unmodifiableSetView.elementAt(0); // LINT final secondElementOfUnmodifiableSetView = unmodifiableSetView.elementAt(1); unmodifiableSetView + ..firstOrNull ..elementAt(2) ..elementAt(0) // LINT ..elementAt(1); diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart index 50ae32b6..075c97ee 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/prefer_first_or_null/prefer_first_or_null_rule_test.dart @@ -29,44 +29,44 @@ void main() { issues: issues, startLines: [ 10, - 11, - 16, - 23, - 24, + 12, + 18, 25, - 31, - 34, - 39, + 27, + 28, + 35, + 38, 44, 50, - 51, 56, - 63, - 65, - 70, - 77, - 78, - 83, - 90, - 91, - 96, - 103, + 58, + 64, + 71, + 74, + 80, + 87, + 89, + 95, + 102, 104, - 109, - 116, + 110, 117, - 122, - 129, - 130, - 135, - 142, - 144, - 145, - 152, + 119, + 125, + 132, + 134, + 140, + 147, + 149, 155, 162, - 164, - 169, + 165, + 166, + 174, + 177, + 184, + 187, + 193, ], startColumns: [ 27,