Skip to content

Commit 7e76412

Browse files
stereotype441Commit Queue
authored andcommitted
[analyzer]: Move some string extensions into analyzer_utilities.
The string extensions `toCamelCase` and `toPascalCase` are used in the code generation logic for diagnostic messages. In a follow-up CL, I intend to move much of this code generation logic from `package:analyzer` to `package:analyzer_utilities` so that the CFE can make use of it without depending on `package:analyzer/src`. To make that possible, these string extensions need to be moved into `package:analyzer_utilities` too. Change-Id: I6a6a6964e4648bdf6ced726a6a58ea9974876ae2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447980 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 4800d2c commit 7e76412

File tree

8 files changed

+102
-76
lines changed

8 files changed

+102
-76
lines changed

pkg/analyzer/lib/src/utilities/extensions/string.dart

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -160,55 +160,6 @@ extension StringExtension on String {
160160
}
161161
}
162162

163-
/// Converts `SCREAMING_SNAKE_CASE` or `snake_case` to `camelCase`.
164-
String toCamelCase() {
165-
var parts = toLowerCase().split('_');
166-
var buffer = StringBuffer();
167-
var i = 0;
168-
// Preserve initial '_'s
169-
while (i < parts.length - 1 && parts[i].isEmpty) {
170-
buffer.write('_');
171-
++i;
172-
}
173-
if (i < parts.length) {
174-
// Convert first word to lower case
175-
buffer.write(parts[i].toLowerCase());
176-
++i;
177-
// Convert remaining words to initial upper case
178-
while (i < parts.length) {
179-
var part = parts[i];
180-
if (part.isNotEmpty) {
181-
buffer.write(part[0].toUpperCase());
182-
buffer.write(part.substring(1));
183-
}
184-
++i;
185-
}
186-
}
187-
return buffer.toString();
188-
}
189-
190-
/// Converts `SCREAMING_SNAKE_CASE` or `snake_case` to `PascalCase`.
191-
String toPascalCase() {
192-
var parts = toLowerCase().split('_');
193-
var buffer = StringBuffer();
194-
var i = 0;
195-
// Preserve initial '_'s
196-
while (i < parts.length - 1 && parts[i].isEmpty) {
197-
buffer.write('_');
198-
++i;
199-
}
200-
// Convert words to initial upper case
201-
while (i < parts.length) {
202-
var part = parts[i];
203-
if (part.isNotEmpty) {
204-
buffer.write(part[0].toUpperCase());
205-
buffer.write(part.substring(1));
206-
}
207-
++i;
208-
}
209-
return buffer.toString();
210-
}
211-
212163
/// Converts `camelCase` / `PascalCase` to `SCREAMING_SNAKE_CASE`.
213164
/// Examples:
214165
/// - camelCase -> CAMEL_CASE

pkg/analyzer/test/generated/test_support.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import 'package:analyzer/instrumentation/instrumentation.dart';
1212
import 'package:analyzer/source/line_info.dart';
1313
import 'package:analyzer/source/source.dart';
1414
import 'package:analyzer/src/generated/engine.dart';
15-
import 'package:analyzer/src/utilities/extensions/string.dart';
15+
import 'package:analyzer_utilities/extensions/string.dart';
1616
import 'package:test/test.dart';
1717

1818
/// A description of a message that is expected to be reported with an error.

pkg/analyzer/test/src/utilities/extensions/string_test.dart

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -197,30 +197,6 @@ class StringExtensionTest {
197197
expect('01234'.removeSuffix('5'), isNull);
198198
}
199199

200-
void test_toCamelCase() {
201-
expect('CAMEL_CASE'.toCamelCase(), 'camelCase');
202-
expect('alreadyCamel_case'.toCamelCase(), 'alreadycamelCase');
203-
expect('FOO_123_BAR'.toCamelCase(), 'foo123Bar');
204-
expect('FOO'.toCamelCase(), 'foo');
205-
expect('___'.toCamelCase(), '___');
206-
expect(''.toCamelCase(), '');
207-
expect('_FOO_BAR'.toCamelCase(), '_fooBar');
208-
expect('FOO__BAR'.toCamelCase(), 'fooBar');
209-
expect('FOO_BAR_'.toCamelCase(), 'fooBar');
210-
}
211-
212-
void test_toPascalCase() {
213-
expect('PASCAL_CASE'.toPascalCase(), 'PascalCase');
214-
expect('AlreadyPascal_case'.toPascalCase(), 'AlreadypascalCase');
215-
expect('FOO_123_BAR'.toPascalCase(), 'Foo123Bar');
216-
expect('FOO'.toPascalCase(), 'Foo');
217-
expect('___'.toPascalCase(), '___');
218-
expect(''.toPascalCase(), '');
219-
expect('_FOO_BAR'.toPascalCase(), '_FooBar');
220-
expect('FOO__BAR'.toPascalCase(), 'FooBar');
221-
expect('FOO_BAR_'.toPascalCase(), 'FooBar');
222-
}
223-
224200
void test_toScreamingSnake() {
225201
expect('camelCase'.toScreamingSnake(), 'CAMEL_CASE');
226202
expect('HTTPRequest'.toScreamingSnake(), 'HTTP_REQUEST');

pkg/analyzer/tool/messages/error_code_info.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import 'dart:convert';
66
import 'dart:io';
77

8-
import 'package:analyzer/src/utilities/extensions/string.dart';
98
import 'package:analyzer_testing/package_root.dart' as pkg_root;
9+
import 'package:analyzer_utilities/extensions/string.dart';
1010
import 'package:analyzer_utilities/tools.dart';
1111
import 'package:path/path.dart';
1212
import 'package:yaml/yaml.dart' show loadYaml;

pkg/analyzer/tool/messages/generate.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ library;
1919
import 'dart:convert';
2020
import 'dart:io';
2121

22-
import 'package:analyzer/src/utilities/extensions/string.dart';
2322
import 'package:analyzer_testing/package_root.dart' as pkg_root;
23+
import 'package:analyzer_utilities/extensions/string.dart';
2424
import 'package:analyzer_utilities/tools.dart';
2525
import 'package:collection/collection.dart';
2626
import 'package:path/path.dart';
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
extension StringExtension on String {
6+
/// Converts `SCREAMING_SNAKE_CASE` or `snake_case` to `camelCase`.
7+
String toCamelCase() {
8+
var parts = toLowerCase().split('_');
9+
var buffer = StringBuffer();
10+
var i = 0;
11+
// Preserve initial '_'s
12+
while (i < parts.length - 1 && parts[i].isEmpty) {
13+
buffer.write('_');
14+
++i;
15+
}
16+
if (i < parts.length) {
17+
// Convert first word to lower case
18+
buffer.write(parts[i].toLowerCase());
19+
++i;
20+
// Convert remaining words to initial upper case
21+
while (i < parts.length) {
22+
var part = parts[i];
23+
if (part.isNotEmpty) {
24+
buffer.write(part[0].toUpperCase());
25+
buffer.write(part.substring(1));
26+
}
27+
++i;
28+
}
29+
}
30+
return buffer.toString();
31+
}
32+
33+
/// Converts `SCREAMING_SNAKE_CASE` or `snake_case` to `PascalCase`.
34+
String toPascalCase() {
35+
var parts = toLowerCase().split('_');
36+
var buffer = StringBuffer();
37+
var i = 0;
38+
// Preserve initial '_'s
39+
while (i < parts.length - 1 && parts[i].isEmpty) {
40+
buffer.write('_');
41+
++i;
42+
}
43+
// Convert words to initial upper case
44+
while (i < parts.length) {
45+
var part = parts[i];
46+
if (part.isNotEmpty) {
47+
buffer.write(part[0].toUpperCase());
48+
buffer.write(part.substring(1));
49+
}
50+
++i;
51+
}
52+
return buffer.toString();
53+
}
54+
}

pkg/analyzer_utilities/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ dependencies:
2020
# Use 'any' constraints here; we get our versions from the DEPS file.
2121
dev_dependencies:
2222
lints: any
23+
test_reflective_loader: any
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Conventions for tests written using `package:test_reflective_loader` aren't
6+
// compatible with the `non_constant_identifier_names` lint.
7+
// ignore_for_file: non_constant_identifier_names
8+
9+
import 'package:analyzer_utilities/extensions/string.dart';
10+
import 'package:test/test.dart';
11+
import 'package:test_reflective_loader/test_reflective_loader.dart';
12+
13+
void main() {
14+
defineReflectiveSuite(() {
15+
defineReflectiveTests(StringExtensionTest);
16+
});
17+
}
18+
19+
@reflectiveTest
20+
class StringExtensionTest {
21+
void test_toCamelCase() {
22+
expect('CAMEL_CASE'.toCamelCase(), 'camelCase');
23+
expect('alreadyCamel_case'.toCamelCase(), 'alreadycamelCase');
24+
expect('FOO_123_BAR'.toCamelCase(), 'foo123Bar');
25+
expect('FOO'.toCamelCase(), 'foo');
26+
expect('___'.toCamelCase(), '___');
27+
expect(''.toCamelCase(), '');
28+
expect('_FOO_BAR'.toCamelCase(), '_fooBar');
29+
expect('FOO__BAR'.toCamelCase(), 'fooBar');
30+
expect('FOO_BAR_'.toCamelCase(), 'fooBar');
31+
}
32+
33+
void test_toPascalCase() {
34+
expect('PASCAL_CASE'.toPascalCase(), 'PascalCase');
35+
expect('AlreadyPascal_case'.toPascalCase(), 'AlreadypascalCase');
36+
expect('FOO_123_BAR'.toPascalCase(), 'Foo123Bar');
37+
expect('FOO'.toPascalCase(), 'Foo');
38+
expect('___'.toPascalCase(), '___');
39+
expect(''.toPascalCase(), '');
40+
expect('_FOO_BAR'.toPascalCase(), '_FooBar');
41+
expect('FOO__BAR'.toPascalCase(), 'FooBar');
42+
expect('FOO_BAR_'.toPascalCase(), 'FooBar');
43+
}
44+
}

0 commit comments

Comments
 (0)