| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Changes Blink-style names to Chrome-style names. Currently transforms: | 5 // Changes Blink-style names to Chrome-style names. Currently transforms: |
| 6 // fields: | 6 // fields: |
| 7 // int m_operationCount => int operation_count_ | 7 // int m_operationCount => int operation_count_ |
| 8 // variables (including parameters): | 8 // variables (including parameters): |
| 9 // int mySuperVariable => int my_super_variable | 9 // int mySuperVariable => int my_super_variable |
| 10 // constants: | 10 // constants: |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "clang/ASTMatchers/ASTMatchersMacros.h" | 26 #include "clang/ASTMatchers/ASTMatchersMacros.h" |
| 27 #include "clang/Basic/CharInfo.h" | 27 #include "clang/Basic/CharInfo.h" |
| 28 #include "clang/Basic/SourceManager.h" | 28 #include "clang/Basic/SourceManager.h" |
| 29 #include "clang/Frontend/FrontendActions.h" | 29 #include "clang/Frontend/FrontendActions.h" |
| 30 #include "clang/Lex/Lexer.h" | 30 #include "clang/Lex/Lexer.h" |
| 31 #include "clang/Tooling/CommonOptionsParser.h" | 31 #include "clang/Tooling/CommonOptionsParser.h" |
| 32 #include "clang/Tooling/Refactoring.h" | 32 #include "clang/Tooling/Refactoring.h" |
| 33 #include "clang/Tooling/Tooling.h" | 33 #include "clang/Tooling/Tooling.h" |
| 34 #include "llvm/Support/CommandLine.h" | 34 #include "llvm/Support/CommandLine.h" |
| 35 #include "llvm/Support/TargetSelect.h" | 35 #include "llvm/Support/TargetSelect.h" |
| 36 #include "tools/clang/rewrite_to_chrome_style/Renamer.h" |
| 36 | 37 |
| 37 using namespace clang::ast_matchers; | 38 using namespace clang::ast_matchers; |
| 38 using clang::tooling::CommonOptionsParser; | 39 using clang::tooling::CommonOptionsParser; |
| 39 using clang::tooling::Replacement; | 40 using clang::tooling::Replacement; |
| 40 using clang::tooling::Replacements; | 41 using clang::tooling::Replacements; |
| 41 using llvm::StringRef; | 42 using llvm::StringRef; |
| 42 | 43 |
| 43 namespace { | 44 namespace { |
| 44 | 45 |
| 45 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { | 46 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { |
| 46 return Node.isOverloadedOperator(); | 47 return Node.isOverloadedOperator(); |
| 47 } | 48 } |
| 48 | 49 |
| 49 constexpr char kBlinkFieldPrefix[] = "m_"; | 50 constexpr char kBlinkFieldPrefix[] = "m_"; |
| 50 constexpr char kBlinkStaticMemberPrefix[] = "s_"; | 51 constexpr char kBlinkStaticMemberPrefix[] = "s_"; |
| 51 | 52 |
| 52 bool GetNameForDecl(const clang::FunctionDecl& decl, std::string& name) { | 53 bool GetNameForDecl(const clang::FunctionDecl& decl, std::string& name) { |
| 53 name = decl.getNameAsString(); | 54 name = IdentifierToCamelCase(decl.getName()); |
| 54 name[0] = clang::toUppercase(name[0]); | |
| 55 return true; | 55 return true; |
| 56 } | 56 } |
| 57 | 57 |
| 58 // Helper to convert from a camelCaseName to camel_case_name. It uses some | |
| 59 // heuristics to try to handle acronyms in camel case names correctly. | |
| 60 std::string CamelCaseToUnderscoreCase(StringRef input) { | |
| 61 std::string output; | |
| 62 bool needs_underscore = false; | |
| 63 bool was_lowercase = false; | |
| 64 bool was_uppercase = false; | |
| 65 // Iterate in reverse to minimize the amount of backtracking. | |
| 66 for (const unsigned char* i = input.bytes_end() - 1; i >= input.bytes_begin(); | |
| 67 --i) { | |
| 68 char c = *i; | |
| 69 bool is_lowercase = clang::isLowercase(c); | |
| 70 bool is_uppercase = clang::isUppercase(c); | |
| 71 c = clang::toLowercase(c); | |
| 72 // Transitioning from upper to lower case requires an underscore. This is | |
| 73 // needed to handle names with acronyms, e.g. handledHTTPRequest needs a '_' | |
| 74 // in 'dH'. This is a complement to the non-acronym case further down. | |
| 75 if (needs_underscore || (was_uppercase && is_lowercase)) { | |
| 76 output += '_'; | |
| 77 needs_underscore = false; | |
| 78 } | |
| 79 output += c; | |
| 80 // Handles the non-acronym case: transitioning from lower to upper case | |
| 81 // requires an underscore when emitting the next character, e.g. didLoad | |
| 82 // needs a '_' in 'dL'. | |
| 83 if (i != input.bytes_end() - 1 && was_lowercase && is_uppercase) | |
| 84 needs_underscore = true; | |
| 85 was_lowercase = is_lowercase; | |
| 86 was_uppercase = is_uppercase; | |
| 87 } | |
| 88 std::reverse(output.begin(), output.end()); | |
| 89 return output; | |
| 90 } | |
| 91 | |
| 92 bool GetNameForDecl(const clang::FieldDecl& decl, std::string& name) { | 58 bool GetNameForDecl(const clang::FieldDecl& decl, std::string& name) { |
| 93 StringRef original_name = decl.getName(); | 59 StringRef original_name = decl.getName(); |
| 94 // Blink style field names are prefixed with `m_`. If this prefix isn't | 60 // Blink style field names are prefixed with `m_`. If this prefix isn't |
| 95 // present, assume it's already been converted to Google style. | 61 // present, assume it's already been converted to Google style. |
| 96 if (original_name.size() < strlen(kBlinkFieldPrefix) || | 62 if (original_name.size() < strlen(kBlinkFieldPrefix) || |
| 97 !original_name.startswith(kBlinkFieldPrefix)) | 63 !original_name.startswith(kBlinkFieldPrefix)) |
| 98 return false; | 64 return false; |
| 99 name = CamelCaseToUnderscoreCase( | 65 name = IdentifierToUnderscoreCase( |
| 100 original_name.substr(strlen(kBlinkFieldPrefix))); | 66 original_name.substr(strlen(kBlinkFieldPrefix))); |
| 101 // The few examples I could find used struct-style naming with no `_` suffix | 67 // The few examples I could find used struct-style naming with no `_` suffix |
| 102 // for unions. | 68 // for unions. |
| 103 if (decl.getParent()->isClass()) | 69 if (decl.getParent()->isClass()) |
| 104 name += '_'; | 70 name += '_'; |
| 105 return true; | 71 return true; |
| 106 } | 72 } |
| 107 | 73 |
| 108 bool IsProbablyConst(const clang::VarDecl& decl) { | 74 bool IsProbablyConst(const clang::VarDecl& decl) { |
| 109 clang::QualType type = decl.getType(); | 75 clang::QualType type = decl.getType(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix)); | 121 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix)); |
| 156 else if (original_name.startswith(kBlinkFieldPrefix)) | 122 else if (original_name.startswith(kBlinkFieldPrefix)) |
| 157 original_name = original_name.substr(strlen(kBlinkFieldPrefix)); | 123 original_name = original_name.substr(strlen(kBlinkFieldPrefix)); |
| 158 | 124 |
| 159 if (IsProbablyConst(decl)) { | 125 if (IsProbablyConst(decl)) { |
| 160 // Don't try to rename constants that already conform to Chrome style. | 126 // Don't try to rename constants that already conform to Chrome style. |
| 161 if (original_name.size() >= 2 && original_name[0] == 'k' && | 127 if (original_name.size() >= 2 && original_name[0] == 'k' && |
| 162 clang::isUppercase(original_name[1])) | 128 clang::isUppercase(original_name[1])) |
| 163 return false; | 129 return false; |
| 164 name = 'k'; | 130 name = 'k'; |
| 165 name.append(original_name.data(), original_name.size()); | 131 name += IdentifierToCamelCase(original_name); |
| 166 name[1] = clang::toUppercase(name[1]); | |
| 167 } else { | 132 } else { |
| 168 name = CamelCaseToUnderscoreCase(original_name); | 133 name = IdentifierToUnderscoreCase(original_name); |
| 169 } | 134 } |
| 170 | 135 |
| 171 if (decl.isStaticDataMember()) { | 136 if (decl.isStaticDataMember()) { |
| 172 name += '_'; | 137 name += '_'; |
| 173 } | 138 } |
| 174 | 139 |
| 175 return true; | 140 return true; |
| 176 } | 141 } |
| 177 | 142 |
| 178 template <typename Type> | 143 template <typename Type> |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 for (const auto& r : replacements) { | 500 for (const auto& r : replacements) { |
| 536 std::string replacement_text = r.getReplacementText().str(); | 501 std::string replacement_text = r.getReplacementText().str(); |
| 537 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 502 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 538 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 503 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 539 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 504 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 540 } | 505 } |
| 541 llvm::outs() << "==== END EDITS ====\n"; | 506 llvm::outs() << "==== END EDITS ====\n"; |
| 542 | 507 |
| 543 return 0; | 508 return 0; |
| 544 } | 509 } |
| OLD | NEW |