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

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: Covering static methods multiple method arities. 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/methods-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:
11 // const int maxThings => const int kMaxThings 11 // const int maxThings => const int kMaxThings
12 // free functions and methods: 12 // free functions and methods:
13 // void doThisThenThat() => void DoThisAndThat() 13 // void doThisThenThat() => void DoThisAndThat()
14 14
15 #include <assert.h> 15 #include <assert.h>
16 #include <algorithm> 16 #include <algorithm>
17 #include <fstream>
17 #include <memory> 18 #include <memory>
18 #include <set> 19 #include <set>
20 #include <sstream>
19 #include <string> 21 #include <string>
20 22
21 #include "clang/AST/ASTContext.h" 23 #include "clang/AST/ASTContext.h"
22 #include "clang/ASTMatchers/ASTMatchFinder.h" 24 #include "clang/ASTMatchers/ASTMatchFinder.h"
23 #include "clang/ASTMatchers/ASTMatchers.h" 25 #include "clang/ASTMatchers/ASTMatchers.h"
24 #include "clang/ASTMatchers/ASTMatchersMacros.h" 26 #include "clang/ASTMatchers/ASTMatchersMacros.h"
25 #include "clang/Basic/CharInfo.h" 27 #include "clang/Basic/CharInfo.h"
26 #include "clang/Basic/SourceManager.h" 28 #include "clang/Basic/SourceManager.h"
27 #include "clang/Frontend/FrontendActions.h" 29 #include "clang/Frontend/FrontendActions.h"
28 #include "clang/Lex/Lexer.h" 30 #include "clang/Lex/Lexer.h"
29 #include "clang/Tooling/CommonOptionsParser.h" 31 #include "clang/Tooling/CommonOptionsParser.h"
30 #include "clang/Tooling/Refactoring.h" 32 #include "clang/Tooling/Refactoring.h"
31 #include "clang/Tooling/Tooling.h" 33 #include "clang/Tooling/Tooling.h"
32 #include "llvm/Support/CommandLine.h" 34 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/TargetSelect.h" 35 #include "llvm/Support/TargetSelect.h"
34 36
35 #include "EditTracker.h" 37 #include "EditTracker.h"
36 38
37 using namespace clang::ast_matchers; 39 using namespace clang::ast_matchers;
38 using clang::tooling::CommonOptionsParser; 40 using clang::tooling::CommonOptionsParser;
39 using clang::tooling::Replacement; 41 using clang::tooling::Replacement;
40 using llvm::StringRef; 42 using llvm::StringRef;
41 43
42 namespace { 44 namespace {
43 45
44 const char kBlinkFieldPrefix[] = "m_"; 46 const char kBlinkFieldPrefix[] = "m_";
45 const char kBlinkStaticMemberPrefix[] = "s_"; 47 const char kBlinkStaticMemberPrefix[] = "s_";
46 const char kGeneratedFileRegex[] = "^gen/|/gen/"; 48 const char kGeneratedFileRegex[] = "^gen/|/gen/";
49 const char kIdlMethodsParamName[] = "idl-methods";
47 50
48 template <typename MatcherType, typename NodeType> 51 template <typename MatcherType, typename NodeType>
49 bool IsMatching(const MatcherType& matcher, 52 bool IsMatching(const MatcherType& matcher,
50 const NodeType& node, 53 const NodeType& node,
51 clang::ASTContext& context) { 54 clang::ASTContext& context) {
52 return !match(matcher, node, context).empty(); 55 return !match(matcher, node, context).empty();
53 } 56 }
54 57
55 const clang::ast_matchers::internal:: 58 const clang::ast_matchers::internal::
56 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> 59 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr>
(...skipping 15 matching lines...) Expand all
72 return Node.isInstance(); 75 return Node.isInstance();
73 } 76 }
74 77
75 AST_MATCHER_P(clang::FunctionTemplateDecl, 78 AST_MATCHER_P(clang::FunctionTemplateDecl,
76 templatedDecl, 79 templatedDecl,
77 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>, 80 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>,
78 InnerMatcher) { 81 InnerMatcher) {
79 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder); 82 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder);
80 } 83 }
81 84
85 class IdlMatcherState {
dcheng 2017/01/12 11:00:58 Nit: MethodBlocklist
Łukasz Anforowicz 2017/01/12 23:32:01 Done.
86 public:
87 explicit IdlMatcherState(const std::string& filepath) {
88 if (filepath.empty()) {
89 // 1. test_tool.py will run the clang tool without --idl-methods argument.
90 // 2. If --idl-methods is empty in a normal run, the test-only entries
91 // should be okay / shouldn't conflict with real Blink methods.
dcheng 2017/01/12 11:00:58 Perhaps test_tool.py should understand how to pars
Łukasz Anforowicz 2017/01/12 23:32:01 Done. test_tool.py will look for a file named run
92 SetupTestBlacklist();
93 } else {
94 ParseInputFile(filepath);
95 }
96 }
97
98 bool IsMatching(const clang::CXXMethodDecl& method) const {
dcheng 2017/01/12 11:00:58 Nit: Contains / Matches / Has
Łukasz Anforowicz 2017/01/12 23:32:01 Done (Contains).
99 auto it = method_to_class_to_args_.find(method.getName());
100 if (it == method_to_class_to_args_.end())
101 return false;
102
103 const clang::CXXRecordDecl* actual_class = method.getParent();
104 // Hopefully |getParent()| can find the class even for non-inlined method
105 // definitions (where CXXRecordDecl is not a parent AST node of
106 // CXXMethodDecl).
107 assert(actual_class);
108
109 const std::map<std::string, std::set<int>>& class_to_args = it->second;
110 auto it2 = class_to_args.find(actual_class->getName());
111 if (it2 == class_to_args.end())
112 return false;
113
114 std::set<int> expected_number_of_args = it2->second;
115 int actual_number_of_args = method.param_size();
116 if (0 == expected_number_of_args.count(-1) &&
117 0 == expected_number_of_args.count(actual_number_of_args))
118 return false;
119
120 // No need to verify here that |actual_class| is in the |blink| namespace -
121 // this will be done by other matchers elsewhere.
122
123 // TODO(lukasza): Do we need to consider return type and/or param types?
124
125 return true;
126 }
127
128 private:
129 void SetupTestBlacklist() {
130 std::istringstream stream(
131 "IdlTestClass:::idlTestMethodNoParams:::0\n"
132 "IdlTestClass:::idlTestMethodOneParam:::1\n"
133 "IdlTestClass:::idlTestMethodTwoOrThreeParams:::2\n"
134 "IdlTestClass:::idlTestMethodTwoOrThreeParams:::3\n"
135 "IdlTestClass:::idlTestMethodAnyNumberOfParams:::-1\n"
136 "IdlTestClass:::path:::0\n"); // "Get" prefix test.
137
138 ParseInputStream("<test input>", stream);
139 }
140
141 void ParseInputFile(const std::string& filepath) {
142 std::ifstream stream(filepath);
dcheng 2017/01/12 11:00:58 Since this is LLVM/clang code, let's go with the L
Łukasz Anforowicz 2017/01/12 23:32:01 Done. I like how I automagically/effortlessly got
143 ParseInputStream(filepath, stream);
144 }
145
146 void ParseInputStream(const std::string& filepath, std::istream& stream) {
147 if (stream.fail()) {
148 llvm::errs() << "ERROR: Cannot open the file specified in --"
149 << kIdlMethodsParamName << " argument: " << filepath << "\n";
150 return;
151 }
152
153 // Each line is expected to have the following format:
154 // <class name>:::<method name>:::<number of arguments>
155 std::string line;
156 int line_number = 0;
157 while (std::getline(stream, line)) {
158 // Split the line into ':::'-delimited parts.
159 const size_t kExpectedNumberOfParts = 3;
160 llvm::SmallVector<llvm::StringRef, kExpectedNumberOfParts + 1> parts;
dcheng 2017/01/12 11:00:58 Why + 1?
Łukasz Anforowicz 2017/01/12 23:32:01 You are right, I should remove it. I tried to be
161 llvm::StringRef(line).split(parts, ":::");
162 line_number++;
163 if (parts.size() < kExpectedNumberOfParts) {
164 llvm::errs() << "ERROR: Parsing error - less than "
165 << kExpectedNumberOfParts
166 << " ':::'-delimited parts: " << filepath << ":"
167 << line_number << ": " << line << "\n";
168 continue;
169 }
170
171 // Parse individual parts.
172 llvm::StringRef class_name = parts[0];
173 llvm::StringRef method_name = parts[1];
174 int number_of_method_args;
Łukasz Anforowicz 2017/01/12 23:32:01 I stopped allowing -1 here as a way to say "any nu
175 if (parts[2].getAsInteger(0, number_of_method_args)) {
176 llvm::errs() << "ERROR: Parsing error - "
177 << "'" << parts[2] << "' is not an integer: " << filepath
178 << ":" << line_number << ": " << line << "\n";
dcheng 2017/01/12 11:00:59 Should we make errors fatal?
Łukasz Anforowicz 2017/01/12 23:32:01 Done. I am not sure if asserts are the right way
179 continue;
180 }
181
182 // Store the new entry.
183 method_to_class_to_args_[method_name][class_name].insert(
184 number_of_method_args);
185 }
186 }
187
188 // Stores methods to blacklist in a map:
189 // method name -> class name -> set of all allowed numbers of arguments.
190 std::map<std::string, std::map<std::string, std::set<int>>>
dcheng 2017/01/12 11:00:58 Perhaps consider StringMap<StringMap<std::set<int>
Łukasz Anforowicz 2017/01/12 23:32:01 Good point. Done.
191 method_to_class_to_args_;
192 };
193
194 AST_MATCHER_P(clang::CXXMethodDecl,
195 internalIdlMethod,
196 IdlMatcherState,
197 MatcherState) {
198 return MatcherState.IsMatching(Node);
199 }
200
201 clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl> idlMethod(
dcheng 2017/01/12 11:00:58 idlMethod => isBlocklistedMethod per the other nit
Łukasz Anforowicz 2017/01/12 23:32:01 Done.
202 const std::string& idl_methods_filepath) {
203 return internalIdlMethod(IdlMatcherState(idl_methods_filepath));
204 }
205
82 // If |InnerMatcher| matches |top|, then the returned matcher will match: 206 // If |InnerMatcher| matches |top|, then the returned matcher will match:
83 // - |top::function| 207 // - |top::function|
84 // - |top::Class::method| 208 // - |top::Class::method|
85 // - |top::internal::Class::method| 209 // - |top::internal::Class::method|
86 AST_MATCHER_P( 210 AST_MATCHER_P(
87 clang::NestedNameSpecifier, 211 clang::NestedNameSpecifier,
88 hasTopLevelPrefix, 212 hasTopLevelPrefix,
89 clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>, 213 clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>,
90 InnerMatcher) { 214 InnerMatcher) {
91 const clang::NestedNameSpecifier* NodeToMatch = &Node; 215 const clang::NestedNameSpecifier* NodeToMatch = &Node;
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 1148
1025 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); 1149 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
1026 1150
1027 int main(int argc, const char* argv[]) { 1151 int main(int argc, const char* argv[]) {
1028 // TODO(dcheng): Clang tooling should do this itself. 1152 // TODO(dcheng): Clang tooling should do this itself.
1029 // http://llvm.org/bugs/show_bug.cgi?id=21627 1153 // http://llvm.org/bugs/show_bug.cgi?id=21627
1030 llvm::InitializeNativeTarget(); 1154 llvm::InitializeNativeTarget();
1031 llvm::InitializeNativeTargetAsmParser(); 1155 llvm::InitializeNativeTargetAsmParser();
1032 llvm::cl::OptionCategory category( 1156 llvm::cl::OptionCategory category(
1033 "rewrite_to_chrome_style: convert Blink style to Chrome style."); 1157 "rewrite_to_chrome_style: convert Blink style to Chrome style.");
1158 llvm::cl::opt<std::string> idl_methods_file(
1159 kIdlMethodsParamName, llvm::cl::value_desc("filepath"),
1160 llvm::cl::desc("file listing method names derived from Web IDL"));
dcheng 2017/01/12 11:00:58 Nit: let's use a more generic name to indicate wha
Łukasz Anforowicz 2017/01/12 23:32:01 Done.
1034 CommonOptionsParser options(argc, argv, category); 1161 CommonOptionsParser options(argc, argv, category);
1035 clang::tooling::ClangTool tool(options.getCompilations(), 1162 clang::tooling::ClangTool tool(options.getCompilations(),
1036 options.getSourcePathList()); 1163 options.getSourcePathList());
1037 1164
1038 MatchFinder match_finder; 1165 MatchFinder match_finder;
1039 std::set<Replacement> replacements; 1166 std::set<Replacement> replacements;
1040 1167
1041 // Blink namespace matchers ======== 1168 // Blink namespace matchers ========
1042 auto blink_namespace_decl = 1169 auto blink_namespace_decl =
1043 namespaceDecl(anyOf(hasName("blink"), hasName("WTF")), 1170 namespaceDecl(anyOf(hasName("blink"), hasName("WTF")),
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 // struct S { 1302 // struct S {
1176 // void g(); 1303 // void g();
1177 // }; 1304 // };
1178 // matches |g|. 1305 // matches |g|.
1179 // For a method to be considered for rewrite, it must not override something 1306 // For a method to be considered for rewrite, it must not override something
1180 // that we're not rewriting. Any methods that we would not normally consider 1307 // that we're not rewriting. Any methods that we would not normally consider
1181 // but that override something we are rewriting should also be rewritten. So 1308 // but that override something we are rewriting should also be rewritten. So
1182 // we use includeAllOverriddenMethods() to check these rules not just for the 1309 // we use includeAllOverriddenMethods() to check these rules not just for the
1183 // method being matched but for the methods it overrides also. 1310 // method being matched but for the methods it overrides also.
1184 auto is_blink_method = includeAllOverriddenMethods( 1311 auto is_blink_method = includeAllOverriddenMethods(
1185 allOf(in_blink_namespace, unless(isBlacklistedMethod()))); 1312 allOf(in_blink_namespace, unless(isBlacklistedMethod()),
1313 unless(idlMethod(idl_methods_file))));
1186 auto method_decl_matcher = id( 1314 auto method_decl_matcher = id(
1187 "decl", 1315 "decl",
1188 cxxMethodDecl( 1316 cxxMethodDecl(
1189 unless(anyOf( 1317 unless(anyOf(
1190 // Overloaded operators have special names and should never be 1318 // Overloaded operators have special names and should never be
1191 // renamed. 1319 // renamed.
1192 isOverloadedOperator(), 1320 isOverloadedOperator(),
1193 // Similarly, constructors, destructors, and conversion 1321 // Similarly, constructors, destructors, and conversion
1194 // functions should not be considered for renaming. 1322 // functions should not be considered for renaming.
1195 cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())), 1323 cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())),
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 for (const auto& r : replacements) { 1537 for (const auto& r : replacements) {
1410 std::string replacement_text = r.getReplacementText().str(); 1538 std::string replacement_text = r.getReplacementText().str();
1411 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); 1539 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
1412 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() 1540 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
1413 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; 1541 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
1414 } 1542 }
1415 llvm::outs() << "==== END EDITS ====\n"; 1543 llvm::outs() << "==== END EDITS ====\n";
1416 1544
1417 return 0; 1545 return 0;
1418 } 1546 }
OLDNEW
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/methods-expected.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698