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

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

Issue 2256913002: Handling of DependentScopeDeclRefExpr and CXXDependentScopeMemberExpr nodes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@blink-style-new-clang
Patch Set: Created 4 years, 4 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
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 namespace { 48 namespace {
49 49
50 const char kBlinkFieldPrefix[] = "m_"; 50 const char kBlinkFieldPrefix[] = "m_";
51 const char kBlinkStaticMemberPrefix[] = "s_"; 51 const char kBlinkStaticMemberPrefix[] = "s_";
52 const char kGeneratedFileRegex[] = "^gen/|/gen/"; 52 const char kGeneratedFileRegex[] = "^gen/|/gen/";
53 53
54 const clang::ast_matchers::internal:: 54 const clang::ast_matchers::internal::
55 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> 55 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr>
56 unresolvedMemberExpr; 56 unresolvedMemberExpr;
57 57
58 const clang::ast_matchers::internal::
59 VariadicDynCastAllOfMatcher<clang::Expr, clang::DependentScopeDeclRefExpr>
60 dependentScopeDeclRefExpr;
61
62 const clang::ast_matchers::internal::
63 VariadicDynCastAllOfMatcher<clang::Expr, clang::CXXDependentScopeMemberExpr>
64 cxxDependentScopeMemberExpr;
65
58 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { 66 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) {
59 return Node.isOverloadedOperator(); 67 return Node.isOverloadedOperator();
60 } 68 }
61 69
62 AST_MATCHER_P(clang::FunctionTemplateDecl, 70 AST_MATCHER_P(clang::FunctionTemplateDecl,
63 templatedDecl, 71 templatedDecl,
64 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>, 72 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>,
65 InnerMatcher) { 73 InnerMatcher) {
66 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder); 74 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder);
67 } 75 }
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 std::string& name) { 430 std::string& name) {
423 assert(decl.shadow_size() > 0); 431 assert(decl.shadow_size() > 0);
424 432
425 // If a using declaration's targeted declaration is a set of overloaded 433 // If a using declaration's targeted declaration is a set of overloaded
426 // functions, it can introduce multiple shadowed declarations. Just using the 434 // functions, it can introduce multiple shadowed declarations. Just using the
427 // first one is OK, since overloaded functions have the same name, by 435 // first one is OK, since overloaded functions have the same name, by
428 // definition. 436 // definition.
429 return GetNameForDecl(*decl.shadow_begin()->getTargetDecl(), context, name); 437 return GetNameForDecl(*decl.shadow_begin()->getTargetDecl(), context, name);
430 } 438 }
431 439
440 std::string RenameDependentScopeName(const std::string& old_name) {
441 // TODO(lukasza): We don't know if |expr| (i.e. |T::x|) refers to a static
442 // method VS static field VS something else (because we can't tell what |T|
443 // is). Let's use some simple heuristics for now :-/.
444 std::string new_name;
445 if (old_name.substr(0, 2) == "m_") {
446 new_name = CamelCaseToUnderscoreCase(old_name.substr(2)) + "_";
447 } else {
448 new_name = old_name;
449 new_name[0] = clang::toUppercase(new_name[0]);
450 }
Łukasz Anforowicz 2016/08/17 22:45:09 Not sure if I can/should handle other kinds of ren
451 return new_name;
452 }
453
454 bool GetNameForDecl(const clang::DependentScopeDeclRefExpr& expr,
455 const clang::ASTContext& context,
456 std::string& name) {
457 name = RenameDependentScopeName(expr.getDeclName().getAsString());
458 return true;
459 }
460
461 bool GetNameForDecl(const clang::CXXDependentScopeMemberExpr& expr,
462 const clang::ASTContext& context,
463 std::string& name) {
464 name = RenameDependentScopeName(expr.getMember().getAsString());
465 return true;
466 }
467
432 template <typename Type> 468 template <typename Type>
433 struct TargetNodeTraits; 469 struct TargetNodeTraits;
434 470
435 template <> 471 template <>
436 struct TargetNodeTraits<clang::NamedDecl> { 472 struct TargetNodeTraits<clang::NamedDecl> {
437 static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) { 473 static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) {
438 return decl.getLocation(); 474 return decl.getLocation();
439 } 475 }
440 static const char* GetName() { return "decl"; } 476 static const char* GetName() { return "decl"; }
441 static const char* GetType() { return "NamedDecl"; }
Łukasz Anforowicz 2016/08/17 22:45:09 Deleting - this trait was unused AFAICT.
442 }; 477 };
443 478
444 template <> 479 template <>
445 struct TargetNodeTraits<clang::MemberExpr> { 480 struct TargetNodeTraits<clang::MemberExpr> {
446 static clang::SourceLocation GetLoc(const clang::MemberExpr& expr) { 481 static clang::SourceLocation GetLoc(const clang::MemberExpr& expr) {
447 return expr.getMemberLoc(); 482 return expr.getMemberLoc();
448 } 483 }
449 static const char* GetName() { return "expr"; } 484 static const char* GetName() { return "expr"; }
450 static const char* GetType() { return "MemberExpr"; }
451 }; 485 };
452 486
453 template <> 487 template <>
454 struct TargetNodeTraits<clang::DeclRefExpr> { 488 struct TargetNodeTraits<clang::DeclRefExpr> {
455 static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) { 489 static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) {
456 return expr.getLocation(); 490 return expr.getLocation();
457 } 491 }
458 static const char* GetName() { return "expr"; } 492 static const char* GetName() { return "expr"; }
459 static const char* GetType() { return "DeclRefExpr"; }
460 }; 493 };
461 494
462 template <> 495 template <>
496 struct TargetNodeTraits<clang::DependentScopeDeclRefExpr> {
497 static clang::SourceLocation GetLoc(
498 const clang::DependentScopeDeclRefExpr& expr) {
499 return expr.getLocation();
500 }
501 static const char* GetName() { return "decl"; }
502 };
503
504 template <>
505 struct TargetNodeTraits<clang::CXXDependentScopeMemberExpr> {
506 static clang::SourceLocation GetLoc(
507 const clang::CXXDependentScopeMemberExpr& expr) {
508 return expr.getMemberLoc();
509 }
510 static const char* GetName() { return "decl"; }
511 };
512
513 template <>
463 struct TargetNodeTraits<clang::CXXCtorInitializer> { 514 struct TargetNodeTraits<clang::CXXCtorInitializer> {
464 static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) { 515 static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) {
465 assert(init.isWritten()); 516 assert(init.isWritten());
466 return init.getSourceLocation(); 517 return init.getSourceLocation();
467 } 518 }
468 static const char* GetName() { return "initializer"; } 519 static const char* GetName() { return "initializer"; }
469 static const char* GetType() { return "CXXCtorInitializer"; }
470 }; 520 };
471 521
472 template <> 522 template <>
473 struct TargetNodeTraits<clang::UnresolvedLookupExpr> { 523 struct TargetNodeTraits<clang::UnresolvedLookupExpr> {
474 static clang::SourceLocation GetLoc(const clang::UnresolvedLookupExpr& expr) { 524 static clang::SourceLocation GetLoc(const clang::UnresolvedLookupExpr& expr) {
475 return expr.getNameLoc(); 525 return expr.getNameLoc();
476 } 526 }
477 static const char* GetName() { return "expr"; } 527 static const char* GetName() { return "expr"; }
478 static const char* GetType() { return "UnresolvedLookupExpr"; }
479 }; 528 };
480 529
481 template <> 530 template <>
482 struct TargetNodeTraits<clang::UnresolvedMemberExpr> { 531 struct TargetNodeTraits<clang::UnresolvedMemberExpr> {
483 static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) { 532 static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) {
484 return expr.getMemberLoc(); 533 return expr.getMemberLoc();
485 } 534 }
486 static const char* GetName() { return "expr"; } 535 static const char* GetName() { return "expr"; }
487 static const char* GetType() { return "UnresolvedMemberExpr"; }
488 }; 536 };
489 537
538 template <typename T>
539 bool ContainsIdentifier(const T& node) {
540 return node.getIdentifier() != nullptr;
541 }
542
543 bool ContainsIdentifier(const clang::DependentScopeDeclRefExpr& expr) {
544 return true;
545 }
546
547 bool ContainsIdentifier(const clang::CXXDependentScopeMemberExpr& expr) {
548 return true;
549 }
Łukasz Anforowicz 2016/08/17 22:45:09 ContainsIdentifier, IsDeclarationMacroTokenConcate
550
551 bool IsDeclarationMacroTokenConcatenated(
552 const clang::NamedDecl& decl,
553 const clang::SourceManager& source_manager) {
554 clang::SourceLocation decl_loc = decl.getLocation();
555 if (decl_loc.isMacroID()) {
556 // Get the location of the spelling of the declaration. If token pasting
557 // was used this will be in "scratch space" and we don't know how to get
558 // from there back to/ the actual macro with the foo##bar text. So just
559 // don't replace in that case.
560 clang::SourceLocation spell = source_manager.getSpellingLoc(decl_loc);
561 if (strcmp(source_manager.getBufferName(spell), "<scratch space>") == 0)
562 return true;
563 }
564 return false;
565 }
566
567 bool IsDeclarationMacroTokenConcatenated(
568 const clang::DependentScopeDeclRefExpr& expr,
569 const clang::SourceManager& source_manager) {
570 return false; // Heuristic - can't realy tell what |expr| will resolve to...
571 }
572
573 bool IsDeclarationMacroTokenConcatenated(
574 const clang::CXXDependentScopeMemberExpr& expr,
575 const clang::SourceManager& source_manager) {
576 return false; // Heuristic - can't realy tell what |expr| will resolve to...
577 }
578
579 template <typename T>
580 std::string GetCurrentName(const T& node) {
581 return node.getName();
582 }
583
584 std::string GetCurrentName(const clang::DependentScopeDeclRefExpr& expr) {
585 return expr.getDeclName().getAsString();
586 }
587
588 std::string GetCurrentName(const clang::CXXDependentScopeMemberExpr& expr) {
589 return expr.getMember().getAsString();
590 }
591
490 template <typename DeclNode, typename TargetNode> 592 template <typename DeclNode, typename TargetNode>
491 class RewriterBase : public MatchFinder::MatchCallback { 593 class RewriterBase : public MatchFinder::MatchCallback {
492 public: 594 public:
493 explicit RewriterBase(std::set<Replacement>* replacements) 595 explicit RewriterBase(std::set<Replacement>* replacements)
494 : replacements_(replacements) {} 596 : replacements_(replacements) {}
495 597
496 void run(const MatchFinder::MatchResult& result) override { 598 void run(const MatchFinder::MatchResult& result) override {
497 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); 599 const DeclNode& decl = *result.Nodes.getNodeAs<DeclNode>("decl");
498 // If false, there's no name to be renamed. 600
499 if (!decl->getIdentifier()) 601 if (!ContainsIdentifier(decl))
602 return; // If false, there's no name to be renamed.
603 if (IsDeclarationMacroTokenConcatenated(decl, *result.SourceManager))
500 return; 604 return;
501 clang::SourceLocation decl_loc =
502 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl);
503 if (decl_loc.isMacroID()) {
504 // Get the location of the spelling of the declaration. If token pasting
505 // was used this will be in "scratch space" and we don't know how to get
506 // from there back to/ the actual macro with the foo##bar text. So just
507 // don't replace in that case.
508 clang::SourceLocation spell =
509 result.SourceManager->getSpellingLoc(decl_loc);
510 if (strcmp(result.SourceManager->getBufferName(spell),
511 "<scratch space>") == 0)
512 return;
513 }
514 clang::ASTContext* context = result.Context;
515 std::string new_name; 605 std::string new_name;
516 if (!GetNameForDecl(*decl, *context, new_name)) 606 if (!GetNameForDecl(decl, *result.Context, new_name))
517 return; // If false, the name was not suitable for renaming. 607 return; // If false, the name was not suitable for renaming.
518 llvm::StringRef old_name = decl->getName(); 608 llvm::StringRef old_name = GetCurrentName(decl);
519 if (old_name == new_name) 609 if (old_name == new_name)
520 return; 610 return;
611
521 clang::SourceLocation loc = TargetNodeTraits<TargetNode>::GetLoc( 612 clang::SourceLocation loc = TargetNodeTraits<TargetNode>::GetLoc(
522 *result.Nodes.getNodeAs<TargetNode>( 613 *result.Nodes.getNodeAs<TargetNode>(
523 TargetNodeTraits<TargetNode>::GetName())); 614 TargetNodeTraits<TargetNode>::GetName()));
524 clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(loc); 615 clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(loc);
525 replacements_->emplace(*result.SourceManager, range, new_name); 616 replacements_->emplace(*result.SourceManager, range, new_name);
526 replacement_names_.emplace(old_name.str(), std::move(new_name)); 617 replacement_names_.emplace(old_name.str(), std::move(new_name));
527 } 618 }
528 619
529 const std::unordered_map<std::string, std::string>& replacement_names() 620 const std::unordered_map<std::string, std::string>& replacement_names()
530 const { 621 const {
(...skipping 28 matching lines...) Expand all
559 using EnumConstantDeclRefRewriter = 650 using EnumConstantDeclRefRewriter =
560 RewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>; 651 RewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>;
561 652
562 using UnresolvedLookupRewriter = 653 using UnresolvedLookupRewriter =
563 RewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>; 654 RewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>;
564 using UnresolvedMemberRewriter = 655 using UnresolvedMemberRewriter =
565 RewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; 656 RewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>;
566 657
567 using UsingDeclRewriter = RewriterBase<clang::UsingDecl, clang::NamedDecl>; 658 using UsingDeclRewriter = RewriterBase<clang::UsingDecl, clang::NamedDecl>;
568 659
660 using DependentScopeDeclRefExprRewriter =
661 RewriterBase<clang::DependentScopeDeclRefExpr,
662 clang::DependentScopeDeclRefExpr>;
663
664 using CXXDependentScopeMemberExprRewriter =
665 RewriterBase<clang::CXXDependentScopeMemberExpr,
666 clang::CXXDependentScopeMemberExpr>;
667
569 } // namespace 668 } // namespace
570 669
571 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); 670 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
572 671
573 int main(int argc, const char* argv[]) { 672 int main(int argc, const char* argv[]) {
574 // TODO(dcheng): Clang tooling should do this itself. 673 // TODO(dcheng): Clang tooling should do this itself.
575 // http://llvm.org/bugs/show_bug.cgi?id=21627 674 // http://llvm.org/bugs/show_bug.cgi?id=21627
576 llvm::InitializeNativeTarget(); 675 llvm::InitializeNativeTarget();
577 llvm::InitializeNativeTargetAsmParser(); 676 llvm::InitializeNativeTargetAsmParser();
578 llvm::cl::OptionCategory category( 677 llvm::cl::OptionCategory category(
579 "rewrite_to_chrome_style: convert Blink style to Chrome style."); 678 "rewrite_to_chrome_style: convert Blink style to Chrome style.");
580 CommonOptionsParser options(argc, argv, category); 679 CommonOptionsParser options(argc, argv, category);
581 clang::tooling::ClangTool tool(options.getCompilations(), 680 clang::tooling::ClangTool tool(options.getCompilations(),
582 options.getSourcePathList()); 681 options.getSourcePathList());
583 682
584 MatchFinder match_finder; 683 MatchFinder match_finder;
585 std::set<Replacement> replacements; 684 std::set<Replacement> replacements;
586 685
587 auto in_blink_namespace = 686 auto in_blink_namespace =
588 decl(hasAncestor(namespaceDecl(anyOf(hasName("blink"), hasName("WTF")), 687 allOf(hasAncestor(namespaceDecl(anyOf(hasName("blink"), hasName("WTF")),
Łukasz Anforowicz 2016/08/17 22:45:09 s/decl/allOf/ because DependentScopeDeclRefExpr an
589 hasParent(translationUnitDecl()))), 688 hasParent(translationUnitDecl()))),
590 unless(isExpansionInFileMatching(kGeneratedFileRegex))); 689 unless(isExpansionInFileMatching(kGeneratedFileRegex)));
591 690
592 // Field, variable, and enum declarations ======== 691 // Field, variable, and enum declarations ========
593 // Given 692 // Given
594 // int x; 693 // int x;
595 // struct S { 694 // struct S {
596 // int y; 695 // int y;
597 // enum { VALUE }; 696 // enum { VALUE };
598 // }; 697 // };
599 // matches |x|, |y|, and |VALUE|. 698 // matches |x|, |y|, and |VALUE|.
600 auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace)); 699 auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace));
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 // using blink::X; 927 // using blink::X;
829 // matches |using blink::X|. 928 // matches |using blink::X|.
830 auto using_decl_matcher = id( 929 auto using_decl_matcher = id(
831 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf( 930 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf(
832 var_decl_matcher, field_decl_matcher, function_decl_matcher, 931 var_decl_matcher, field_decl_matcher, function_decl_matcher,
833 method_decl_matcher, function_template_decl_matcher, 932 method_decl_matcher, function_template_decl_matcher,
834 method_template_decl_matcher, enum_member_decl_matcher))))); 933 method_template_decl_matcher, enum_member_decl_matcher)))));
835 UsingDeclRewriter using_decl_rewriter(&replacements); 934 UsingDeclRewriter using_decl_rewriter(&replacements);
836 match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter); 935 match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter);
837 936
937 // Template-dependent decl lookup ========
938 // Given
939 // template <typename T> void f() { T::foo(); }
940 // matches |T::foo|.
941 auto dependent_scope_decl_ref_expr_matcher =
942 expr(id("decl", dependentScopeDeclRefExpr(in_blink_namespace)));
Łukasz Anforowicz 2016/08/17 22:45:09 One could argue that I should say "expr" instead o
943 DependentScopeDeclRefExprRewriter dependent_scope_decl_ref_expr_rewriter(
944 &replacements);
945 match_finder.addMatcher(dependent_scope_decl_ref_expr_matcher,
946 &dependent_scope_decl_ref_expr_rewriter);
947
948 // Template-dependent member lookup ========
949 // Given
950 // template <typename T>
951 // class Foo {
952 // void f() { T::foo(); }
953 // };
954 // matches |T::foo|.
955 auto cxx_dependent_scope_member_expr_matcher =
956 expr(id("decl", cxxDependentScopeMemberExpr(in_blink_namespace)));
957 CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter(
958 &replacements);
959 match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher,
960 &cxx_dependent_scope_member_expr_rewriter);
961
838 std::unique_ptr<clang::tooling::FrontendActionFactory> factory = 962 std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
839 clang::tooling::newFrontendActionFactory(&match_finder); 963 clang::tooling::newFrontendActionFactory(&match_finder);
840 int result = tool.run(factory.get()); 964 int result = tool.run(factory.get());
841 if (result != 0) 965 if (result != 0)
842 return result; 966 return result;
843 967
844 #if defined(_WIN32) 968 #if defined(_WIN32)
845 HANDLE lockfd = CreateFile("rewrite-sym.lock", GENERIC_READ, FILE_SHARE_READ, 969 HANDLE lockfd = CreateFile("rewrite-sym.lock", GENERIC_READ, FILE_SHARE_READ,
846 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 970 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
847 OVERLAPPED overlapped = {}; 971 OVERLAPPED overlapped = {};
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 for (const auto& r : replacements) { 1003 for (const auto& r : replacements) {
880 std::string replacement_text = r.getReplacementText().str(); 1004 std::string replacement_text = r.getReplacementText().str();
881 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); 1005 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
882 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() 1006 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
883 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; 1007 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
884 } 1008 }
885 llvm::outs() << "==== END EDITS ====\n"; 1009 llvm::outs() << "==== END EDITS ====\n";
886 1010
887 return 0; 1011 return 0;
888 } 1012 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698