Skip to content
Open
45 changes: 28 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
## 1.0.0

- feat!: migrate to analyzer_server_plugin
- refactor: replace `avoid_unnecessary_type_casts` rule with dart analyzer's `unnecessary_cast`
- refactor: replace `avoid_unnecessary_type_casts` rule with dart analyzer's
`unnecessary_cast`
- Added `use_nearest_context` rule.
- Added `use_descriptive_names_for_type_parameters` rule.

## 0.3.3

Expand All @@ -17,9 +19,9 @@

- Added `allow_with_comments` parameter for `no_empty_block` lint.
- Added extension support for `avoid_using_api`
- Added `exclude_entity` parameter for `prefer_match_file_name` lint.
It is now possible to configure this lint to ignore `enum`,
`extension` and `mixin` declarations via `analysis_options.yaml`.
- Added `exclude_entity` parameter for `prefer_match_file_name` lint. It is now
possible to configure this lint to ignore `enum`, `extension` and `mixin`
declarations via `analysis_options.yaml`.

## 0.3.0

Expand All @@ -30,7 +32,8 @@
- `function_lines_of_code`
- `no_empty_bloc`
- `number_of_parameters`
- BREAKING CHANGE: Renamed `excludeNames` parameter to `exclude` for `function_lines_of_code` lint.
- BREAKING CHANGE: Renamed `excludeNames` parameter to `exclude` for
`function_lines_of_code` lint.
- Fixed an issue with `prefer_early_retrun` for throw expression
- `number_of_parameters` lint: added `copyWith` to the default exclude list.
- Update dependencies:
Expand All @@ -53,28 +56,36 @@
## 0.2.0

- Added `avoid_final_with_getter` rule
- Improve `avoid_late_keyword` - `ignored_types` to support ignoring subtype of the node type (<https://github.com/solid-software/solid_lints/issues/157>)
- Abstract methods should be omitted by `proper_super_calls` (<https://github.com/solid-software/solid_lints/issues/159>)
- Add a rule prefer_guard_clause for reversing nested if statements (<https://github.com/solid-software/solid_lints/issues/91>)
- add exclude params support to avoid_returning_widgets rule (<https://github.com/solid-software/solid_lints/issues/131>)
- add quick fix to avoid_final_with_getter (<https://github.com/solid-software/solid_lints/pull/164>)
- Improve `avoid_late_keyword` - `ignored_types` to support ignoring subtype of
the node type (<https://github.com/solid-software/solid_lints/issues/157>)
- Abstract methods should be omitted by `proper_super_calls`
(<https://github.com/solid-software/solid_lints/issues/159>)
- Add a rule prefer_guard_clause for reversing nested if statements
(<https://github.com/solid-software/solid_lints/issues/91>)
- add exclude params support to avoid_returning_widgets rule
(<https://github.com/solid-software/solid_lints/issues/131>)
- add quick fix to avoid_final_with_getter
(<https://github.com/solid-software/solid_lints/pull/164>)
- Renamed `avoid_debug_print` to `avoid_debug_print_in_release`
- The `avoid_debug_print_in_release` no longer reports a warning if the `debugPrint` call is wrapped in a `!kReleaseMode` check.
- The `avoid_debug_print_in_release` no longer reports a warning if the
`debugPrint` call is wrapped in a `!kReleaseMode` check.
- Update custom_lints to work with newer Flutter

## 0.1.5

- Added `avoid_debug_print` rule
- Fixed an issue with no_magic_number lint
- Fixed `avoid_unused_parameters` to report positional parameters from typedef if their name are not underscores.
- Fixed `avoid_unused_parameters` to report positional parameters from typedef
if their name are not underscores.
- Improvement for `avoid_returning_widget` lint:
- ignores methods that override ones that return widget (build() for example)
- no longer allows returning widgets from methods/functions named build
- Fixed unexpected avoid_unnecessary_type_assertions
- Added `excludeNames` param for `function_lines_of_code` lint
- Improved `avoid_unrelated_type_assertions` to support true and false results
- Set default `cyclomatic_complexity` to 10 (<https://github.com/solid-software/solid_lints/issues/146>)
Credits: Arthur Miranda (<https://github.com/arthurbcd>)
- Set default `cyclomatic_complexity` to 10
(<https://github.com/solid-software/solid_lints/issues/146>) Credits: Arthur
Miranda (<https://github.com/arthurbcd>)

## 0.1.4

Expand Down Expand Up @@ -108,8 +119,7 @@
- avoid_unnecessary_type_casts
- avoid_unrelated_type_assertions
- avoid_unused_parameters
- avoid_using_api
Credits: getBoolean (<https://github.com/getBoolean>)
- avoid_using_api Credits: getBoolean (<https://github.com/getBoolean>)
- cyclomatic_complexity
- double_literal_format
- function_lines_of_code
Expand Down Expand Up @@ -176,7 +186,8 @@

## 0.0.13

- enable use_colored_box & use_decorated_box + add more comments about specific lints
- enable use_colored_box & use_decorated_box + add more comments about specific
lints

## 0.0.12

Expand Down
1 change: 1 addition & 0 deletions lib/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ solid_lints:
proper_super_calls: true
named_parameters_ordering: true
use_nearest_context: true
use_descriptive_names_for_type_parameters: true

linter:
rules:
Expand Down
4 changes: 4 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import 'package:solid_lints/src/lints/prefer_first/prefer_first_rule.dart';
import 'package:solid_lints/src/lints/prefer_last/fixes/prefer_last_fix.dart';
import 'package:solid_lints/src/lints/prefer_last/prefer_last_rule.dart';
import 'package:solid_lints/src/lints/proper_super_calls/proper_super_calls_rule.dart';
import 'package:solid_lints/src/lints/use_descriptive_names_for_type_parameters/use_descriptive_names_for_type_parameters_rule.dart';
import 'package:solid_lints/src/lints/use_nearest_context/fixes/rename_nearest_context_parameter_fix.dart';
import 'package:solid_lints/src/lints/use_nearest_context/use_nearest_context_rule.dart';

Expand Down Expand Up @@ -80,6 +81,9 @@ class SolidLintsPlugin extends Plugin {
CyclomaticComplexityRule(analysisOptionsLoader: analysisLoader),
NoEmptyBlockRule(analysisOptionsLoader: analysisLoader),
UseNearestContextRule(),
UseDescriptiveNamesForTypeParametersRule(
analysisOptionsLoader: analysisLoader,
),
NoMagicNumberRule(analysisOptionsLoader: analysisLoader),
preferFirstRule,
preferConditionalExpressionsRule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// A data model class that represents the
/// "use descriptive names for type parameters" input parameters.
class UseDescriptiveNamesForTypeParametersParameters {
static const _defaultMinTypeParameters = 3;

/// Minimum number of type parameters required before the rule is enforced.
final int minTypeParameters;

/// Constructor for [UseDescriptiveNamesForTypeParametersParameters] model
const UseDescriptiveNamesForTypeParametersParameters({
required this.minTypeParameters,
});

/// Empty [UseDescriptiveNamesForTypeParametersParameters] model.
factory UseDescriptiveNamesForTypeParametersParameters.empty() {
return const UseDescriptiveNamesForTypeParametersParameters(
minTypeParameters: _defaultMinTypeParameters,
);
}

/// Method for creating from json data.
factory UseDescriptiveNamesForTypeParametersParameters.fromJson(
Map<String, Object?> json,
) => UseDescriptiveNamesForTypeParametersParameters(
minTypeParameters:
json['min_type_parameters'] as int? ?? _defaultMinTypeParameters,
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'package:analyzer/analysis_rule/rule_context.dart';
import 'package:analyzer/analysis_rule/rule_visitor_registry.dart';
import 'package:analyzer/error/error.dart';
import 'package:solid_lints/src/lints/use_descriptive_names_for_type_parameters/models/use_descriptive_names_for_type_parameters_parameters.dart';
import 'package:solid_lints/src/lints/use_descriptive_names_for_type_parameters/visitors/use_descriptive_names_for_type_parameters_visitor.dart';
import 'package:solid_lints/src/models/solid_lint_rule.dart';

/// A `use_descriptive_names_for_type_parameters` rule which
/// warns about single-letter type parameter names when there are
/// three or more type parameters.
///
/// ### Example:
///
/// Assuming config:
///
/// ```yaml
/// plugins:
/// solid_lints:
/// diagnostics:
/// use_descriptive_names_for_type_parameters:
/// min_type_parameters: 3
/// ```
///
/// #### BAD:
/// ```dart
/// class MyClass<T, U, V> {} // LINT
/// ```
///
/// #### GOOD:
/// ```dart
/// class MyClass<TSource, TResult, TError> {} // OK
/// class MyClass2<T, U> {} // OK
/// ```
class UseDescriptiveNamesForTypeParametersRule
extends SolidLintRule<UseDescriptiveNamesForTypeParametersParameters> {
/// The lint rule name.
static const lintName = 'use_descriptive_names_for_type_parameters';

static const _code = LintCode(
lintName,
'Type parameters should have descriptive names instead '
'of single letters when there are {0} or '
'more type parameters.',
);

@override
DiagnosticCode get diagnosticCode => _code;

/// Creates a new instance of [UseDescriptiveNamesForTypeParametersRule].
UseDescriptiveNamesForTypeParametersRule({
required super.analysisOptionsLoader,
}) : super.withParameters(
name: lintName,
description:
'Warns about single-letter type parameter names when there are '
'three or more type parameters.',
parametersParser:
UseDescriptiveNamesForTypeParametersParameters.fromJson,
);

@override
void registerNodeProcessors(
RuleVisitorRegistry registry,
RuleContext context,
) {
super.registerNodeProcessors(registry, context);

final parameters =
getParametersForContext(context) ??
UseDescriptiveNamesForTypeParametersParameters.empty();

final visitor = UseDescriptiveNamesForTypeParametersVisitor(
this,
parameters,
);

registry.addClassDeclaration(this, visitor);
registry.addClassTypeAlias(this, visitor);
registry.addEnumDeclaration(this, visitor);
registry.addFunctionExpression(this, visitor);
registry.addMethodDeclaration(this, visitor);
registry.addGenericTypeAlias(this, visitor);
registry.addFunctionTypeAlias(this, visitor);
registry.addGenericFunctionType(this, visitor);
registry.addExtensionDeclaration(this, visitor);
registry.addMixinDeclaration(this, visitor);
registry.addExtensionTypeDeclaration(this, visitor);
Comment on lines +77 to +87

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
registry.addClassDeclaration(this, visitor);
registry.addClassTypeAlias(this, visitor);
registry.addEnumDeclaration(this, visitor);
registry.addFunctionExpression(this, visitor);
registry.addMethodDeclaration(this, visitor);
registry.addGenericTypeAlias(this, visitor);
registry.addFunctionTypeAlias(this, visitor);
registry.addGenericFunctionType(this, visitor);
registry.addExtensionDeclaration(this, visitor);
registry.addMixinDeclaration(this, visitor);
registry.addExtensionTypeDeclaration(this, visitor);
registry
..addClassDeclaration(this, visitor)
..addClassTypeAlias(this, visitor)
..addEnumDeclaration(this, visitor)
..addFunctionExpression(this, visitor)
..addMethodDeclaration(this, visitor)
..addGenericTypeAlias(this, visitor)
..addFunctionTypeAlias(this, visitor)
..addGenericFunctionType(this, visitor)
..addExtensionDeclaration(this, visitor)
..addMixinDeclaration(this, visitor)
..addExtensionTypeDeclaration(this, visitor);

}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Could be a bit shorter:

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:solid_lints/src/lints/use_descriptive_names_for_type_parameters/models/use_descriptive_names_for_type_parameters_parameters.dart';
import 'package:solid_lints/src/lints/use_descriptive_names_for_type_parameters/use_descriptive_names_for_type_parameters_rule.dart';

/// A visitor that checks descriptive names for type parameters on declarations.
class UseDescriptiveNamesForTypeParametersVisitor
    extends SimpleAstVisitor<void> {
  final UseDescriptiveNamesForTypeParametersRule _rule;
  final UseDescriptiveNamesForTypeParametersParameters _parameters;

  int get _minParameters => _parameters.minTypeParameters;

  /// Creates a new instance of [UseDescriptiveNamesForTypeParametersVisitor].
  UseDescriptiveNamesForTypeParametersVisitor(this._rule, this._parameters);

  void _visit(TypeParameterList? types) {
    if (types case TypeParameterList(
      typeParameters: final ps,
    ) when ps.length < _minParameters) {
      ps.where(_hasInvalidShortName).forEach(_report);
    }
  }

  bool _hasInvalidShortName(TypeParameter p) =>
      p.name.length == 1 && p.name.lexeme != '_';

  void _report(TypeParameter p) =>
      _rule.reportAtNode(p, arguments: ['$_minParameters']);

  @override
  void visitClassDeclaration(ClassDeclaration node) =>
      _visit(node.namePart.typeParameters);

  @override
  void visitClassTypeAlias(ClassTypeAlias node) => _visit(node.typeParameters);

  @override
  void visitEnumDeclaration(EnumDeclaration node) =>
      _visit(node.namePart.typeParameters);

  @override
  void visitFunctionExpression(FunctionExpression node) =>
      _visit(node.typeParameters);

  @override
  void visitMethodDeclaration(MethodDeclaration node) =>
      _visit(node.typeParameters);

  @override
  void visitGenericTypeAlias(GenericTypeAlias node) =>
      _visit(node.typeParameters);

  @override
  void visitFunctionTypeAlias(FunctionTypeAlias node) =>
      _visit(node.typeParameters);

  @override
  void visitGenericFunctionType(GenericFunctionType node) =>
      _visit(node.typeParameters);

  @override
  void visitExtensionDeclaration(ExtensionDeclaration node) =>
      _visit(node.typeParameters);

  @override
  void visitMixinDeclaration(MixinDeclaration node) =>
      _visit(node.typeParameters);

  @override
  void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) =>
      _visit(node.primaryConstructor.typeParameters);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:solid_lints/src/lints/use_descriptive_names_for_type_parameters/models/use_descriptive_names_for_type_parameters_parameters.dart';
import 'package:solid_lints/src/lints/use_descriptive_names_for_type_parameters/use_descriptive_names_for_type_parameters_rule.dart';

/// A visitor that checks descriptive names for type parameters on declarations.
class UseDescriptiveNamesForTypeParametersVisitor
extends SimpleAstVisitor<void> {
final UseDescriptiveNamesForTypeParametersRule _rule;
final UseDescriptiveNamesForTypeParametersParameters _parameters;

/// Creates a new instance of [UseDescriptiveNamesForTypeParametersVisitor].
UseDescriptiveNamesForTypeParametersVisitor(this._rule, this._parameters);

void _checkAndReport(TypeParameterList? typeParameters) {
if (typeParameters == null ||
typeParameters.typeParameters.length < _parameters.minTypeParameters) {
return;
}

for (final param in typeParameters.typeParameters) {
final name = param.name.lexeme;
if (name.length == 1 && name != '_') {
_rule.reportAtNode(
param,
arguments: [_parameters.minTypeParameters.toString()],
);
}
}
}

@override
void visitClassDeclaration(ClassDeclaration node) {
_checkAndReport(node.namePart.typeParameters);
}
Comment thread
solid-illiaaihistov marked this conversation as resolved.

@override
void visitClassTypeAlias(ClassTypeAlias node) {
_checkAndReport(node.typeParameters);
}

@override
void visitEnumDeclaration(EnumDeclaration node) {
_checkAndReport(node.namePart.typeParameters);
}
Comment thread
solid-illiaaihistov marked this conversation as resolved.

@override
void visitFunctionExpression(FunctionExpression node) {
_checkAndReport(node.typeParameters);
}

@override
void visitMethodDeclaration(MethodDeclaration node) {
_checkAndReport(node.typeParameters);
}

@override
void visitGenericTypeAlias(GenericTypeAlias node) {
_checkAndReport(node.typeParameters);
}

@override
void visitFunctionTypeAlias(FunctionTypeAlias node) {
_checkAndReport(node.typeParameters);
}

@override
void visitGenericFunctionType(GenericFunctionType node) {
_checkAndReport(node.typeParameters);
}

@override
void visitExtensionDeclaration(ExtensionDeclaration node) {
_checkAndReport(node.typeParameters);
}

@override
void visitMixinDeclaration(MixinDeclaration node) {
_checkAndReport(node.typeParameters);
}

@override
void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
_checkAndReport(node.primaryConstructor.typeParameters);
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: solid_lints
description:
Lints for Dart and Flutter based on software industry standards and best
practices.
version: 0.3.4
version: 1.0.0
homepage: https://github.com/solid-software/solid_lints/
documentation: https://solid-software.github.io/solid_lints/docs/intro
topics: [lints, linter, lint, analysis, analyzer]
Expand Down
Loading