Chromium Code Reviews| 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 |