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

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

Issue 2627003003: Add --idl-methods <filepath> parameter for skipping renaming of IDL methods. (Closed)
Patch Set: Addressed remaining CR feedback from dcheng@. Created 3 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
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/blocked_methods.txt » ('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 16 matching lines...) Expand all
27 #include "clang/Frontend/CompilerInstance.h" 27 #include "clang/Frontend/CompilerInstance.h"
28 #include "clang/Frontend/FrontendActions.h" 28 #include "clang/Frontend/FrontendActions.h"
29 #include "clang/Lex/MacroArgs.h" 29 #include "clang/Lex/MacroArgs.h"
30 #include "clang/Lex/Lexer.h" 30 #include "clang/Lex/Lexer.h"
31 #include "clang/Lex/PPCallbacks.h" 31 #include "clang/Lex/PPCallbacks.h"
32 #include "clang/Lex/Preprocessor.h" 32 #include "clang/Lex/Preprocessor.h"
33 #include "clang/Tooling/CommonOptionsParser.h" 33 #include "clang/Tooling/CommonOptionsParser.h"
34 #include "clang/Tooling/Refactoring.h" 34 #include "clang/Tooling/Refactoring.h"
35 #include "clang/Tooling/Tooling.h" 35 #include "clang/Tooling/Tooling.h"
36 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Support/CommandLine.h"
37 #include "llvm/Support/ErrorOr.h"
38 #include "llvm/Support/LineIterator.h"
39 #include "llvm/Support/MemoryBuffer.h"
37 #include "llvm/Support/TargetSelect.h" 40 #include "llvm/Support/TargetSelect.h"
38 41
39 #include "EditTracker.h" 42 #include "EditTracker.h"
40 43
41 using namespace clang::ast_matchers; 44 using namespace clang::ast_matchers;
42 using clang::tooling::CommonOptionsParser; 45 using clang::tooling::CommonOptionsParser;
43 using clang::tooling::Replacement; 46 using clang::tooling::Replacement;
44 using llvm::StringRef; 47 using llvm::StringRef;
45 48
46 namespace { 49 namespace {
47 50
48 const char kBlinkFieldPrefix[] = "m_"; 51 const char kBlinkFieldPrefix[] = "m_";
49 const char kBlinkStaticMemberPrefix[] = "s_"; 52 const char kBlinkStaticMemberPrefix[] = "s_";
50 const char kGeneratedFileRegex[] = "^gen/|/gen/"; 53 const char kGeneratedFileRegex[] = "^gen/|/gen/";
51 const char kGMockMethodNamePrefix[] = "gmock_"; 54 const char kGMockMethodNamePrefix[] = "gmock_";
55 const char kMethodBlocklistParamName[] = "method-blocklist";
52 56
53 template <typename MatcherType, typename NodeType> 57 template <typename MatcherType, typename NodeType>
54 bool IsMatching(const MatcherType& matcher, 58 bool IsMatching(const MatcherType& matcher,
55 const NodeType& node, 59 const NodeType& node,
56 clang::ASTContext& context) { 60 clang::ASTContext& context) {
57 return !match(matcher, node, context).empty(); 61 return !match(matcher, node, context).empty();
58 } 62 }
59 63
60 const clang::ast_matchers::internal:: 64 const clang::ast_matchers::internal::
61 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> 65 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr>
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 if (potentially_mocked_method->getNumParams() != Node.getNumParams()) 116 if (potentially_mocked_method->getNumParams() != Node.getNumParams())
113 continue; 117 continue;
114 118
115 if (InnerMatcher.matches(*potentially_mocked_method, Finder, Builder)) 119 if (InnerMatcher.matches(*potentially_mocked_method, Finder, Builder))
116 return true; 120 return true;
117 } 121 }
118 122
119 return false; 123 return false;
120 } 124 }
121 125
126 class MethodBlocklist {
127 public:
128 explicit MethodBlocklist(const std::string& filepath) {
129 if (!filepath.empty())
130 ParseInputFile(filepath);
131 }
132
133 bool Contains(const clang::CXXMethodDecl& method) const {
134 auto it = method_to_class_to_args_.find(method.getName());
135 if (it == method_to_class_to_args_.end())
136 return false;
137
138 const clang::CXXRecordDecl* actual_class = method.getParent();
139 assert(actual_class &&
140 "Hopefully |getParent()| can find the class even for non-inlined "
141 "method definitions (where CXXRecordDecl is not a parent AST node "
142 "of CXXMethodDecl.");
143
144 const llvm::StringMap<std::set<unsigned>>& class_to_args = it->second;
145 auto it2 = class_to_args.find(actual_class->getName());
146 if (it2 == class_to_args.end())
147 return false;
148
149 const std::set<unsigned>& arg_counts = it2->second;
150 unsigned method_param_count = method.param_size();
151 unsigned method_non_optional_param_count = method_param_count;
152 for (const clang::ParmVarDecl* param : method.parameters()) {
153 if (param->hasInit())
154 method_non_optional_param_count--;
155 }
156 bool found_matching_arg_count =
157 std::any_of(arg_counts.begin(), arg_counts.end(),
158 [method_param_count,
159 method_non_optional_param_count](unsigned arg_count) {
160 return (method_non_optional_param_count <= arg_count) &&
161 (arg_count <= method_param_count);
162 });
163
164 // No need to verify here that |actual_class| is in the |blink| namespace -
165 // this will be done by other matchers elsewhere.
166
167 // TODO(lukasza): Do we need to consider return type and/or param types?
168
169 return found_matching_arg_count;
170 }
171
172 private:
173 // Each line is expected to have the following format:
174 // <class name>:::<method name>:::<number of arguments>
175 void ParseInputFile(const std::string& filepath) {
176 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> file_or_err =
177 llvm::MemoryBuffer::getFile(filepath);
178 if (std::error_code err = file_or_err.getError()) {
179 llvm::errs() << "ERROR: Cannot open the file specified in --"
180 << kMethodBlocklistParamName << " argument: " << filepath
181 << ": " << err.message() << "\n";
182 assert(false);
183 return;
184 }
185
186 llvm::line_iterator it(**file_or_err, true /* SkipBlanks */, '#');
187 for (; !it.is_at_eof(); ++it) {
188 llvm::StringRef line = it->trim();
189 if (line.empty())
190 continue;
191
192 // Split the line into ':::'-delimited parts.
193 const size_t kExpectedNumberOfParts = 3;
194 llvm::SmallVector<llvm::StringRef, kExpectedNumberOfParts> parts;
195 line.split(parts, ":::");
196 if (parts.size() != kExpectedNumberOfParts) {
197 llvm::errs() << "ERROR: Parsing error - expected "
198 << kExpectedNumberOfParts
199 << " ':::'-delimited parts: " << filepath << ":"
200 << it.line_number() << ": " << line << "\n";
201 assert(false);
202 continue;
203 }
204
205 // Parse individual parts.
206 llvm::StringRef class_name = parts[0];
207 llvm::StringRef method_name = parts[1];
208 unsigned number_of_method_args;
209 if (parts[2].getAsInteger(0, number_of_method_args)) {
210 llvm::errs() << "ERROR: Parsing error - '" << parts[2] << "' "
211 << "is not an unsigned integer: " << filepath << ":"
212 << it.line_number() << ": " << line << "\n";
213 assert(false);
214 continue;
215 }
216
217 // Store the new entry.
218 method_to_class_to_args_[method_name][class_name].insert(
219 number_of_method_args);
220 }
221 }
222
223 // Stores methods to blacklist in a map:
224 // method name -> class name -> set of all allowed numbers of arguments.
225 llvm::StringMap<llvm::StringMap<std::set<unsigned>>> method_to_class_to_args_;
226 };
227
228 AST_MATCHER_P(clang::CXXMethodDecl,
229 isBlocklistedMethod,
230 MethodBlocklist,
231 Blocklist) {
232 return Blocklist.Contains(Node);
233 }
234
122 // If |InnerMatcher| matches |top|, then the returned matcher will match: 235 // If |InnerMatcher| matches |top|, then the returned matcher will match:
123 // - |top::function| 236 // - |top::function|
124 // - |top::Class::method| 237 // - |top::Class::method|
125 // - |top::internal::Class::method| 238 // - |top::internal::Class::method|
126 AST_MATCHER_P( 239 AST_MATCHER_P(
127 clang::NestedNameSpecifier, 240 clang::NestedNameSpecifier,
128 hasTopLevelPrefix, 241 hasTopLevelPrefix,
129 clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>, 242 clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>,
130 InnerMatcher) { 243 InnerMatcher) {
131 const clang::NestedNameSpecifier* NodeToMatch = &Node; 244 const clang::NestedNameSpecifier* NodeToMatch = &Node;
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 1381
1269 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); 1382 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
1270 1383
1271 int main(int argc, const char* argv[]) { 1384 int main(int argc, const char* argv[]) {
1272 // TODO(dcheng): Clang tooling should do this itself. 1385 // TODO(dcheng): Clang tooling should do this itself.
1273 // http://llvm.org/bugs/show_bug.cgi?id=21627 1386 // http://llvm.org/bugs/show_bug.cgi?id=21627
1274 llvm::InitializeNativeTarget(); 1387 llvm::InitializeNativeTarget();
1275 llvm::InitializeNativeTargetAsmParser(); 1388 llvm::InitializeNativeTargetAsmParser();
1276 llvm::cl::OptionCategory category( 1389 llvm::cl::OptionCategory category(
1277 "rewrite_to_chrome_style: convert Blink style to Chrome style."); 1390 "rewrite_to_chrome_style: convert Blink style to Chrome style.");
1391 llvm::cl::opt<std::string> blocklisted_methods_file(
1392 kMethodBlocklistParamName, llvm::cl::value_desc("filepath"),
1393 llvm::cl::desc("file listing methods to be blocked (not renamed)"));
1278 CommonOptionsParser options(argc, argv, category); 1394 CommonOptionsParser options(argc, argv, category);
1279 clang::tooling::ClangTool tool(options.getCompilations(), 1395 clang::tooling::ClangTool tool(options.getCompilations(),
1280 options.getSourcePathList()); 1396 options.getSourcePathList());
1281 1397
1282 MatchFinder match_finder; 1398 MatchFinder match_finder;
1283 std::set<Replacement> replacements; 1399 std::set<Replacement> replacements;
1284 1400
1285 // Blink namespace matchers ======== 1401 // Blink namespace matchers ========
1286 auto blink_namespace_decl = 1402 auto blink_namespace_decl =
1287 namespaceDecl(anyOf(hasName("blink"), hasName("WTF")), 1403 namespaceDecl(anyOf(hasName("blink"), hasName("WTF")),
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1418 // Given 1534 // Given
1419 // struct S { 1535 // struct S {
1420 // void g(); 1536 // void g();
1421 // }; 1537 // };
1422 // matches |g|. 1538 // matches |g|.
1423 // For a method to be considered for rewrite, it must not override something 1539 // For a method to be considered for rewrite, it must not override something
1424 // that we're not rewriting. Any methods that we would not normally consider 1540 // that we're not rewriting. Any methods that we would not normally consider
1425 // but that override something we are rewriting should also be rewritten. So 1541 // but that override something we are rewriting should also be rewritten. So
1426 // we use includeAllOverriddenMethods() to check these rules not just for the 1542 // we use includeAllOverriddenMethods() to check these rules not just for the
1427 // method being matched but for the methods it overrides also. 1543 // method being matched but for the methods it overrides also.
1544 MethodBlocklist method_blocklist(blocklisted_methods_file);
1428 auto is_blink_method = includeAllOverriddenMethods( 1545 auto is_blink_method = includeAllOverriddenMethods(
1429 allOf(in_blink_namespace, unless(isBlacklistedMethod()))); 1546 allOf(in_blink_namespace, unless(isBlacklistedMethod()),
1547 unless(isBlocklistedMethod(method_blocklist))));
1430 auto method_decl_matcher = id( 1548 auto method_decl_matcher = id(
1431 "decl", 1549 "decl",
1432 cxxMethodDecl( 1550 cxxMethodDecl(
1433 unless(anyOf( 1551 unless(anyOf(
1434 // Overloaded operators have special names and should never be 1552 // Overloaded operators have special names and should never be
1435 // renamed. 1553 // renamed.
1436 isOverloadedOperator(), 1554 isOverloadedOperator(),
1437 // Similarly, constructors, destructors, and conversion 1555 // Similarly, constructors, destructors, and conversion
1438 // functions should not be considered for renaming. 1556 // functions should not be considered for renaming.
1439 cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())), 1557 cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())),
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 for (const auto& r : replacements) { 1785 for (const auto& r : replacements) {
1668 std::string replacement_text = r.getReplacementText().str(); 1786 std::string replacement_text = r.getReplacementText().str();
1669 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); 1787 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
1670 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() 1788 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
1671 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; 1789 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
1672 } 1790 }
1673 llvm::outs() << "==== END EDITS ====\n"; 1791 llvm::outs() << "==== END EDITS ====\n";
1674 1792
1675 return 0; 1793 return 0;
1676 } 1794 }
OLDNEW
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/blocked_methods.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698