Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp

Issue 1638683002: rewrite_to_chrome_style: Check expression is const when deciding style (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698