Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix avoid-late if initialized #71

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
da4b854
Fix avoid-late if initialized
maxxlab Nov 15, 2023
f5f5bf2
Update lint_test/avoid_late_keyword_test.dart
maxxlab Nov 15, 2023
e34f822
Apply suggestions from code review
maxxlab Nov 15, 2023
2633fc9
Custom avoid-late
maxxlab Nov 15, 2023
f5a4a81
Fix naming
maxxlab Nov 15, 2023
78eef07
Apply suggestions from code review
maxxlab Nov 15, 2023
8aeeeb2
Avoid late simplified
maxxlab Nov 15, 2023
13b5e61
Update lib/lints/avoid_late_keyword/models/avoid_late_keyword_paramet…
maxxlab Nov 15, 2023
83629fe
Avoid-late ignored_types
maxxlab Nov 16, 2023
13a6d16
Avoid-late ignored_types formatted
maxxlab Nov 16, 2023
56abdb6
Update lib/lints/avoid_late_keyword/models/avoid_late_keyword_paramet…
maxxlab Nov 16, 2023
6315eca
Avoid-late ignored_types fix
maxxlab Nov 16, 2023
78246e9
Merge branch 'avoid_late_feature' of https://github.com/maxxlab/solid…
maxxlab Nov 16, 2023
dbd6bdf
Avoid-late ignored_types Fix
maxxlab Nov 16, 2023
d215871
Avoid-late allow_initialized testcases
maxxlab Nov 16, 2023
f639d91
Update lint_test/avoid_late_keyword_allow_initialized_test/pubspec.yaml
maxxlab Nov 16, 2023
850cfaa
Update lib/lints/avoid_late_keyword/models/avoid_late_keyword_paramet…
maxxlab Nov 16, 2023
b426d49
Allow subclasses for avoid-late whitelist
solid-yuriiprykhodko Nov 16, 2023
b023b8c
Fix naming
solid-yuriiprykhodko Nov 16, 2023
b4fe907
Merge pull request #1 from yurii-prykhodko-solid/ignore-late-subclasses
maxxlab Nov 16, 2023
662dc49
Short-circuit of there's no ignored types
solid-yuriiprykhodko Nov 16, 2023
41fe9ab
Short-circuit earlier
solid-yuriiprykhodko Nov 16, 2023
8167c07
Merge pull request #2 from yurii-prykhodko-solid/ignore-late-subclasses
maxxlab Nov 16, 2023
fbf2270
Update lib/lints/avoid_late_keyword/avoid_late_keyword_rule.dart
maxxlab Nov 17, 2023
2037550
Avoid-late ignored_types tests
maxxlab Nov 17, 2023
e3a85fa
Merge branch 'avoid_late_feature' of https://github.com/maxxlab/solid…
maxxlab Nov 17, 2023
bb69baa
Avoid-late add testcases
maxxlab Nov 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions lib/lints/avoid_late_keyword/avoid_late_keyword_rule.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/listener.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';
import 'package:solid_lints/lints/avoid_late_keyword/models/avoid_late_keyword_parameters.dart';
import 'package:solid_lints/models/rule_config.dart';
import 'package:solid_lints/models/solid_lint_rule.dart';

/// A `late` keyword rule which forbids using it to avoid runtime exceptions.
class AvoidLateKeywordRule extends SolidLintRule {
class AvoidLateKeywordRule extends SolidLintRule<AvoidLateKeywordParameters> {
/// The [LintCode] of this lint rule that represents
/// the error whether we use `late` keyword.
static const lintName = 'avoid_late_keyword';
Expand All @@ -17,6 +19,7 @@ class AvoidLateKeywordRule extends SolidLintRule {
final rule = RuleConfig(
configs: configs,
name: lintName,
paramsParser: AvoidLateKeywordParameters.fromJson,
problemMessage: (_) => 'Avoid using the "late" keyword. '
'It may result in runtime exceptions.',
);
Expand All @@ -31,9 +34,28 @@ class AvoidLateKeywordRule extends SolidLintRule {
CustomLintContext context,
) {
context.registry.addVariableDeclaration((node) {
if (node.declaredElement?.isLate ?? false) {
if (_shouldLint(node)) {
reporter.reportErrorForNode(code, node);
}
});
}

bool _shouldLint(VariableDeclaration node) {
final isLateDeclaration = node.declaredElement?.isLate ?? false;
if (!isLateDeclaration) return false;

final ignoredTypes = _hasIgnoredType(node);
if (ignoredTypes) return false;
maxxlab marked this conversation as resolved.
Show resolved Hide resolved

final allowInitialized = config.parameters.allowInitialized;
if (!allowInitialized) return true;

final hasInitializer = node.initializer != null;
return !hasInitializer;
}
yurii-prykhodko-solid marked this conversation as resolved.
Show resolved Hide resolved

bool _hasIgnoredType(VariableDeclaration node) =>
config.parameters.ignoredTypes.contains(
(node.parent! as VariableDeclarationList).type?.toSource() ?? '',
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/// A data model class that represents the "avoid late keyword" input
/// parameters.
class AvoidLateKeywordParameters {
/// Allow immediately initialised late variables.
///
/// ```dart
/// late var ok = 0; // ok when allowInitialized == true
/// late var notOk; // initialized elsewhere, not allowed
/// ```
final bool allowInitialized;

/// Types that would be ignored by avoid-late rule
final Iterable<String> ignoredTypes;

/// Constructor for [AvoidLateKeywordParameters] model
const AvoidLateKeywordParameters({
this.allowInitialized = false,
this.ignoredTypes = const [],
});

/// Method for creating from json data
factory AvoidLateKeywordParameters.fromJson(Map<String, Object?> json) =>
AvoidLateKeywordParameters(
allowInitialized: json['allow_initialized'] as bool? ?? false,
ignoredTypes: json['ignored_types'] as List<String>?,
);
}
6 changes: 5 additions & 1 deletion lint_test/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ custom_lint:
- function_lines_of_code:
max_lines: 50
- avoid_non_null_assertion
- avoid_late_keyword
- avoid_late_keyword:
allow_initialized: true
ignored_types:
- ColorTween
- AnimationController
- avoid_global_state
- avoid_returning_widgets
- avoid_unnecessary_setstate
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
analyzer:
plugins:
- ../custom_lint

custom_lint:
rules:
- avoid_late_keyword:
allow_initialized: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// ignore_for_file: prefer_const_declarations, unused_local_variable, prefer_match_file_name
// ignore_for_file: avoid_global_state

import 'package:flutter/material.dart';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove Flutter SDK dependency.


/// Check "late" keyword fail
///
/// `avoid_late_keyword`
/// allow_initialized option disabled
class AvoidLateKeyword {
/// expect_lint: avoid_late_keyword
late final ColorTween colorTween;

late final AnimationController controller1;

/// expect_lint: avoid_late_keyword
late final field1 = 'string';

/// expect_lint: avoid_late_keyword
late String field2;

void test() {
/// expect_lint: avoid_late_keyword
late final ColorTween colorTween;

late final AnimationController controller2;

/// expect_lint: avoid_late_keyword
late final field3 = 'string';

/// expect_lint: avoid_late_keyword
late String field4;
}
}
13 changes: 13 additions & 0 deletions lint_test/avoid_late_keyword_allow_initialized_test/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: avoid_late_keyword_allow_initialized_test
publish_to: none

environment:
sdk: '>=3.0.0 <4.0.0'

dependencies:
flutter:
sdk: flutter
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can declare your own classes with same names for test purpose instead of pulling in the entire Flutter SDK as a dependency. See https://github.com/solid-software/solid_lints/pull/74/files#diff-f77bef8e8287cf15cac0245e3c6046109cd594bb0238e8bb61c991070521ab47

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
flutter:
sdk: flutter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I did it yesterday but create PR only today


dev_dependencies:
solid_lints:
path: ../../
13 changes: 11 additions & 2 deletions lint_test/avoid_late_keyword_test.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
// ignore_for_file: prefer_const_declarations, unused_local_variable, prefer_match_file_name
// ignore_for_file: avoid_global_state

import 'package:flutter/material.dart';

/// Check "late" keyword fail
///
/// `avoid_late_keyword`
/// allow_initialized option enabled
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also test allow_initialized == false + ignored types.

class AvoidLateKeyword {
/// expect_lint: avoid_late_keyword
late final ColorTween colorTween;

late final AnimationController controller1;

late final field1 = 'string';

/// expect_lint: avoid_late_keyword
late String field2;

void test() {
/// expect_lint: avoid_late_keyword
late final ColorTween colorTween;

late final AnimationController controller2;

late final field3 = 'string';

/// expect_lint: avoid_late_keyword
Expand Down