Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 @@ -101,6 +101,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 @@ -31,6 +31,7 @@ import 'package:solid_lints/src/lints/prefer_first/prefer_first_rule.dart';
import 'package:solid_lints/src/lints/prefer_last/prefer_last_rule.dart';
import 'package:solid_lints/src/lints/prefer_match_file_name/prefer_match_file_name_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/use_nearest_context_rule.dart';
import 'package:solid_lints/src/models/proxy_analysis_rule.dart';
import 'package:solid_lints/src/models/proxy_multi_analysis_rule.dart';
Expand Down Expand Up @@ -83,6 +84,9 @@ class SolidLintsPlugin extends Plugin {
PreferLastRule(),
PreferMatchFileNameRule(analysisOptionsLoader: analysisLoader),
ProperSuperCallsRule(),
UseDescriptiveNamesForTypeParametersRule(
analysisOptionsLoader: analysisLoader,
),
UseNearestContextRule(),
];

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,90 @@
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)
..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,73 @@
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);
}
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
Loading