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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { | 45 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { |
46 return Node.isOverloadedOperator(); | 46 return Node.isOverloadedOperator(); |
47 } | 47 } |
48 | 48 |
49 constexpr char kBlinkFieldPrefix[] = "m_"; | 49 constexpr char kBlinkFieldPrefix[] = "m_"; |
50 constexpr char kBlinkStaticMemberPrefix[] = "s_"; | 50 constexpr char kBlinkStaticMemberPrefix[] = "s_"; |
51 | 51 |
52 bool GetNameForDecl(const clang::FunctionDecl& decl, std::string& name) { | 52 bool GetNameForDecl(const clang::FunctionDecl& decl, |
| 53 const clang::ASTContext& context, |
| 54 std::string& name) { |
53 name = decl.getNameAsString(); | 55 name = decl.getNameAsString(); |
54 name[0] = clang::toUppercase(name[0]); | 56 name[0] = clang::toUppercase(name[0]); |
55 return true; | 57 return true; |
56 } | 58 } |
57 | 59 |
58 // Helper to convert from a camelCaseName to camel_case_name. It uses some | 60 // 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. | 61 // heuristics to try to handle acronyms in camel case names correctly. |
60 std::string CamelCaseToUnderscoreCase(StringRef input) { | 62 std::string CamelCaseToUnderscoreCase(StringRef input) { |
61 std::string output; | 63 std::string output; |
62 bool needs_underscore = false; | 64 bool needs_underscore = false; |
(...skipping 19 matching lines...) Expand all Loading... |
82 // needs a '_' in 'dL'. | 84 // needs a '_' in 'dL'. |
83 if (i != input.bytes_end() - 1 && was_lowercase && is_uppercase) | 85 if (i != input.bytes_end() - 1 && was_lowercase && is_uppercase) |
84 needs_underscore = true; | 86 needs_underscore = true; |
85 was_lowercase = is_lowercase; | 87 was_lowercase = is_lowercase; |
86 was_uppercase = is_uppercase; | 88 was_uppercase = is_uppercase; |
87 } | 89 } |
88 std::reverse(output.begin(), output.end()); | 90 std::reverse(output.begin(), output.end()); |
89 return output; | 91 return output; |
90 } | 92 } |
91 | 93 |
92 bool GetNameForDecl(const clang::FieldDecl& decl, std::string& name) { | 94 bool GetNameForDecl(const clang::FieldDecl& decl, |
| 95 const clang::ASTContext& context, |
| 96 std::string& name) { |
93 StringRef original_name = decl.getName(); | 97 StringRef original_name = decl.getName(); |
94 // Blink style field names are prefixed with `m_`. If this prefix isn't | 98 // Blink style field names are prefixed with `m_`. If this prefix isn't |
95 // present, assume it's already been converted to Google style. | 99 // present, assume it's already been converted to Google style. |
96 if (original_name.size() < strlen(kBlinkFieldPrefix) || | 100 if (original_name.size() < strlen(kBlinkFieldPrefix) || |
97 !original_name.startswith(kBlinkFieldPrefix)) | 101 !original_name.startswith(kBlinkFieldPrefix)) |
98 return false; | 102 return false; |
99 name = CamelCaseToUnderscoreCase( | 103 name = CamelCaseToUnderscoreCase( |
100 original_name.substr(strlen(kBlinkFieldPrefix))); | 104 original_name.substr(strlen(kBlinkFieldPrefix))); |
101 // The few examples I could find used struct-style naming with no `_` suffix | 105 // The few examples I could find used struct-style naming with no `_` suffix |
102 // for unions. | 106 // for unions. |
103 if (decl.getParent()->isClass()) | 107 if (decl.getParent()->isClass()) |
104 name += '_'; | 108 name += '_'; |
105 return true; | 109 return true; |
106 } | 110 } |
107 | 111 |
108 bool IsProbablyConst(const clang::VarDecl& decl) { | 112 bool IsProbablyConst(const clang::VarDecl& decl, |
| 113 const clang::ASTContext& context) { |
109 clang::QualType type = decl.getType(); | 114 clang::QualType type = decl.getType(); |
110 if (!type.isConstQualified()) | 115 if (!type.isConstQualified()) |
111 return false; | 116 return false; |
112 | 117 |
113 if (type.isVolatileQualified()) | 118 if (type.isVolatileQualified()) |
114 return false; | 119 return false; |
115 | 120 |
116 // http://google.github.io/styleguide/cppguide.html#Constant_Names | 121 // http://google.github.io/styleguide/cppguide.html#Constant_Names |
117 // Static variables that are const-qualified should use kConstantStyle naming. | 122 // Static variables that are const-qualified should use kConstantStyle naming. |
118 if (decl.getStorageDuration() == clang::SD_Static) | 123 if (decl.getStorageDuration() == clang::SD_Static) |
119 return true; | 124 return true; |
120 | 125 |
121 // Otherwise, use a simple heuristic: if it's initialized with a literal of | |
122 // some sort, also use kConstantStyle naming. | |
123 const clang::Expr* initializer = decl.getInit(); | 126 const clang::Expr* initializer = decl.getInit(); |
124 if (!initializer) | 127 if (!initializer) |
125 return false; | 128 return false; |
126 | 129 |
127 // Ignore implicit casts, so the literal check below still matches on | 130 // If the expression can be evaluated at compile time, then it should have a |
128 // array-to-pointer decay, e.g. | 131 // kFoo style name. Otherwise, not. |
129 // const char* const kConst = "..."; | 132 return initializer->isEvaluatable(context); |
130 if (const clang::ImplicitCastExpr* cast_expr = | |
131 clang::dyn_cast<clang::ImplicitCastExpr>(initializer)) | |
132 initializer = cast_expr->getSubExprAsWritten(); | |
133 | |
134 return clang::isa<clang::CharacterLiteral>(initializer) || | |
135 clang::isa<clang::CompoundLiteralExpr>(initializer) || | |
136 clang::isa<clang::CXXBoolLiteralExpr>(initializer) || | |
137 clang::isa<clang::CXXNullPtrLiteralExpr>(initializer) || | |
138 clang::isa<clang::FloatingLiteral>(initializer) || | |
139 clang::isa<clang::IntegerLiteral>(initializer) || | |
140 clang::isa<clang::StringLiteral>(initializer) || | |
141 clang::isa<clang::UserDefinedLiteral>(initializer); | |
142 } | 133 } |
143 | 134 |
144 bool GetNameForDecl(const clang::VarDecl& decl, std::string& name) { | 135 bool GetNameForDecl(const clang::VarDecl& decl, |
| 136 const clang::ASTContext& context, |
| 137 std::string& name) { |
145 StringRef original_name = decl.getName(); | 138 StringRef original_name = decl.getName(); |
146 | 139 |
147 // Nothing to do for unnamed parameters. | 140 // Nothing to do for unnamed parameters. |
148 if (clang::isa<clang::ParmVarDecl>(decl) && original_name.empty()) | 141 if (clang::isa<clang::ParmVarDecl>(decl) && original_name.empty()) |
149 return false; | 142 return false; |
150 | 143 |
151 // static class members match against VarDecls. Blink style dictates that | 144 // static class members match against VarDecls. Blink style dictates that |
152 // these should be prefixed with `s_`, so strip that off. Also check for `m_` | 145 // these should be prefixed with `s_`, so strip that off. Also check for `m_` |
153 // and strip that off too, for code that accidentally uses the wrong prefix. | 146 // and strip that off too, for code that accidentally uses the wrong prefix. |
154 if (original_name.startswith(kBlinkStaticMemberPrefix)) | 147 if (original_name.startswith(kBlinkStaticMemberPrefix)) |
155 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix)); | 148 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix)); |
156 else if (original_name.startswith(kBlinkFieldPrefix)) | 149 else if (original_name.startswith(kBlinkFieldPrefix)) |
157 original_name = original_name.substr(strlen(kBlinkFieldPrefix)); | 150 original_name = original_name.substr(strlen(kBlinkFieldPrefix)); |
158 | 151 |
159 if (IsProbablyConst(decl)) { | 152 if (IsProbablyConst(decl, context)) { |
160 // Don't try to rename constants that already conform to Chrome style. | 153 // Don't try to rename constants that already conform to Chrome style. |
161 if (original_name.size() >= 2 && original_name[0] == 'k' && | 154 if (original_name.size() >= 2 && original_name[0] == 'k' && |
162 clang::isUppercase(original_name[1])) | 155 clang::isUppercase(original_name[1])) |
163 return false; | 156 return false; |
164 name = 'k'; | 157 name = 'k'; |
165 name.append(original_name.data(), original_name.size()); | 158 name.append(original_name.data(), original_name.size()); |
166 name[1] = clang::toUppercase(name[1]); | 159 name[1] = clang::toUppercase(name[1]); |
167 } else { | 160 } else { |
168 name = CamelCaseToUnderscoreCase(original_name); | 161 name = CamelCaseToUnderscoreCase(original_name); |
169 } | 162 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 210 |
218 template <typename DeclNode, typename TargetNode> | 211 template <typename DeclNode, typename TargetNode> |
219 class RewriterBase : public MatchFinder::MatchCallback { | 212 class RewriterBase : public MatchFinder::MatchCallback { |
220 public: | 213 public: |
221 explicit RewriterBase(Replacements* replacements) | 214 explicit RewriterBase(Replacements* replacements) |
222 : replacements_(replacements) {} | 215 : replacements_(replacements) {} |
223 | 216 |
224 void run(const MatchFinder::MatchResult& result) override { | 217 void run(const MatchFinder::MatchResult& result) override { |
225 std::string name; | 218 std::string name; |
226 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); | 219 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); |
227 if (!GetNameForDecl(*decl, name)) | 220 clang::ASTContext* context = result.Context; |
| 221 if (!GetNameForDecl(*decl, *context, name)) |
228 return; | 222 return; |
229 auto r = replacements_->emplace( | 223 auto r = replacements_->emplace( |
230 *result.SourceManager, TargetNodeTraits<TargetNode>::GetRange( | 224 *result.SourceManager, TargetNodeTraits<TargetNode>::GetRange( |
231 *result.Nodes.getNodeAs<TargetNode>( | 225 *result.Nodes.getNodeAs<TargetNode>( |
232 TargetNodeTraits<TargetNode>::kName)), | 226 TargetNodeTraits<TargetNode>::kName)), |
233 name); | 227 name); |
234 auto from = decl->getNameAsString(); | 228 auto from = decl->getNameAsString(); |
235 auto to = r.first->getReplacementText().str(); | 229 auto to = r.first->getReplacementText().str(); |
236 if (from != to) | 230 if (from != to) |
237 replacement_names_.emplace(std::move(from), std::move(to)); | 231 replacement_names_.emplace(std::move(from), std::move(to)); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 for (const auto& r : replacements) { | 523 for (const auto& r : replacements) { |
530 std::string replacement_text = r.getReplacementText().str(); | 524 std::string replacement_text = r.getReplacementText().str(); |
531 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 525 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
532 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 526 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
533 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 527 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
534 } | 528 } |
535 llvm::outs() << "==== END EDITS ====\n"; | 529 llvm::outs() << "==== END EDITS ====\n"; |
536 | 530 |
537 return 0; | 531 return 0; |
538 } | 532 } |
OLD | NEW |