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 // blink::InternalSettings::trace method overrides |
| 157 // 1) blink::InternalSettingsGenerated::trace |
| 158 // (won't be renamed because it is in generated code) |
| 159 // 2) blink::Supplement<blink::Page>::trace |
| 160 // (will be renamed). |
| 161 // It is safe to rename blink::InternalSettings::trace, because |
| 162 // both 1 and 2 will both be renamed (#1 via manual changes of the code |
| 163 // generator for DOM bindings and #2 via the clang tool). |
| 164 auto internal_settings_class_decl = cxxRecordDecl( |
| 165 hasName("InternalSettings"), |
| 166 hasParent(namespaceDecl(hasName("blink"), |
| 167 hasParent(translationUnitDecl())))); |
| 168 auto is_method_safe_to_rename = cxxMethodDecl( |
| 169 hasName("trace"), |
| 170 anyOf(hasParent(internal_settings_class_decl), // in .h file |
| 171 has(nestedNameSpecifier(specifiesType( // in .cpp file |
| 172 hasDeclaration(internal_settings_class_decl)))))); |
| 173 if (IsMatching(is_method_safe_to_rename, decl, decl.getASTContext())) |
| 174 return true; |
| 175 |
| 176 // For previously unknown conflicts, error out and require a human to |
| 177 // analyse the problem (rather than falling back to a potentially unsafe / |
| 178 // code semantics changing rename). |
| 179 llvm::errs() << "ERROR: "; |
| 180 PrintForDiagnostics(llvm::errs(), decl); |
| 181 llvm::errs() << " method overrides " |
| 182 << "some virtual methods that will be automatically renamed " |
| 183 << "and some that won't be renamed."; |
| 184 llvm::errs() << "\n"; |
| 185 for (auto it = decl.begin_overridden_methods(); |
| 186 it != decl.end_overridden_methods(); ++it) { |
| 187 if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder)) |
| 188 llvm::errs() << "Overriden method that will be renamed: "; |
| 189 else |
| 190 llvm::errs() << "Overriden method that will not be renamed: "; |
| 191 PrintForDiagnostics(llvm::errs(), **it); |
| 192 llvm::errs() << "\n"; |
| 193 } |
| 194 llvm::errs() << "\n"; |
| 195 assert(false); |
| 196 } |
150 | 197 |
151 // If the method overrides something that doesn't match, so the method itself | 198 // If the method overrides something that doesn't match, so the method itself |
152 // doesn't match. | 199 // doesn't match. |
153 if (override_not_matches) | 200 if (override_not_matches) |
154 return false; | 201 return false; |
| 202 |
155 // If the method overrides something that matches, so the method ifself | 203 // If the method overrides something that matches, so the method ifself |
156 // matches. | 204 // matches. |
157 if (override_matches) | 205 if (override_matches) |
158 return true; | 206 return true; |
159 | 207 |
160 return inner_matcher.matches(decl, finder, builder); | 208 return inner_matcher.matches(decl, finder, builder); |
161 } | 209 } |
162 | 210 |
163 AST_MATCHER_P(clang::CXXMethodDecl, | 211 AST_MATCHER_P(clang::CXXMethodDecl, |
164 includeAllOverriddenMethods, | 212 includeAllOverriddenMethods, |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 for (const auto& r : replacements) { | 1457 for (const auto& r : replacements) { |
1410 std::string replacement_text = r.getReplacementText().str(); | 1458 std::string replacement_text = r.getReplacementText().str(); |
1411 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1459 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
1412 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1460 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
1413 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1461 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
1414 } | 1462 } |
1415 llvm::outs() << "==== END EDITS ====\n"; | 1463 llvm::outs() << "==== END EDITS ====\n"; |
1416 | 1464 |
1417 return 0; | 1465 return 0; |
1418 } | 1466 } |
OLD | NEW |