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

Ignore magic numbers in widget parameters #74

Merged
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
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,
);
}