Fix rename_to_camel_case to handle screaming caps Change-Id: I04564db1c4f47be18949cf16dcf42230db0da6e5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252562 Reviewed-by: Phil Quitslund <pquitslund@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart index 3323ec6..83f4f0a 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
@@ -5,7 +5,7 @@ import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart'; import 'package:analysis_server/src/services/correction/fix.dart'; import 'package:analysis_server/src/services/correction/util.dart'; -import 'package:analysis_server/src/utilities/strings.dart'; +import 'package:analysis_server/src/utilities/extensions/string.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; @@ -39,11 +39,11 @@ } // Prepare the new name. - var words = identifier.name.split('_'); - if (words.length < 2) { + var newName = identifier.name.toLowerCamelCase; + if (newName == null) { return; } - _newName = words.first + words.skip(1).map((w) => capitalize(w)).join(); + _newName = newName; // Find references to the identifier. List<SimpleIdentifier>? references;
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/string.dart b/pkg/analysis_server/lib/src/utilities/extensions/string.dart new file mode 100644 index 0000000..6e9d46f --- /dev/null +++ b/pkg/analysis_server/lib/src/utilities/extensions/string.dart
@@ -0,0 +1,44 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +extension StringExtension on String { + /// Assuming that the receiver is a valid identifier, return a lowerCamelCase + /// version of the identifier. + /// + /// No checks are made that the receiver is a valid identifier, but the + /// receiver must contain at least one underscore (but neither at the + /// beginning nor the end), and must not have two adjacent underscores. + /// + /// The resulting identifier is one in which only the letters following the + /// underscores are capitalized. + String? get toLowerCamelCase { + var words = split('_'); + if (words.length < 2) { + return null; + } + var firstWord = words.first; + if (firstWord.isEmpty) { + return null; + } + var buffer = StringBuffer(); + buffer.write(firstWord.toLowerCase()); + for (var i = 1; i < words.length; i++) { + var word = words[i]; + if (word.isEmpty) { + return null; + } + buffer.write(word._capitalized); + } + return buffer.toString(); + } + + /// Return a version of this string in which the first character is upper case + /// and all remaining characters are lower case. + String get _capitalized { + if (length <= 1) { + return toUpperCase(); + } + return substring(0, 1).toUpperCase() + substring(1).toLowerCase(); + } +}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart index a658d2d..a70faee 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
@@ -104,6 +104,19 @@ '''); } + Future<void> test_parameter_function_screamingCaps() async { + await resolveTestCode(''' +void f(int FIRST_PARAMETER) { + print(FIRST_PARAMETER); +} +'''); + await assertHasFix(''' +void f(int firstParameter) { + print(firstParameter); +} +'''); + } + Future<void> test_parameter_method() async { await resolveTestCode(''' class A {
diff --git a/pkg/analysis_server/test/src/utilities/extensions/string_test.dart b/pkg/analysis_server/test/src/utilities/extensions/string_test.dart new file mode 100644 index 0000000..8f7c1ec --- /dev/null +++ b/pkg/analysis_server/test/src/utilities/extensions/string_test.dart
@@ -0,0 +1,40 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/src/utilities/extensions/string.dart'; +import 'package:test/test.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +void main() { + defineReflectiveSuite(() { + defineReflectiveTests(ToLowerCamelCaseTest); + }); +} + +@reflectiveTest +class ToLowerCamelCaseTest { + void test_adjacentUnderscores() { + expect('a__b'.toLowerCamelCase, null); + } + + void test_empty() { + expect(''.toLowerCamelCase, null); + } + + void test_leadingUnderscore() { + expect('_a'.toLowerCamelCase, null); + } + + void test_screamingCaps() { + expect('AA_BB'.toLowerCamelCase, 'aaBb'); + } + + void test_snakeCase() { + expect('aa_bb'.toLowerCamelCase, 'aaBb'); + } + + void test_trailingUnderscore() { + expect('a_'.toLowerCamelCase, null); + } +}
diff --git a/pkg/analysis_server/test/src/utilities/extensions/test_all.dart b/pkg/analysis_server/test/src/utilities/extensions/test_all.dart index d4620d4..e3dbeea2 100644 --- a/pkg/analysis_server/test/src/utilities/extensions/test_all.dart +++ b/pkg/analysis_server/test/src/utilities/extensions/test_all.dart
@@ -5,9 +5,11 @@ import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'range_factory_test.dart' as range_factory; +import 'string_test.dart' as string; void main() { defineReflectiveSuite(() { range_factory.main(); + string.main(); }); }