Skip to content
Open
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
6 changes: 4 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:solid_lints/src/lints/avoid_final_with_getter/fixes/avoid_final_
import 'package:solid_lints/src/lints/avoid_global_state/avoid_global_state_rule.dart';
import 'package:solid_lints/src/lints/avoid_non_null_assertion/avoid_non_null_assertion_rule.dart';
import 'package:solid_lints/src/lints/avoid_returning_widgets/avoid_returning_widgets_rule.dart';
import 'package:solid_lints/src/lints/avoid_returning_widgets/models/avoid_returning_widgets_parameters.dart';
import 'package:solid_lints/src/lints/avoid_unused_parameters/avoid_unused_parameters_rule.dart';
import 'package:solid_lints/src/lints/double_literal_format/double_literal_format_rule.dart';
import 'package:solid_lints/src/lints/double_literal_format/fixes/double_literal_format_fix.dart';
import 'package:solid_lints/src/lints/proper_super_calls/proper_super_calls_rule.dart';
Expand Down Expand Up @@ -40,7 +40,9 @@ class SolidLintsPlugin extends Plugin {
ProperSuperCallsRule(),
AvoidReturningWidgetsRule(
analysisOptionsLoader: analysisLoader,
parametersParser: AvoidReturningWidgetsParameters.fromJson,
),
AvoidUnusedParametersRule(
analysisOptionsLoader: analysisLoader,
),
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ class AvoidReturningWidgetsRule
/// Creates a new instance of [AvoidReturningWidgetsRule]
AvoidReturningWidgetsRule({
required super.analysisOptionsLoader,
required super.parametersParser,
}) : super.withParameters(
name: _code.lowerCaseName,
description: _code.problemMessage,
);
name: _code.lowerCaseName,
description: _code.problemMessage,
parametersParser: AvoidReturningWidgetsParameters.fromJson,
);

@override
void registerNodeProcessors(
Expand All @@ -79,7 +79,8 @@ class AvoidReturningWidgetsRule
) {
super.registerNodeProcessors(registry, context);

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

final visitor = AvoidReturningWidgetsVisitor(this, parameters);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import 'package:analyzer/error/listener.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';
import 'package:solid_lints/src/lints/avoid_unused_parameters/models/avoid_unused_parameters.dart';
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/avoid_unused_parameters/models/avoid_unused_parameters_parameters.dart';
import 'package:solid_lints/src/lints/avoid_unused_parameters/visitors/avoid_unused_parameters_visitor.dart';
import 'package:solid_lints/src/models/rule_config.dart';
import 'package:solid_lints/src/models/solid_lint_rule.dart';

/// Warns about unused function, method, constructor or factory parameters.
/// Warns about unused function, method, constructor, or factory parameters.
///
/// Named parameters are always allowed because they document the API surface.
/// Parameters whose names consist only of underscores are also ignored.
/// Overridden methods and methods used as tear-offs are skipped.
///
/// {@template solid_lints.avoid_unused_parameters.example}
/// ### Example
///
/// ### Example:
/// #### BAD:
///
/// ```dart
/// typedef MaxFun = int Function(int a, int b);
/// final MaxFun bad = (int a, int b) => 1; // LINT
Expand All @@ -18,6 +25,7 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart';
/// final optional = (int a, [int b = 0]) { // LINT
/// return a;
/// };
///
/// void fun(String x) {} // LINT
/// void fun2(String x, String y) { // LINT
/// print(y);
Expand All @@ -35,6 +43,7 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart';
/// ```
///
/// #### GOOD:
///
/// ```dart
/// typedef MaxFun = int Function(int a, int b);
/// final MaxFun good = (int a, int b) => a + b;
Expand All @@ -47,63 +56,67 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart';
/// }
///
/// class TestClass {
/// static void staticMethod(int _) {} // OK
/// void method(String _) {} // OK
/// static void staticMethod(int _) {}
/// void method(String _) {}
///
/// TestClass([int _]); // OK
/// factory TestClass.named(int _) { // OK
/// TestClass([int _]);
/// factory TestClass.named(int _) {
/// return TestClass();
/// }
/// }
/// ```
///
/// #### Allowed:
///
/// ```dart
/// typedef Named = String Function({required String text});
/// final Named named = ({required text}) {
/// return '';
/// return '';
/// };
///
/// ```
class AvoidUnusedParametersRule extends SolidLintRule<AvoidUnusedParameters> {
/// This lint rule represents
/// the error whether we use bad formatted double literals.
static const String lintName = 'avoid_unused_parameters';
/// {@endtemplate}
class AvoidUnusedParametersRule
extends SolidLintRule<AvoidUnusedParametersParameters> {
/// The name of this lint rule.
static const lintName = 'avoid_unused_parameters';

AvoidUnusedParametersRule._(super.config);
/// Reported when a parameter is declared but never read in the body.
///
/// {@macro solid_lints.avoid_unused_parameters.example}
static const LintCode _code = LintCode(
lintName,
'Avoid unused parameters.',
correctionMessage:
'Remove the parameter or replace its name with underscores.',
);

/// Creates a new instance of [AvoidUnusedParametersRule]
/// based on the lint configuration.
factory AvoidUnusedParametersRule.createRule(
CustomLintConfigs configs,
) {
final rule = RuleConfig(
configs: configs,
name: lintName,
paramsParser: AvoidUnusedParameters.fromJson,
problemMessage: (_) => 'Parameter is unused.',
);
@override
LintCode get diagnosticCode => _code;

return AvoidUnusedParametersRule._(rule);
}
/// Creates a new instance of [AvoidUnusedParametersRule].
AvoidUnusedParametersRule({
required super.analysisOptionsLoader,
}) : super.withParameters(
name: lintName,
description:
'Warns about unused function, method, constructor, or factory '
'parameters.',
parametersParser: AvoidUnusedParametersParameters.fromJson,
);

@override
void run(
CustomLintResolver resolver,
DiagnosticReporter reporter,
CustomLintContext context,
void registerNodeProcessors(
RuleVisitorRegistry registry,
RuleContext context,
) {
context.registry.addDeclaration((node) {
final isIgnored = config.parameters.exclude.shouldIgnore(node);
super.registerNodeProcessors(registry, context);

if (isIgnored) return;
final parameters =
getParametersForContext(context) ??
AvoidUnusedParametersParameters.empty();

final visitor = AvoidUnusedParametersVisitor();
node.accept(visitor);
final visitor = AvoidUnusedParametersVisitor(this, parameters);

for (final element in visitor.unusedParameters) {
reporter.atNode(element, code);
}
});
registry.addCompilationUnit(this, visitor);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:solid_lints/src/common/parameters/excluded_identifiers_list_parameter.dart';

/// A data model class that represents the `avoid_unused_parameters` input
/// parameters.
class AvoidUnusedParametersParameters {
/// A list of methods that should be excluded from the lint.
final ExcludedIdentifiersListParameter exclude;

/// Constructor for [AvoidUnusedParametersParameters] model.
AvoidUnusedParametersParameters({
required this.exclude,
});

/// Empty [AvoidUnusedParametersParameters] model, excludes nothing.
factory AvoidUnusedParametersParameters.empty() {
return AvoidUnusedParametersParameters(
exclude: ExcludedIdentifiersListParameter(exclude: []),
);
}

/// Method for creating from json data.
factory AvoidUnusedParametersParameters.fromJson(Map<String, dynamic> json) {
return AvoidUnusedParametersParameters(
exclude: ExcludedIdentifiersListParameter.defaultFromJson(json),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:collection/collection.dart';
import 'package:solid_lints/src/lints/avoid_unused_parameters/avoid_unused_parameters_rule.dart';
import 'package:solid_lints/src/lints/avoid_unused_parameters/models/avoid_unused_parameters_parameters.dart';
import 'package:solid_lints/src/utils/node_utils.dart';
import 'package:solid_lints/src/utils/parameter_utils.dart';

/// AST Visitor which finds all is expressions and checks if they are
/// unrelated (result always false)
/// A visitor that reports unused formal parameters.
class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {
final _unusedParameters = <FormalParameter>[];
final AvoidUnusedParametersRule _rule;
final AvoidUnusedParametersParameters _parameters;

/// List of unused parameters
Iterable<FormalParameter> get unusedParameters => _unusedParameters;
/// Creates a new instance of [AvoidUnusedParametersVisitor].
AvoidUnusedParametersVisitor(this._rule, this._parameters);

@override
void visitConstructorDeclaration(ConstructorDeclaration node) {
Expand All @@ -48,15 +50,18 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {
parameters.parameters.isEmpty) {
return;
}

if (_isExcluded(node)) return;

final unused = _getUnusedParameters(
node.body,
parameters.parameters,
initializers: node.initializers,
).whereNot(nameConsistsOfUnderscoresOnly);

_unusedParameters.addAll(
unused,
);
for (final parameter in unused) {
_rule.reportAtNode(parameter);
}
}

@override
Expand All @@ -73,34 +78,41 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {
return;
}

final isTearOff = _usedAsTearOff(node);
if (_isExcluded(node) || isOverride(node.metadata) || _isATearOff(node)) {
return;
}

if (!isOverride(node.metadata) && !isTearOff) {
_unusedParameters.addAll(
_filterOutUnderscoresAndNamed(
node.body,
parameters.parameters,
),
);
for (final parameter in _filterOutUnderscoresAndNamed(
node.body,
parameters.parameters,
)) {
_rule.reportAtNode(parameter);
}
}

@override
void visitFunctionExpression(FunctionExpression node) {
super.visitFunctionExpression(node);

final declaration =
node.thisOrAncestorOfType<FunctionDeclaration>() ??
node.thisOrAncestorOfType<MethodDeclaration>() ??
node.thisOrAncestorOfType<ConstructorDeclaration>();
if (declaration != null && _isExcluded(declaration)) return;

final params = node.parameters;
if (params == null) {
return;
}
if (params == null) return;

_unusedParameters.addAll(
_filterOutUnderscoresAndNamed(
node.body,
params.parameters,
),
);
for (final parameter in _filterOutUnderscoresAndNamed(
node.body,
params.parameters,
)) {
_rule.reportAtNode(parameter);
}
}

bool _isExcluded(Declaration node) => _parameters.exclude.shouldIgnore(node);

Iterable<FormalParameter> _filterOutUnderscoresAndNamed(
AstNode body,
Iterable<FormalParameter> parameters,
Expand All @@ -109,9 +121,10 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {
body,
parameters,
);
return unused.whereNot(nameConsistsOfUnderscoresOnly).where(
(param) => !param.isNamed,
);

return unused
.whereNot(nameConsistsOfUnderscoresOnly)
.where((param) => !param.isNamed);
}

Set<FormalParameter> _getUnusedParameters(
Expand Down Expand Up @@ -145,7 +158,6 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {
isFieldFormalParameter = parameter.toSource().contains('this.');
isSuperFormalParameter = parameter.toSource().contains('super.');
}
//

if (name != null &&
!isPresentInAll &&
Expand All @@ -158,7 +170,7 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {
return result;
}

bool _usedAsTearOff(MethodDeclaration node) {
bool _isATearOff(MethodDeclaration node) {
final name = node.name.lexeme;
if (!Identifier.isPrivateName(name)) {
return false;
Expand Down
Loading
Loading