Skip to content

Commit

Permalink
Ignore magic numbers in widget parameters (#74)
Browse files Browse the repository at this point in the history
* Ignore magic numbers in widget parameters

* Add lint parameter to ignore magic numbers in widget params

* Improve the allowed_in_widget_params parameter to exclude magic numbers in nested objects of Widget parameters

* Add tests for disabled allowed_in_widget_params lint parameter

* Remove unnecessary dependency

---------

Co-authored-by: vladimir-beloded <[email protected]>
  • Loading branch information
solid-vovabeloded and vova-beloded-solid authored Nov 20, 2023
1 parent 414a14e commit b45d2be
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@
/// parameters.
class NoMagicNumberParameters {
static const _allowedConfigName = 'allowed';
static const _allowedInWidgetParamsConfigName = 'allowed_in_widget_params';
static const _defaultMagicNumbers = [-1, 0, 1];

/// List of allowed numbers
final Iterable<num> allowedNumbers;

/// The flag indicates whether magic numbers are allowed as a Widget instance
/// parameter.
final bool allowedInWidgetParams;

/// Constructor for [NoMagicNumberParameters] model
const NoMagicNumberParameters({
required this.allowedNumbers,
required this.allowedInWidgetParams,
});

/// Method for creating from json data
factory NoMagicNumberParameters.fromJson(Map<String, Object?> json) =>
NoMagicNumberParameters(
allowedNumbers:
json[_allowedConfigName] as Iterable<num>? ?? _defaultMagicNumbers,
allowedInWidgetParams:
json[_allowedInWidgetParamsConfigName] as bool? ?? false,
);
}
32 changes: 31 additions & 1 deletion lib/lints/no_magic_number/no_magic_number_rule.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
// SOFTWARE.

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:collection/collection.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';
import 'package:solid_lints/lints/no_magic_number/models/no_magic_number_parameters.dart';
import 'package:solid_lints/lints/no_magic_number/no_magic_number_visitor.dart';
Expand Down Expand Up @@ -71,7 +73,8 @@ class NoMagicNumberRule extends SolidLintRule<NoMagicNumberParameters> {
.where(_isNotInsideIndexExpression)
.where(_isNotInsideEnumConstantArguments)
.where(_isNotDefaultValue)
.where(_isNotInConstructorInitializer);
.where(_isNotInConstructorInitializer)
.where(_isNotWidgetParameter);

for (final magicNumber in magicNumbers) {
reporter.reportErrorForNode(code, magicNumber);
Expand Down Expand Up @@ -132,4 +135,31 @@ class NoMagicNumberRule extends SolidLintRule<NoMagicNumberParameters> {
bool _isNotInConstructorInitializer(Literal literal) {
return literal.thisOrAncestorOfType<ConstructorInitializer>() == null;
}

bool _isNotWidgetParameter(Literal literal) {
if (!config.parameters.allowedInWidgetParams) return true;

final widgetCreationExpression = literal.thisOrAncestorMatching(
_isWidgetCreationExpression,
);

return widgetCreationExpression == null;
}

bool _isWidgetCreationExpression(
AstNode node,
) {
if (node is! InstanceCreationExpression) return false;

final staticType = node.staticType;

if (staticType is! InterfaceType) return false;

final widgetSupertype = staticType.allSupertypes.firstWhereOrNull(
(supertype) =>
supertype.getDisplayString(withNullability: false) == 'Widget',
);

return widgetSupertype != null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
analyzer:
plugins:
- ../custom_lint

custom_lint:
rules:
- no_magic_number:
allowed_in_widget_params: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Allowed for numbers in a Widget subtype parameters.
abstract interface class Widget {}

class StatelessWidget implements Widget {}

class MyWidget extends StatelessWidget {
final MyWidgetDecoration decoration;
final int value;

MyWidget({
required this.decoration,
required this.value,
});
}

class MyWidgetDecoration {
final int size;

MyWidgetDecoration({required this.size});
}

Widget build() {
return MyWidget(
decoration: MyWidgetDecoration(size: 12),
value: 23,
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: no_magic_number_allowed_in_widget_params_test
description: A starting point for Dart libraries or applications.
publish_to: none

environment:
sdk: '>=3.0.0 <4.0.0'

dev_dependencies:
solid_lints:
path: ../../
test: ^1.20.1
29 changes: 29 additions & 0 deletions lint_test/no_magic_number_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,32 @@ class ConstructorInitializer {

ConstructorInitializer() : value = 10;
}

abstract interface class Widget {}

class StatelessWidget implements Widget {}

class MyWidget extends StatelessWidget {
final MyWidgetDecoration decoration;
final int value;

MyWidget({
required this.decoration,
required this.value,
});
}

class MyWidgetDecoration {
final int size;

MyWidgetDecoration({required this.size});
}

Widget build() {
return MyWidget(
// expect_lint: no_magic_number
decoration: MyWidgetDecoration(size: 12),
// expect_lint: no_magic_number
value: 23,
);
}

0 comments on commit b45d2be

Please sign in to comment.