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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 if (Node.getNumDecls() == 0) | 114 if (Node.getNumDecls() == 0) |
115 return false; | 115 return false; |
116 | 116 |
117 for (clang::NamedDecl* decl : Node.decls()) { | 117 for (clang::NamedDecl* decl : Node.decls()) { |
118 if (!InnerMatcher.matches(*decl, Finder, Builder)) | 118 if (!InnerMatcher.matches(*decl, Finder, Builder)) |
119 return false; | 119 return false; |
120 } | 120 } |
121 return true; | 121 return true; |
122 } | 122 } |
123 | 123 |
124 void PrintForDiagnostics(clang::raw_ostream& os, | |
125 const clang::FunctionDecl& decl) { | |
126 decl.getLocStart().print(os, decl.getASTContext().getSourceManager()); | |
127 os << ": "; | |
128 decl.getNameForDiagnostic(os, decl.getASTContext().getPrintingPolicy(), true); | |
129 } | |
130 | |
124 template <typename T> | 131 template <typename T> |
125 bool MatchAllOverriddenMethods( | 132 bool MatchAllOverriddenMethods( |
126 const clang::CXXMethodDecl& decl, | 133 const clang::CXXMethodDecl& decl, |
127 T&& inner_matcher, | 134 T&& inner_matcher, |
128 clang::ast_matchers::internal::ASTMatchFinder* finder, | 135 clang::ast_matchers::internal::ASTMatchFinder* finder, |
129 clang::ast_matchers::internal::BoundNodesTreeBuilder* builder) { | 136 clang::ast_matchers::internal::BoundNodesTreeBuilder* builder) { |
130 bool override_matches = false; | 137 bool override_matches = false; |
131 bool override_not_matches = false; | 138 bool override_not_matches = false; |
132 | 139 |
133 for (auto it = decl.begin_overridden_methods(); | 140 for (auto it = decl.begin_overridden_methods(); |
134 it != decl.end_overridden_methods(); ++it) { | 141 it != decl.end_overridden_methods(); ++it) { |
135 if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder)) | 142 if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder)) |
136 override_matches = true; | 143 override_matches = true; |
137 else | 144 else |
138 override_not_matches = true; | 145 override_not_matches = true; |
139 } | 146 } |
140 | 147 |
141 // If this fires we have a class overriding a method that matches, and a | 148 // If this fires we have a class overriding a method that matches, and a |
142 // method that does not match the inner matcher. In that case we will match | 149 // method that does not match the inner matcher. In that case we will match |
143 // one ancestor method but not the other. If we rename one of the and not the | 150 // one ancestor method but not the other. If we rename one of the and not the |
144 // other it will break what this class overrides, disconnecting it from the | 151 // other it will break what this class overrides, disconnecting it from the |
145 // one we did not rename which creates a behaviour change. So assert and | 152 // one we did not rename which creates a behaviour change. So assert and |
146 // demand the user to fix the code first (or add the method to our | 153 // demand the user to fix the code first (or add the method to our |
147 // blacklist T_T). | 154 // blacklist T_T). |
148 if (override_matches || override_not_matches) | 155 if (override_matches || override_not_matches) { |
149 assert(override_matches != override_not_matches); | 156 if (override_matches == override_not_matches) { |
danakj
2017/01/05 18:55:19
can you change this to &&, it should be the same b
Łukasz Anforowicz
2017/01/05 19:04:43
Good point. Done.
| |
157 // blink::InternalSettings::trace method overrides | |
158 // 1) blink::InternalSettingsGenerated::trace | |
159 // (won't be renamed because it is in generated code) | |
160 // 2) blink::Supplement<blink::Page>::trace | |
161 // (will be renamed). | |
162 // It is safe to rename blink::InternalSettings::trace, because | |
163 // both 1 and 2 will both be renamed (#1 via manual changes of the code | |
164 // generator for DOM bindings and #2 via the clang tool). | |
165 // will only rename method overrides | |
danakj
2017/01/05 18:55:19
this comment isn't a sentence
Łukasz Anforowicz
2017/01/05 19:04:44
Ooops. Removed this line (leftover from drafting
| |
166 auto internal_settings_class_decl = cxxRecordDecl( | |
167 hasName("InternalSettings"), | |
168 hasParent(namespaceDecl(hasName("blink"), | |
169 hasParent(translationUnitDecl())))); | |
170 auto is_method_safe_to_rename = cxxMethodDecl( | |
171 hasName("trace"), | |
172 anyOf(hasParent(internal_settings_class_decl), // in .h file | |
173 has(nestedNameSpecifier(specifiesType( // in .cpp file | |
174 hasDeclaration(internal_settings_class_decl)))))); | |
175 if (IsMatching(is_method_safe_to_rename, decl, decl.getASTContext())) | |
176 return true; | |
177 | |
178 // For previously unknown conflicts, errors out and require a human to | |
179 // analyse the problem (rather than falling back to a potentially unsafe / | |
180 // code semantics changing rename). | |
181 llvm::errs() << "ERROR: "; | |
182 PrintForDiagnostics(llvm::errs(), decl); | |
183 llvm::errs() << " method overrides " | |
184 << "some virtual methods that will be automatically renamed " | |
185 << "and some that won't be renamed."; | |
186 llvm::errs() << "\n"; | |
187 for (auto it = decl.begin_overridden_methods(); | |
188 it != decl.end_overridden_methods(); ++it) { | |
189 if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder)) | |
190 llvm::errs() << "Overriden method that will be renamed: "; | |
191 else | |
192 llvm::errs() << "Overriden method that will not be renamed: "; | |
193 PrintForDiagnostics(llvm::errs(), **it); | |
194 llvm::errs() << "\n"; | |
195 } | |
196 llvm::errs() << "\n"; | |
197 assert(0); | |
Łukasz Anforowicz
2017/01/05 18:45:19
We could also return |true| rather than asserting.
danakj
2017/01/05 18:55:19
assert cuz we want to know about it on the big day
Łukasz Anforowicz
2017/01/05 19:04:44
Done.
| |
198 } | |
199 } | |
150 | 200 |
151 // If the method overrides something that doesn't match, so the method itself | 201 // If the method overrides something that doesn't match, so the method itself |
152 // doesn't match. | 202 // doesn't match. |
153 if (override_not_matches) | 203 if (override_not_matches) |
154 return false; | 204 return false; |
205 | |
155 // If the method overrides something that matches, so the method ifself | 206 // If the method overrides something that matches, so the method ifself |
156 // matches. | 207 // matches. |
157 if (override_matches) | 208 if (override_matches) |
158 return true; | 209 return true; |
159 | 210 |
160 return inner_matcher.matches(decl, finder, builder); | 211 return inner_matcher.matches(decl, finder, builder); |
161 } | 212 } |
162 | 213 |
163 AST_MATCHER_P(clang::CXXMethodDecl, | 214 AST_MATCHER_P(clang::CXXMethodDecl, |
164 includeAllOverriddenMethods, | 215 includeAllOverriddenMethods, |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1409 for (const auto& r : replacements) { | 1460 for (const auto& r : replacements) { |
1410 std::string replacement_text = r.getReplacementText().str(); | 1461 std::string replacement_text = r.getReplacementText().str(); |
1411 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1462 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
1412 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1463 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
1413 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1464 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
1414 } | 1465 } |
1415 llvm::outs() << "==== END EDITS ====\n"; | 1466 llvm::outs() << "==== END EDITS ====\n"; |
1416 | 1467 |
1417 return 0; | 1468 return 0; |
1418 } | 1469 } |
OLD | NEW |