Skip to content

Commit

Permalink
feat: Add avoid_hardcoded_color rule
Browse files Browse the repository at this point in the history
  • Loading branch information
naipaka committed Jul 29, 2024
1 parent 313f4ae commit 2843698
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"ints",
"pubspec",
"redeclares",
"RGBO",
"subosito",
"Supertypes",
"tearoffs",
Expand Down
2 changes: 2 additions & 0 deletions packages/altive_lints/lib/altive_lints.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:custom_lint_builder/custom_lint_builder.dart';

import 'src/lints/avoid_hardcoded_color.dart';
import 'src/lints/avoid_hardcoded_japanese.dart';
import 'src/lints/avoid_shrink_wrap_in_list_view.dart';
import 'src/lints/avoid_single_child.dart';
Expand All @@ -10,6 +11,7 @@ PluginBase createPlugin() => _AltivePlugin();
class _AltivePlugin extends PluginBase {
@override
List<LintRule> getLintRules(CustomLintConfigs configs) => [
const AvoidHardcodedColor(),
const AvoidHardcodedJapanese(),
const AvoidShrinkWrapInListView(),
const AvoidSingleChild(),
Expand Down
78 changes: 78 additions & 0 deletions packages/altive_lints/lib/src/lints/avoid_hardcoded_color.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';

/// An `avoid_hardcoded_color` rule that discourages the use of
/// hardcoded colors directly in the code, promoting the use of `ColorScheme`,
/// `ThemeExtension`, or other Theme-based systems for defining colors.
///
/// This practice ensures that colors are consistent and
/// adaptable to different themes and accessibility settings.
///
/// ### Example
///
/// #### BAD:
///
/// ```dart
/// Container(
/// color: Color(0xFF00FF00), // LINT
/// );
/// ```
///
/// #### GOOD:
///
/// ```dart
/// Container(
/// color: Theme.of(context).colorScheme.primary,
/// );
/// ```
class AvoidHardcodedColor extends DartLintRule {
const AvoidHardcodedColor() : super(code: _lintCode);

static const _lintCode = LintCode(
name: 'avoid_hardcoded_color',
problemMessage: 'Avoid using hardcoded color. Use ColorScheme, '
'ThemeExtension, or other Theme-based color definitions instead. '
'Consider using Theme.of(context).colorScheme or a custom '
'ThemeExtension for color definitions.',
);

@override
void run(
CustomLintResolver resolver,
ErrorReporter reporter,
CustomLintContext context,
) {
context.registry.addInstanceCreationExpression((node) {
final typeName =
node.staticType?.getDisplayString(withNullability: false);

if (typeName == 'Color') {
reporter.reportErrorForNode(code, node);
}
});

context.registry.addPrefixedIdentifier((node) {
final prefix = node.prefix.name;
if (prefix == 'Colors') {
final element = node.staticElement;
if (element is PropertyAccessorElement) {
final returnType = element.returnType;
if (_isColorType(returnType)) {
reporter.reportErrorForNode(code, node);
}
}
}
});
}

bool _isColorType(DartType? type) {
return type != null &&
(type.isDartCoreInt ||
type.getDisplayString(withNullability: false) == 'Color' ||
type.getDisplayString(withNullability: false) == 'MaterialColor' ||
type.getDisplayString(withNullability: false) ==
'MaterialAccentColor');
}
}
20 changes: 20 additions & 0 deletions packages/altive_lints/lint_test/lints/avoid_hardcoded_color.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
const MyWidget({super.key});

@override
Widget build(BuildContext context) {
return Column(
children: [
// expect_lint: avoid_hardcoded_color
const ColoredBox(color: Color(0xFF00FF00)),
// expect_lint: avoid_hardcoded_color
const ColoredBox(color: Color.fromRGBO(0, 255, 0, 1)),
// expect_lint: avoid_hardcoded_color
const ColoredBox(color: Colors.green),
ColoredBox(color: Theme.of(context).colorScheme.primary),
],
);
}
}

0 comments on commit 2843698

Please sign in to comment.