Skip to content

Commit d84619e

Browse files
srawlinsCommit Queue
authored and
Commit Queue
committed
analyzer: Support digit separators in use_full_hex rule
Work towards #56188 Cq-Include-Trybots: luci.dart.try:flutter-analyze-try,analyzer-win-release-try,pkg-win-release-try Change-Id: I75897ffdcacd3613b9e5f5095932f514c4653fac Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/375780 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com>
1 parent 01b1156 commit d84619e

File tree

4 files changed

+84
-52
lines changed

4 files changed

+84
-52
lines changed

pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
import 'package:analysis_server/src/services/correction/fix.dart';
66
import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
77
import 'package:analyzer/dart/ast/ast.dart';
8+
import 'package:analyzer/dart/ast/token.dart';
89
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
910
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
1011
import 'package:analyzer_plugin/utilities/range_factory.dart';
1112

1213
class ReplaceWithEightDigitHex extends ResolvedCorrectionProducer {
14+
static final _underscoresPattern = RegExp('_+');
15+
1316
/// The replacement text, used as an argument to the fix message.
1417
String _replacement = '';
1518

@@ -30,22 +33,23 @@ class ReplaceWithEightDigitHex extends ResolvedCorrectionProducer {
3033

3134
@override
3235
Future<void> compute(ChangeBuilder builder) async {
33-
//
34-
// Extract the information needed to build the edit.
35-
//
36-
if (node is! IntegerLiteral) {
37-
return;
38-
}
39-
var value = (node as IntegerLiteral).value;
40-
if (value == null) {
41-
return;
36+
if (node case (IntegerLiteral(:var value?, :var literal))) {
37+
var replacementDigits = value.toRadixString(16).padLeft(8, '0');
38+
if (literal.type == TokenType.HEXADECIMAL_WITH_SEPARATORS) {
39+
// The original string should be a substring of the replacement
40+
// (ignoring the '0x'). If there are existing separators, preserve them.
41+
var originalDigits = literal.lexeme.substring('0x'.length);
42+
var originalWithoutSeparators =
43+
originalDigits.replaceAll(_underscoresPattern, '');
44+
var numberOfDigitsToAdd =
45+
replacementDigits.length - originalWithoutSeparators.length;
46+
var newLeadingDigits = '0' * numberOfDigitsToAdd;
47+
replacementDigits = '$newLeadingDigits$originalDigits';
48+
}
49+
_replacement = '0x$replacementDigits';
50+
await builder.addDartFileEdit(file, (builder) {
51+
builder.addSimpleReplacement(range.node(node), _replacement);
52+
});
4253
}
43-
_replacement = '0x${value.toRadixString(16).padLeft(8, '0')}';
44-
//
45-
// Build the edit.
46-
//
47-
await builder.addDartFileEdit(file, (builder) {
48-
builder.addSimpleReplacement(range.node(node), _replacement);
49-
});
5054
}
5155
}

pkg/analysis_server/test/src/services/correction/fix/replace_with_eight_digit_hex_test.dart

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class ReplaceWithEightDigitHexTest extends FixProcessorLintTest {
5353
@override
5454
String get lintCode => LintNames.use_full_hex_values_for_flutter_colors;
5555

56-
Future<void> test_notHex() async {
56+
Future<void> test_decimal() async {
5757
await resolveTestCode('''
5858
library dart.ui;
5959
@@ -74,7 +74,7 @@ class Color {
7474
''');
7575
}
7676

77-
Future<void> test_short() async {
77+
Future<void> test_sixDigitHex() async {
7878
await resolveTestCode('''
7979
library dart.ui;
8080
@@ -89,6 +89,27 @@ library dart.ui;
8989
9090
var c = Color(0x00000001);
9191
92+
class Color {
93+
Color(int value);
94+
}
95+
''');
96+
}
97+
98+
Future<void> test_sixDigitHex_withSeparators() async {
99+
await resolveTestCode('''
100+
library dart.ui;
101+
102+
var c = Color(0x00_00_01);
103+
104+
class Color {
105+
Color(int value);
106+
}
107+
''');
108+
await assertHasFix('''
109+
library dart.ui;
110+
111+
var c = Color(0x0000_00_01);
112+
92113
class Color {
93114
Color(int value);
94115
}

pkg/linter/lib/src/rules/use_full_hex_values_for_flutter_colors.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import '../analyzer.dart';
99
import '../extensions.dart';
1010

1111
const _desc =
12-
r'Prefer an 8-digit hexadecimal integer(0xFFFFFFFF) to instantiate Color.';
12+
r'Prefer an 8-digit hexadecimal integer (for example, 0xFFFFFFFF) to '
13+
'instantiate a Color.';
1314

1415
const _details = r'''
15-
**PREFER** an 8-digit hexadecimal integer(0xFFFFFFFF) to instantiate Color. Colors
16-
have four 8-bit channels, which adds up to 32 bits, so Colors are described
17-
using a 32 bit integer.
16+
**PREFER** an 8-digit hexadecimal integer (for example, 0xFFFFFFFF) to
17+
instantiate a Color. Colors have four 8-bit channels, which adds up to 32 bits,
18+
so Colors are described using a 32-bit integer.
1819
1920
**BAD:**
2021
```dart
@@ -57,6 +58,8 @@ class UseFullHexValuesForFlutterColors extends LintRule {
5758
}
5859

5960
class _Visitor extends SimpleAstVisitor {
61+
static final _underscoresPattern = RegExp('_+');
62+
6063
final LintRule rule;
6164

6265
_Visitor(this.rule);
@@ -72,6 +75,7 @@ class _Visitor extends SimpleAstVisitor {
7275
var argument = arguments.first;
7376
if (argument is IntegerLiteral) {
7477
var value = argument.literal.lexeme.toLowerCase();
78+
value = value.replaceAll(_underscoresPattern, '');
7579
if (!value.startsWith('0x') || value.length != 10) {
7680
rule.reportLint(argument);
7781
}

pkg/linter/test/rules/use_full_hex_values_for_flutter_colors_test.dart

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,29 @@ class UseFullHexValuesForFlutterColorsTest extends LintRuleTest {
1717
@override
1818
String get lintRule => 'use_full_hex_values_for_flutter_colors';
1919

20-
test_dynamicArgument() async {
21-
await assertNoDiagnostics(r'''
20+
test_decimal() async {
21+
await assertDiagnostics(r'''
2222
library dart.ui;
2323
24+
var c = Color(1);
25+
2426
class Color {
2527
Color(int v);
2628
}
29+
''', [
30+
lint(32, 1),
31+
]);
32+
}
2733

28-
void f(dynamic a) {
29-
Color(a);
34+
test_dynamicArgument() async {
35+
await assertNoDiagnostics(r'''
36+
library dart.ui;
37+
38+
dynamic a = 1;
39+
var c = Color(a);
40+
41+
class Color {
42+
Color(int v);
3043
}
3144
''');
3245
}
@@ -35,75 +48,65 @@ void f(dynamic a) {
3548
await assertNoDiagnostics(r'''
3649
library dart.ui;
3750
51+
var c = Color(0x00000000);
52+
3853
class Color {
3954
Color(int v);
4055
}
41-
42-
void f() {
43-
Color(0x00000000);
44-
}
4556
''');
4657
}
4758

4859
test_eightDigitHex_upper() async {
4960
await assertNoDiagnostics(r'''
5061
library dart.ui;
5162
63+
var c = Color(0X00000000);
64+
5265
class Color {
5366
Color(int v);
5467
}
55-
56-
void f() {
57-
Color(0X00000000);
58-
}
5968
''');
6069
}
6170

62-
test_nonHex() async {
71+
test_sixDigitHex_lower() async {
6372
await assertDiagnostics(r'''
6473
library dart.ui;
6574
75+
var c = Color(0x000000);
76+
6677
class Color {
6778
Color(int v);
6879
}
69-
70-
void f() {
71-
Color(1);
72-
}
7380
''', [
74-
lint(70, 1),
81+
lint(32, 8),
7582
]);
7683
}
7784

78-
test_sixDigitHex_lower() async {
85+
test_sixDigitHex_upper() async {
7986
await assertDiagnostics(r'''
8087
library dart.ui;
8188
89+
var c = Color(0X000000);
90+
8291
class Color {
8392
Color(int v);
8493
}
85-
86-
void f() {
87-
Color(0x000000);
88-
}
8994
''', [
90-
lint(70, 8),
95+
lint(32, 8),
9196
]);
9297
}
9398

94-
test_sixDigitHex_upper() async {
99+
test_sixDigitHex_withSeparators() async {
95100
await assertDiagnostics(r'''
96101
library dart.ui;
97102
103+
var c = Color(0x00_00_00);
104+
98105
class Color {
99106
Color(int v);
100107
}
101-
102-
void f() {
103-
Color(0X000000);
104-
}
105108
''', [
106-
lint(70, 8),
109+
lint(32, 10),
107110
]);
108111
}
109112
}

0 commit comments

Comments
 (0)