Chromium Code Reviews| 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..26e00147720eb500fed184f17e1704d2b8e37f34 |
| --- /dev/null |
| +++ b/tools/clang/rewrite_to_chrome_style/Renamer.cpp |
| @@ -0,0 +1,103 @@ |
| +// 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 { |
| + |
| +using WordList = llvm::SmallVector<llvm::StringRef, 6>; |
| + |
| +WordList SplitIdentifier(llvm::StringRef input) { |
| + assert(input.size() > 0); |
| + |
| + WordList output; |
| + for (size_t i = 0; i < input.size(); ) { |
| + size_t start = i; |
| + size_t end = input.size(); |
| + bool was_lowercase = clang::isLowercase(input[start]); |
| + bool was_uppercase = clang::isUppercase(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; |
| + } |
| + |
| + bool is_lowercase = clang::isLowercase(input[i]); |
| + bool is_uppercase = clang::isUppercase(input[i]); |
| + // Non-acronym case: the next uppercase letter is the beginning of the |
| + // next word. |
| + if (was_lowercase && is_uppercase) { |
|
danakj
2016/01/26 21:32:10
What about V8Stuff?
8 won't be uppercase or lower
dcheng
2016/01/27 00:09:28
I made a small tweak so this gets handled correctl
|
| + end = i; |
| + break; |
| + } |
| + // End of ACRONYM case: |
| + if (in_acronym && was_uppercase && is_lowercase) { |
| + --i; // Already iterated into the next word, so backtrack. |
|
danakj
2016/01/26 21:32:10
Should it in_acronym = false?
dcheng
2016/01/27 00:09:28
This is scoped to the body of the outermost for lo
|
| + end = i; |
| + break; |
| + } |
| + // Seeing two consecutive uppercase letters indicates that this is |
| + // probably part of an acronym. |
|
danakj
2016/01/26 21:32:10
Heh, except AThing. I wonder if that happens..
It
dcheng
2016/01/27 00:09:28
This is OK though: we'll mark this as being in an
|
| + if (was_uppercase && is_uppercase) { |
| + in_acronym = true; |
| + // Intentionally fallthrough, so casing state is updated. |
| + } |
| + |
| + was_lowercase = is_lowercase; |
| + was_uppercase = is_uppercase; |
| + } |
| + // TODO(dcheng): Special acronym handling here. |
| + output.emplace_back(input.substr(start, end - start)); |
| + } |
| + |
| + return output; |
| +} |
| + |
| +} // 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; |
| +} |