Skip to content

Commit

Permalink
Fixed avoid_unused_parameters (#140)
Browse files Browse the repository at this point in the history
* Fixed avoid_unused_parameters

* PR issues

* chnages toward named params

* fix doc mistake

* fix dry

* PR fix

* Update CHANGELOG.md

Co-authored-by: Illia Romanenko <[email protected]>

---------

Co-authored-by: Yurii Prykhodko <[email protected]>
Co-authored-by: Illia Romanenko <[email protected]>
  • Loading branch information
3 people authored Mar 14, 2024
1 parent b8d126d commit 03e0b44
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 22 deletions.
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

0 comments on commit 03e0b44

Please sign in to comment.