| Index: tools/clang/rewrite_to_chrome_style/Renamer.cpp
|
| diff --git a/tools/clang/rewrite_to_chrome_style/Renamer.cpp b/tools/clang/rewrite_to_chrome_style/Renamer.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b3fd8afdb2061e2e8bf45b7300207fb5eff3c107
|
| --- /dev/null
|
| +++ b/tools/clang/rewrite_to_chrome_style/Renamer.cpp
|
| @@ -0,0 +1,147 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "Renamer.h"
|
| +
|
| +#include <assert.h>
|
| +
|
| +#include "clang/Basic/CharInfo.h"
|
| +#include "llvm/ADT/SmallVector.h"
|
| +
|
| +namespace {
|
| +
|
| +enum class Case {
|
| + NEITHER,
|
| + LOWER,
|
| + UPPER,
|
| +};
|
| +
|
| +using WordList = llvm::SmallVector<llvm::StringRef, 6>;
|
| +
|
| +Case DetermineCase(char c) {
|
| + if (clang::isUppercase(c))
|
| + return Case::UPPER;
|
| + if (clang::isLowercase(c))
|
| + return Case::LOWER;
|
| + return Case::NEITHER;
|
| +}
|
| +
|
| +// True if the input only contains letters of one case.
|
| +bool CanSplitWithUnderscores(llvm::StringRef input) {
|
| + Case expected_case = Case::NEITHER;
|
| + for (size_t i = 0; i < input.size(); ++i) {
|
| + Case current_case = DetermineCase(input[i]);
|
| + if (expected_case == Case::NEITHER) {
|
| + expected_case = current_case;
|
| + continue;
|
| + }
|
| + if (current_case == Case::NEITHER)
|
| + continue;
|
| + if (expected_case != current_case)
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +WordList SplitWithUnderscores(llvm::StringRef input) {
|
| + WordList output;
|
| + input.split(output, "_", -1, false /*KeepEmpty*/);
|
| + return output;
|
| +}
|
| +
|
| +// Most identifiers in Blink use CamelCase, but some (incorrectly) mix in
|
| +// underscores. In that case, split into words, using uppercase letters and
|
| +// underscores signal the start of the next word, while trying to handle
|
| +// acronyms.
|
| +WordList SplitWithHeuristics(llvm::StringRef input) {
|
| + WordList output;
|
| + for (size_t i = 0; i < input.size();) {
|
| + size_t start = i;
|
| + size_t end = input.size();
|
| + Case previous_case = DetermineCase(input[start]);
|
| + bool in_acronym = false;
|
| +
|
| + // Find the next "meaningful" uppercase letter or underscore.
|
| + for (++i; i < input.size(); ++i) {
|
| + // Underscore case: assume underscores always separate two words.
|
| + if (input[i] == '_') {
|
| + end = i;
|
| + ++i; // Skip the underscore.
|
| + break;
|
| + }
|
| +
|
| + Case current_case = DetermineCase(input[i]);
|
| + // Non-acronym case: the next uppercase letter is the beginning of the
|
| + // next word.
|
| + if (previous_case != Case::UPPER && current_case == Case::UPPER) {
|
| + end = i;
|
| + break;
|
| + }
|
| + // End of ACRONYM case:
|
| + if (in_acronym && previous_case == Case::UPPER &&
|
| + current_case == Case::LOWER) {
|
| + --i; // Already iterated into the next word, so backtrack.
|
| + end = i;
|
| + break;
|
| + }
|
| + // Seeing a non-uppercase letter after an uppercase letter means this is
|
| + // probably part of an acronym.
|
| + if (previous_case == Case::UPPER && current_case != Case::LOWER) {
|
| + in_acronym = true;
|
| + // Intentionally fallthrough, so casing state is updated.
|
| + }
|
| +
|
| + previous_case = current_case;
|
| + }
|
| + // TODO(dcheng): Special acronym handling here.
|
| + output.emplace_back(input.substr(start, end - start));
|
| + }
|
| + return output;
|
| +}
|
| +
|
| +WordList SplitIdentifier(llvm::StringRef input) {
|
| + assert(input.size() > 0);
|
| +
|
| + if (CanSplitWithUnderscores(input))
|
| + return SplitWithUnderscores(input);
|
| +
|
| + return SplitWithHeuristics(input);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +std::string IdentifierToCamelCase(llvm::StringRef input) {
|
| + WordList words = SplitIdentifier(input);
|
| + std::string output;
|
| + for (const auto& word : words) {
|
| + output += clang::toUppercase(word[0]);
|
| + for (size_t i = 1; i < word.size(); ++i)
|
| + output += clang::toLowercase(word[i]);
|
| + }
|
| + return output;
|
| +}
|
| +
|
| +std::string IdentifierToUnderscoreCase(llvm::StringRef input) {
|
| + WordList words = SplitIdentifier(input);
|
| + std::string output;
|
| + for (const auto& word : words) {
|
| + if (!output.empty())
|
| + output += '_';
|
| + for (size_t i = 0; i < word.size(); ++i)
|
| + output += clang::toLowercase(word[i]);
|
| + }
|
| + return output;
|
| +}
|
| +
|
| +std::string identifierToShoutyCase(llvm::StringRef input) {
|
| + WordList words = SplitIdentifier(input);
|
| + std::string output;
|
| + for (const auto& word : words) {
|
| + if (!output.empty())
|
| + output += '_';
|
| + for (size_t i = 0; i < word.size(); ++i)
|
| + output += clang::toUppercase(word[i]);
|
| + }
|
| + return output;
|
| +}
|
|
|