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

Fixed avoid_unused_parameters #140

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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- 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.
- 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart';
/// ### Example:
/// #### BAD:
/// ```dart
/// typedef MaxFun = int Function(int a, int b);
/// final MaxFun bad = (int a, int b) => 1; // LINT
/// final MaxFun testFun = (int a, int b) { // LINT
/// return 4;
/// };
/// 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 @@ -27,6 +35,11 @@ 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;
/// final MaxFun testFun = (int a, int b) {
/// return a + b;
/// };
/// void fun(String _) {} // Replacing with underscores silences the warning
/// void fun2(String _, String y) {
/// print(y);
Expand All @@ -42,6 +55,15 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart';
/// }
/// }
/// ```
///
/// #### Allowed:
/// ```dart
/// typedef Named = String Function({required String text});
/// final Named named = ({required text}) {
/// return '';
/// };
///
/// ```
class AvoidUnusedParametersRule extends SolidLintRule {
/// The [LintCode] of this lint rule that represents
/// the error whether we use bad formatted double literals.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {
parameters.parameters.isEmpty) {
return;
}
final unused = _getUnusedParameters(
node.body,
parameters.parameters,
initializers: node.initializers,
).whereNot(nameConsistsOfUnderscoresOnly);

_unusedParameters.addAll(
_getUnusedParameters(
node.body,
parameters.parameters,
initializers: node.initializers,
).whereNot(nameConsistsOfUnderscoresOnly),
unused,
);
}

Expand All @@ -76,31 +77,41 @@ class AvoidUnusedParametersVisitor extends RecursiveAstVisitor<void> {

if (!isOverride(node.metadata) && !isTearOff) {
_unusedParameters.addAll(
_getUnusedParameters(
_filterOutUnderscoresAndNamed(
node.body,
parameters.parameters,
).whereNot(nameConsistsOfUnderscoresOnly),
),
);
}
}

@override
void visitFunctionDeclaration(FunctionDeclaration node) {
super.visitFunctionDeclaration(node);

final parameters = node.functionExpression.parameters;

if (node.externalKeyword != null ||
(parameters == null || parameters.parameters.isEmpty)) {
void visitFunctionExpression(FunctionExpression node) {
super.visitFunctionExpression(node);
final params = node.parameters;
if (params == null) {
return;
}

_unusedParameters.addAll(
_getUnusedParameters(
node.functionExpression.body,
parameters.parameters,
).whereNot(nameConsistsOfUnderscoresOnly),
_filterOutUnderscoresAndNamed(
node.body,
params.parameters,
),
);
}

Iterable<FormalParameter> _filterOutUnderscoresAndNamed(
AstNode body,
Iterable<FormalParameter> parameters,
) {
final unused = _getUnusedParameters(
body,
parameters,
);
return unused.whereNot(nameConsistsOfUnderscoresOnly).where(
(param) => !param.isNamed,
);
}

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

if (name != null &&
!isPresentInAll &&
Expand Down
96 changes: 92 additions & 4 deletions lint_test/avoid_unused_parameters_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ignore_for_file: prefer_const_declarations, prefer_match_file_name
// ignore_for_file: prefer_const_declarations, prefer_match_file_name, avoid_global_state
// ignore_for_file: unnecessary_nullable_for_final_variable_declarations
// ignore_for_file: unused_local_variable
// ignore_for_file: unused_element
Expand All @@ -9,12 +9,79 @@
import 'package:flutter/material.dart';

/// Check the `avoid_unused_parameters` rule
///
void testNamed() {
SomeAnotherClass(
func: ({required text}) {},
);
}

typedef MaxFun = int Function(int a, int b);

typedef Named = String Function({required String text});

typedef ReqNamed = void Function({required String text});

// expect_lint: avoid_unused_parameters
final MaxFun bad = (int a, int b) => 1;

final MaxFun good = (int a, _) => a;

final MaxFun ok = (int _, int __) => 1;

final MaxFun goodMax = (int a, int b) {
return a + b;
};

final Named _named = ({required text}) {
return '';
};

void ch({String text = ''}) {}

final Named _named2 = ({required text}) {
return text;
};

final Named _named3 = ({required text}) => '';

final Named _named4 = ({required text}) => text;

// expect_lint: avoid_unused_parameters
final optional = (int a, [int b = 0]) {
return a;
};

// expect_lint: avoid_unused_parameters
final named = (int a, {required int b, int c = 0}) {
return c;
};

// good
var k = (String g) {
return g;
};

// expect_lint: avoid_unused_parameters
var c = (String g) {
return '0';
};

// expect_lint: avoid_unused_parameters
final MaxFun tetsFun = (int a, int b) {
return 4;
};

// expect_lint: avoid_unused_parameters
void fun(String s) {
return;
}

// expect_lint: avoid_unused_parameters
void fun2(String s) {
return;
}

class TestClass {
// expect_lint: avoid_unused_parameters
static void staticMethod(int a) {}
Expand All @@ -34,13 +101,27 @@ class TestClass2 {
}

class SomeOtherClass {
// expect_lint: avoid_unused_parameters
final MaxFun maxFunLint = (int a, int b) => 1;

// Good
final MaxFun good = (int a, int b) {
return a * b;
};

// expect_lint: avoid_unused_parameters
void method(String s) {
return;
}
}

class SomeAnotherClass extends SomeOtherClass {
final ReqNamed func;

SomeAnotherClass({
required this.func,
});

@override
void method(String s) {}
}
Expand All @@ -67,11 +148,11 @@ void closure(int a) {
}
}

typedef MaxFun = int Function(int a, int b);

// Allowed same way as override
// expect_lint: avoid_unused_parameters
final MaxFun maxFunInstance = (int a, int b) => 1;

final MaxFun m = (_, __) => 1;

class Foo {
final int a;
final int? b;
Expand Down Expand Up @@ -102,8 +183,15 @@ class TestWidget extends StatelessWidget {
super.key,
// expect_lint: avoid_unused_parameters
int a = 1,
// expect_lint: avoid_unused_parameters
String k = '',
});

// expect_lint: avoid_unused_parameters
factory TestWidget.a([int b = 0]) {
return TestWidget(k: '');
}

@override
Widget build(BuildContext context) {
return const Placeholder();
Expand Down
Loading