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 9 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
27 changes: 25 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,29 @@ 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(
// ignore: deprecated_member_use
node.declaredElement2?.type.getDisplayString(withNullability: false),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a way to solve this without using deprecated APIs?
Also, this checks for exact match, not subtypes.

);
}
15 changes: 15 additions & 0 deletions lib/lints/avoid_late_keyword/models/_config_parser.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
part of 'avoid_late_keyword_parameters.dart';

class _ConfigParser {
static const _allowInitializedConfig = 'allow_initialized';
static const _ignoredTypesConfig = 'ignored_types';

static bool parseAllowInitialized(Map<String, Object?> config) =>
config[_allowInitializedConfig] as bool? ?? false;

static Iterable<String> parseIgnoredTypes(Map<String, Object?> config) =>
config.containsKey(_ignoredTypesConfig) &&
config[_ignoredTypesConfig] is Iterable
? List<String>.from(config[_ignoredTypesConfig] as Iterable)
: <String>['AnimationController'];
}
yurii-prykhodko-solid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
part '_config_parser.dart';

/// A data model class that represents the "avoid late keyword" input
/// parameters.
class AvoidLateKeywordParameters {
/// Allow to dynamically initialize
maxxlab marked this conversation as resolved.
Show resolved Hide resolved
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: _ConfigParser.parseAllowInitialized(json),
ignoredTypes: _ConfigParser.parseIgnoredTypes(json),
);
}
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
12 changes: 10 additions & 2 deletions lint_test/avoid_late_keyword_test.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
// 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`
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
Loading