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

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

Issue 1557243002: Update rewrite_to_chrome_style tool to also rename methods. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Group more logically Created 4 years, 11 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
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: 8 // variables (including parameters):
9 // int mySuperVariable => int my_super_variable 9 // int mySuperVariable => int my_super_variable
10 // constants: 10 // constants:
11 // const int maxThings => const int kMaxThings 11 // const int maxThings => const int kMaxThings
danakj 2016/01/06 22:09:40 there are at least some constants named MaxThings.
dcheng 2016/01/08 01:41:11 It should (the heuristics for using kConstantStyle
12 // free functions: 12 // free functions and methods:
13 // void doThisThenThat() => void DoThisAndThat() 13 // void doThisThenThat() => void DoThisAndThat()
14 14
15 #include <assert.h>
15 #include <algorithm> 16 #include <algorithm>
16 #include <memory> 17 #include <memory>
17 #include <string> 18 #include <string>
19 #include <unordered_set>
18 20
19 #include "clang/AST/ASTContext.h" 21 #include "clang/AST/ASTContext.h"
20 #include "clang/ASTMatchers/ASTMatchFinder.h" 22 #include "clang/ASTMatchers/ASTMatchFinder.h"
21 #include "clang/ASTMatchers/ASTMatchers.h" 23 #include "clang/ASTMatchers/ASTMatchers.h"
22 #include "clang/ASTMatchers/ASTMatchersMacros.h" 24 #include "clang/ASTMatchers/ASTMatchersMacros.h"
23 #include "clang/Basic/CharInfo.h" 25 #include "clang/Basic/CharInfo.h"
24 #include "clang/Basic/SourceManager.h" 26 #include "clang/Basic/SourceManager.h"
25 #include "clang/Frontend/FrontendActions.h" 27 #include "clang/Frontend/FrontendActions.h"
26 #include "clang/Lex/Lexer.h" 28 #include "clang/Lex/Lexer.h"
27 #include "clang/Tooling/CommonOptionsParser.h" 29 #include "clang/Tooling/CommonOptionsParser.h"
28 #include "clang/Tooling/Refactoring.h" 30 #include "clang/Tooling/Refactoring.h"
29 #include "clang/Tooling/Tooling.h" 31 #include "clang/Tooling/Tooling.h"
30 #include "llvm/Support/CommandLine.h" 32 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/TargetSelect.h" 33 #include "llvm/Support/TargetSelect.h"
32 34
33 using namespace clang::ast_matchers; 35 using namespace clang::ast_matchers;
34 using clang::tooling::CommonOptionsParser; 36 using clang::tooling::CommonOptionsParser;
35 using clang::tooling::Replacement; 37 using clang::tooling::Replacement;
36 using clang::tooling::Replacements; 38 using clang::tooling::Replacements;
37 using llvm::StringRef; 39 using llvm::StringRef;
38 40
39 namespace { 41 namespace {
40 42
43 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) {
44 return Node.isOverloadedOperator();
45 }
46
41 constexpr char kBlinkFieldPrefix[] = "m_"; 47 constexpr char kBlinkFieldPrefix[] = "m_";
42 constexpr char kBlinkStaticMemberPrefix[] = "s_"; 48 constexpr char kBlinkStaticMemberPrefix[] = "s_";
43 49
44 bool GetNameForDecl(const clang::FunctionDecl& decl, 50 bool GetNameForDecl(const clang::FunctionDecl& decl, std::string& name) {
45 clang::ASTContext* context,
46 std::string& name) {
47 name = decl.getNameAsString(); 51 name = decl.getNameAsString();
48 name[0] = clang::toUppercase(name[0]); 52 name[0] = clang::toUppercase(name[0]);
49 return true; 53 return true;
50 } 54 }
51 55
52 // Helper to convert from a camelCaseName to camel_case_name. It uses some 56 // Helper to convert from a camelCaseName to camel_case_name. It uses some
53 // heuristics to try to handle acronyms in camel case names correctly. 57 // heuristics to try to handle acronyms in camel case names correctly.
54 std::string CamelCaseToUnderscoreCase(StringRef input) { 58 std::string CamelCaseToUnderscoreCase(StringRef input) {
55 std::string output; 59 std::string output;
56 bool needs_underscore = false; 60 bool needs_underscore = false;
(...skipping 19 matching lines...) Expand all
76 // needs a '_' in 'dL'. 80 // needs a '_' in 'dL'.
77 if (i != input.bytes_end() - 1 && was_lowercase && is_uppercase) 81 if (i != input.bytes_end() - 1 && was_lowercase && is_uppercase)
78 needs_underscore = true; 82 needs_underscore = true;
79 was_lowercase = is_lowercase; 83 was_lowercase = is_lowercase;
80 was_uppercase = is_uppercase; 84 was_uppercase = is_uppercase;
81 } 85 }
82 std::reverse(output.begin(), output.end()); 86 std::reverse(output.begin(), output.end());
83 return output; 87 return output;
84 } 88 }
85 89
86 bool GetNameForDecl(const clang::FieldDecl& decl, 90 bool GetNameForDecl(const clang::FieldDecl& decl, std::string& name) {
87 clang::ASTContext* context,
88 std::string& name) {
89 StringRef original_name = decl.getName(); 91 StringRef original_name = decl.getName();
90 // Blink style field names are prefixed with `m_`. If this prefix isn't 92 // Blink style field names are prefixed with `m_`. If this prefix isn't
91 // present, assume it's already been converted to Google style. 93 // present, assume it's already been converted to Google style.
92 if (original_name.size() < strlen(kBlinkFieldPrefix) || 94 if (original_name.size() < strlen(kBlinkFieldPrefix) ||
93 !original_name.startswith(kBlinkFieldPrefix)) 95 !original_name.startswith(kBlinkFieldPrefix))
94 return false; 96 return false;
95 name = CamelCaseToUnderscoreCase( 97 name = CamelCaseToUnderscoreCase(
96 original_name.substr(strlen(kBlinkFieldPrefix))); 98 original_name.substr(strlen(kBlinkFieldPrefix)));
97 // The few examples I could find used struct-style naming with no `_` suffix 99 // The few examples I could find used struct-style naming with no `_` suffix
98 // for unions. 100 // for unions.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 return clang::isa<clang::CharacterLiteral>(initializer) || 132 return clang::isa<clang::CharacterLiteral>(initializer) ||
131 clang::isa<clang::CompoundLiteralExpr>(initializer) || 133 clang::isa<clang::CompoundLiteralExpr>(initializer) ||
132 clang::isa<clang::CXXBoolLiteralExpr>(initializer) || 134 clang::isa<clang::CXXBoolLiteralExpr>(initializer) ||
133 clang::isa<clang::CXXNullPtrLiteralExpr>(initializer) || 135 clang::isa<clang::CXXNullPtrLiteralExpr>(initializer) ||
134 clang::isa<clang::FloatingLiteral>(initializer) || 136 clang::isa<clang::FloatingLiteral>(initializer) ||
135 clang::isa<clang::IntegerLiteral>(initializer) || 137 clang::isa<clang::IntegerLiteral>(initializer) ||
136 clang::isa<clang::StringLiteral>(initializer) || 138 clang::isa<clang::StringLiteral>(initializer) ||
137 clang::isa<clang::UserDefinedLiteral>(initializer); 139 clang::isa<clang::UserDefinedLiteral>(initializer);
138 } 140 }
139 141
140 bool GetNameForDecl(const clang::VarDecl& decl, 142 bool GetNameForDecl(const clang::VarDecl& decl, std::string& name) {
141 clang::ASTContext* context,
142 std::string& name) {
143 StringRef original_name = decl.getName(); 143 StringRef original_name = decl.getName();
144 144
145 // Nothing to do for unnamed parameters. 145 // Nothing to do for unnamed parameters.
146 if (clang::isa<clang::ParmVarDecl>(decl) && original_name.empty()) 146 if (clang::isa<clang::ParmVarDecl>(decl) && original_name.empty())
147 return false; 147 return false;
148 148
149 // static class members match against VarDecls. Blink style dictates that 149 // static class members match against VarDecls. Blink style dictates that
150 // these should be prefixed with `s_`, so strip that off. Also check for `m_` 150 // these should be prefixed with `s_`, so strip that off. Also check for `m_`
151 // and strip that off too, for code that accidentally uses the wrong prefix. 151 // and strip that off too, for code that accidentally uses the wrong prefix.
152 if (original_name.startswith(kBlinkStaticMemberPrefix)) 152 if (original_name.startswith(kBlinkStaticMemberPrefix))
(...skipping 13 matching lines...) Expand all
166 name = CamelCaseToUnderscoreCase(original_name); 166 name = CamelCaseToUnderscoreCase(original_name);
167 } 167 }
168 168
169 if (decl.isStaticDataMember()) { 169 if (decl.isStaticDataMember()) {
170 name += '_'; 170 name += '_';
171 } 171 }
172 172
173 return true; 173 return true;
174 } 174 }
175 175
176 template <typename DeclNodeType, typename TargetTraits> 176 template <typename Type>
177 class RewriterCallbackBase : public MatchFinder::MatchCallback { 177 struct TargetNodeTraits;
178
179 template <>
180 struct TargetNodeTraits<clang::NamedDecl> {
181 static constexpr char kName[] = "decl";
182 static clang::CharSourceRange GetRange(const clang::NamedDecl& decl) {
183 return clang::CharSourceRange::getTokenRange(decl.getLocation());
184 }
185 };
186 constexpr char TargetNodeTraits<clang::NamedDecl>::kName[];
187
188 template <>
189 struct TargetNodeTraits<clang::CallExpr> {
190 static constexpr char kName[] = "expr";
191 static clang::CharSourceRange GetRange(const clang::CallExpr& expr) {
192 return clang::CharSourceRange::getTokenRange(expr.getExprLoc());
193 }
194 };
195 constexpr char TargetNodeTraits<clang::CallExpr>::kName[];
196
197 template <>
198 struct TargetNodeTraits<clang::MemberExpr> {
199 static constexpr char kName[] = "expr";
200 static clang::CharSourceRange GetRange(const clang::MemberExpr& expr) {
201 return clang::CharSourceRange::getTokenRange(expr.getMemberLoc());
202 }
203 };
204 constexpr char TargetNodeTraits<clang::MemberExpr>::kName[];
205
206 template <>
207 struct TargetNodeTraits<clang::DeclRefExpr> {
208 static constexpr char kName[] = "expr";
209 static clang::CharSourceRange GetRange(const clang::DeclRefExpr& expr) {
210 return clang::CharSourceRange::getTokenRange(expr.getLocation());
danakj 2016/01/06 22:09:40 consider a comment on each of these why you chose
dcheng 2016/01/08 01:41:11 I'm not sure how helpful a comment would be. It's
211 }
212 };
213 constexpr char TargetNodeTraits<clang::DeclRefExpr>::kName[];
214
215 template <>
216 struct TargetNodeTraits<clang::CXXCtorInitializer> {
217 static constexpr char kName[] = "initializer";
218 static clang::CharSourceRange GetRange(
219 const clang::CXXCtorInitializer& init) {
220 return clang::CharSourceRange::getTokenRange(init.getSourceLocation());
221 }
222 };
223 constexpr char TargetNodeTraits<clang::CXXCtorInitializer>::kName[];
224
225 template <typename DeclNode, typename TargetNode>
226 class RewriterBase : public MatchFinder::MatchCallback {
178 public: 227 public:
179 explicit RewriterCallbackBase(Replacements* replacements) 228 explicit RewriterBase(Replacements* replacements)
180 : replacements_(replacements) {} 229 : replacements_(replacements) {}
181 virtual void run(const MatchFinder::MatchResult& result) override { 230
231 void run(const MatchFinder::MatchResult& result) override {
182 std::string name; 232 std::string name;
183 if (!GetNameForDecl(*result.Nodes.getNodeAs<DeclNodeType>("decl"), 233 if (!GetNameForDecl(*result.Nodes.getNodeAs<DeclNode>("decl"), name))
184 result.Context, name))
185 return; 234 return;
186 replacements_->emplace( 235 replacements_->emplace(*result.SourceManager,
187 *result.SourceManager, 236 TargetNodeTraits<TargetNode>::GetRange(
188 TargetTraits::GetRange( 237 *result.Nodes.getNodeAs<TargetNode>(
189 *result.Nodes.getNodeAs<typename TargetTraits::NodeType>( 238 TargetNodeTraits<TargetNode>::kName)),
190 TargetTraits::kName)), 239 name);
191 name);
192 } 240 }
193 241
194 private: 242 private:
195 Replacements* const replacements_; 243 Replacements* const replacements_;
196 }; 244 };
197 245
198 struct DeclTargetTraits { 246 using FieldDeclRewriter = RewriterBase<clang::FieldDecl, clang::NamedDecl>;
199 using NodeType = clang::NamedDecl; 247 using VarDeclRewriter = RewriterBase<clang::VarDecl, clang::NamedDecl>;
200 static constexpr char kName[] = "decl"; 248 using MemberRewriter = RewriterBase<clang::FieldDecl, clang::MemberExpr>;
201 static clang::CharSourceRange GetRange(const NodeType& decl) { 249 using DeclRefRewriter = RewriterBase<clang::VarDecl, clang::DeclRefExpr>;
202 return clang::CharSourceRange::getTokenRange(decl.getLocation()); 250 using ConstructorInitializerRewriter =
251 RewriterBase<clang::FieldDecl, clang::CXXCtorInitializer>;
252
253 // Helpers for rewriting functions. The tool needs to detect overrides of Blink
254 // methods, and uses two matchers to help accomplish this goal:
255 // - The first matcher matches all method declarations in Blink. When the
256 // callback rewrites the declaration, it also stores a pointer to the
257 // canonical declaration, to record it as a Blink method.
258 // - The second matcher matches all method declarations that are overrides. When
259 // the callback processes the match, it checks if its overriding a method that
260 // was marked as a Blink method. If so, it rewrites the declaration.
261 // - Because an override is determined based on inclusion in the set of Blink
262 // methods, the overridden methods matcher does not need to filter out special
263 // member functions: they get filtered out by virtue of the first matcher.
264 //
265 // This works because per the documentation on MatchFinder:
266 // The order of matches is guaranteed to be equivalent to doing a pre-order
267 // traversal on the AST, and applying the matchers in the order in which they
268 // were added to the MatchFinder.
269 //
270 // Since classes cannot forward declare their base classes, it is guaranteed
271 // that the base class methods will be seen before processing the overridden
272 // methods.
273 class FunctionDeclRewriter
274 : public RewriterBase<clang::FunctionDecl, clang::NamedDecl> {
275 public:
276 explicit FunctionDeclRewriter(Replacements* replacements)
277 : RewriterBase(replacements) {}
278
279 void run(const MatchFinder::MatchResult& result) override {
280 if (const clang::CXXMethodDecl* method_decl =
281 result.Nodes.getNodeAs<clang::CXXMethodDecl>("decl")) {
282 // TODO(dcheng): Does this need to check for the override attribute, or is
283 // this good enough?
284 if (method_decl->size_overridden_methods() > 0) {
285 if (!IsBlinkOverride(method_decl))
286 return;
287 } else {
288 blink_methods_.emplace(method_decl->getCanonicalDecl());
289 }
290 }
291
292 RewriterBase::run(result);
203 } 293 }
294
295 bool IsBlinkOverride(const clang::CXXMethodDecl* decl) const {
296 assert(decl->size_overridden_methods() > 0);
297 for (auto it = decl->begin_overridden_methods();
298 it != decl->end_overridden_methods(); ++it) {
299 if (blink_methods_.find((*it)->getCanonicalDecl()) !=
300 blink_methods_.end())
301 return true;
302 }
303 return false;
304 }
305
306 private:
307 std::unordered_set<const clang::CXXMethodDecl*> blink_methods_;
204 }; 308 };
205 constexpr char DeclTargetTraits::kName[];
206 309
207 struct ExprTargetTraits { 310 template <typename BaseRewriter>
208 using NodeType = clang::Expr; 311 class FilteringFunctionRewriter : public BaseRewriter {
209 static constexpr char kName[] = "expr"; 312 public:
210 static clang::CharSourceRange GetRange(const NodeType& expr) { 313 FilteringFunctionRewriter(const FunctionDeclRewriter& decl_rewriter,
211 return clang::CharSourceRange::getTokenRange(expr.getExprLoc()); 314 Replacements* replacements)
315 : BaseRewriter(replacements), decl_rewriter_(decl_rewriter) {}
316
317 void run(const MatchFinder::MatchResult& result) override {
318 if (const clang::CXXMethodDecl* method_decl =
319 result.Nodes.getNodeAs<clang::CXXMethodDecl>("decl")) {
320 if (method_decl->size_overridden_methods() > 0 &&
321 !decl_rewriter_.IsBlinkOverride(method_decl))
322 return;
323 }
324 BaseRewriter::run(result);
212 } 325 }
326
327 private:
328 const FunctionDeclRewriter& decl_rewriter_;
213 }; 329 };
214 constexpr char ExprTargetTraits::kName[];
215 330
216 struct InitializerTargetTraits { 331 using CallRewriter = FilteringFunctionRewriter<
217 using NodeType = clang::CXXCtorInitializer; 332 RewriterBase<clang::FunctionDecl, clang::CallExpr>>;
218 static constexpr char kName[] = "initializer"; 333 using FunctionDeclRefRewriter = FilteringFunctionRewriter<
219 static clang::CharSourceRange GetRange(const NodeType& init) { 334 RewriterBase<clang::FunctionDecl, clang::DeclRefExpr>>;
220 return clang::CharSourceRange::getTokenRange(init.getSourceLocation());
221 }
222 };
223 constexpr char InitializerTargetTraits::kName[];
224
225 using FunctionDeclRewriterCallback =
226 RewriterCallbackBase<clang::FunctionDecl, DeclTargetTraits>;
227 using FieldDeclRewriterCallback =
228 RewriterCallbackBase<clang::FieldDecl, DeclTargetTraits>;
229 using VarDeclRewriterCallback =
230 RewriterCallbackBase<clang::VarDecl, DeclTargetTraits>;
231
232 using CallRewriterCallback =
233 RewriterCallbackBase<clang::FunctionDecl, ExprTargetTraits>;
234 using MemberRewriterCallback =
235 RewriterCallbackBase<clang::FieldDecl, ExprTargetTraits>;
236 using DeclRefRewriterCallback =
237 RewriterCallbackBase<clang::VarDecl, ExprTargetTraits>;
238
239 using ConstructorInitializerRewriterCallback =
240 RewriterCallbackBase<clang::FieldDecl, InitializerTargetTraits>;
241 335
242 } // namespace 336 } // namespace
243 337
244 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); 338 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
245 339
246 int main(int argc, const char* argv[]) { 340 int main(int argc, const char* argv[]) {
247 // TODO(dcheng): Clang tooling should do this itself. 341 // TODO(dcheng): Clang tooling should do this itself.
248 // http://llvm.org/bugs/show_bug.cgi?id=21627 342 // http://llvm.org/bugs/show_bug.cgi?id=21627
249 llvm::InitializeNativeTarget(); 343 llvm::InitializeNativeTarget();
250 llvm::InitializeNativeTargetAsmParser(); 344 llvm::InitializeNativeTargetAsmParser();
251 llvm::cl::OptionCategory category( 345 llvm::cl::OptionCategory category(
252 "rewrite_to_chrome_style: convert Blink style to Chrome style."); 346 "rewrite_to_chrome_style: convert Blink style to Chrome style.");
253 CommonOptionsParser options(argc, argv, category); 347 CommonOptionsParser options(argc, argv, category);
254 clang::tooling::ClangTool tool(options.getCompilations(), 348 clang::tooling::ClangTool tool(options.getCompilations(),
255 options.getSourcePathList()); 349 options.getSourcePathList());
256 350
257 MatchFinder match_finder; 351 MatchFinder match_finder;
258 Replacements replacements; 352 Replacements replacements;
259 353
260 auto in_blink_namespace = 354 auto in_blink_namespace =
261 decl(hasAncestor(namespaceDecl(anyOf(hasName("blink"), hasName("WTF"))))); 355 decl(hasAncestor(namespaceDecl(anyOf(hasName("blink"), hasName("WTF")))));
262 356
263 // Declaration handling (e.g. function definitions and variable definitions): 357 // Declarations of fields and variables:
264
265 // Note: for now, only rewrite standalone functions until the question of JS
266 // binding integration for class methods is resolved.
267 // TODO(dcheng): Since classes in public/ aren't directly web-exposed, just go
268 // ahead and rewrite those.
269 auto function_decl_matcher =
270 id("decl", functionDecl(unless(cxxMethodDecl()), in_blink_namespace));
271
272 auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace)); 358 auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace));
273 auto var_decl_matcher = id("decl", varDecl(in_blink_namespace)); 359 auto var_decl_matcher = id("decl", varDecl(in_blink_namespace));
274 360
275 FunctionDeclRewriterCallback function_decl_rewriter(&replacements); 361 FieldDeclRewriter field_decl_rewriter(&replacements);
276 match_finder.addMatcher(function_decl_matcher, &function_decl_rewriter);
277 FieldDeclRewriterCallback field_decl_rewriter(&replacements);
278 match_finder.addMatcher(field_decl_matcher, &field_decl_rewriter); 362 match_finder.addMatcher(field_decl_matcher, &field_decl_rewriter);
279 VarDeclRewriterCallback var_decl_rewriter(&replacements); 363
364 VarDeclRewriter var_decl_rewriter(&replacements);
280 match_finder.addMatcher(var_decl_matcher, &var_decl_rewriter); 365 match_finder.addMatcher(var_decl_matcher, &var_decl_rewriter);
281 366
282 // Expression handling (e.g. calling a Blink function or referencing a 367 // References to declared fields and variables:
283 // variable defined in Blink):
284 auto call_matcher = id("expr", callExpr(callee(function_decl_matcher)));
285 auto member_matcher = id("expr", memberExpr(member(field_decl_matcher))); 368 auto member_matcher = id("expr", memberExpr(member(field_decl_matcher)));
286 auto decl_ref_matcher = id("expr", declRefExpr(to(var_decl_matcher))); 369 auto decl_ref_matcher = id("expr", declRefExpr(to(var_decl_matcher)));
287 370
288 CallRewriterCallback call_rewriter(&replacements); 371 MemberRewriter member_rewriter(&replacements);
289 match_finder.addMatcher(call_matcher, &call_rewriter);
290 MemberRewriterCallback member_rewriter(&replacements);
291 match_finder.addMatcher(member_matcher, &member_rewriter); 372 match_finder.addMatcher(member_matcher, &member_rewriter);
292 DeclRefRewriterCallback decl_ref_rewriter(&replacements); 373
374 DeclRefRewriter decl_ref_rewriter(&replacements);
293 match_finder.addMatcher(decl_ref_matcher, &decl_ref_rewriter); 375 match_finder.addMatcher(decl_ref_matcher, &decl_ref_rewriter);
294 376
295 // Function reference handling (e.g. getting a pointer to a function without 377 // The AST matchers don't provide a good way to match against an override from
296 // calling it): 378 // a given class. Instead, use two matchers: one that matches the declarations
379 // (in Blink) and another which matches all overrides and performs some
380 // filtering.
381 auto function_decl_matcher =
382 id("decl",
383 functionDecl(unless(anyOf(cxxMethodDecl(isOverride()),
384 // Overloaded operators have special names
385 // and should never be renamed.
386 isOverloadedOperator(),
387 // Similarly, constructors and destructors
388 // should not be considered for renaming.
389 cxxConstructorDecl(), cxxDestructorDecl())),
390 in_blink_namespace));
391 // Note that the matcher for overridden methods doesn't need to filter for
392 // special member functions: see implementation of FunctionDeclRewriter for
393 // the explanation.
394 auto overridden_method_decl_matcher = id("decl", cxxMethodDecl(isOverride()));
395 FunctionDeclRewriter function_decl_rewriter(&replacements);
396 match_finder.addMatcher(function_decl_matcher, &function_decl_rewriter);
397 match_finder.addMatcher(overridden_method_decl_matcher,
398 &function_decl_rewriter);
399
400 // Call handling:
401 auto call_matcher = id("expr", callExpr(callee(function_decl_matcher)));
402 auto overridden_call_matcher =
403 id("expr", callExpr(callee(overridden_method_decl_matcher)));
404
405 CallRewriter call_rewriter(function_decl_rewriter, &replacements);
406 match_finder.addMatcher(call_matcher, &call_rewriter);
407 match_finder.addMatcher(overridden_call_matcher, &call_rewriter);
408
409 // Function reference handling (e.g. getting a pointer to a function):
297 auto function_ref_matcher = 410 auto function_ref_matcher =
298 id("expr", declRefExpr(to(function_decl_matcher))); 411 id("expr", declRefExpr(to(function_decl_matcher)));
299 match_finder.addMatcher(function_ref_matcher, &call_rewriter); 412 // TODO(dcheng): apparently this bit of code isn't exercised in tests.
413 auto overridden_method_ref_matcher =
414 id("expr", declRefExpr(to(overridden_method_decl_matcher)));
415
416 FunctionDeclRefRewriter function_decl_ref_rewriter(function_decl_rewriter,
417 &replacements);
418 match_finder.addMatcher(function_ref_matcher, &function_decl_ref_rewriter);
419 match_finder.addMatcher(overridden_method_ref_matcher,
420 &function_decl_ref_rewriter);
300 421
301 // Initializer handling: 422 // Initializer handling:
302 auto constructor_initializer_matcher = 423 auto constructor_initializer_matcher =
303 cxxConstructorDecl(forEachConstructorInitializer( 424 cxxConstructorDecl(forEachConstructorInitializer(
304 id("initializer", cxxCtorInitializer(forField(field_decl_matcher))))); 425 id("initializer", cxxCtorInitializer(forField(field_decl_matcher)))));
305 426
306 ConstructorInitializerRewriterCallback constructor_initializer_rewriter( 427 ConstructorInitializerRewriter constructor_initializer_rewriter(
307 &replacements); 428 &replacements);
308 match_finder.addMatcher(constructor_initializer_matcher, 429 match_finder.addMatcher(constructor_initializer_matcher,
309 &constructor_initializer_rewriter); 430 &constructor_initializer_rewriter);
310 431
311 std::unique_ptr<clang::tooling::FrontendActionFactory> factory = 432 std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
312 clang::tooling::newFrontendActionFactory(&match_finder); 433 clang::tooling::newFrontendActionFactory(&match_finder);
313 int result = tool.run(factory.get()); 434 int result = tool.run(factory.get());
314 if (result != 0) 435 if (result != 0)
315 return result; 436 return result;
316 437
317 // Serialization format is documented in tools/clang/scripts/run_tool.py 438 // Serialization format is documented in tools/clang/scripts/run_tool.py
318 llvm::outs() << "==== BEGIN EDITS ====\n"; 439 llvm::outs() << "==== BEGIN EDITS ====\n";
319 for (const auto& r : replacements) { 440 for (const auto& r : replacements) {
320 std::string replacement_text = r.getReplacementText().str(); 441 std::string replacement_text = r.getReplacementText().str();
321 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); 442 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
322 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() 443 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
323 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; 444 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
324 } 445 }
325 llvm::outs() << "==== END EDITS ====\n"; 446 llvm::outs() << "==== END EDITS ====\n";
326 447
327 return 0; 448 return 0;
328 } 449 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698