diff options
author | Yitzhak Mandelbaum <yitzhakm@google.com> | 2019-05-22 18:03:00 +0000 |
---|---|---|
committer | Yitzhak Mandelbaum <yitzhakm@google.com> | 2019-05-22 18:03:00 +0000 |
commit | 7566666325307d40dec5c5f47daaf77adab026c8 (patch) | |
tree | 92d6c8315de10cae26b5dccbafe17cb14f4fa681 /lib/Tooling/Refactoring | |
parent | 97176da393dc1164736b74a9f9d7cfd59a280b62 (diff) | |
download | clang-7566666325307d40dec5c5f47daaf77adab026c8.tar.gz |
[LibTooling] Update Stencil to use RangeSelector
Add support for creating a `StencilPart` from any `RangeSelector`, which
broadens the scope of `Stencil`.
Correspondingly, deprecate Stencil's specialized combinators `node` and `sNode`
in favor of using the new `selection` combinator directly (with the appropriate
range selector).
Reviewers: sbenza
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62160
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@361413 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Tooling/Refactoring')
-rw-r--r-- | lib/Tooling/Refactoring/Stencil.cpp | 61 |
1 files changed, 18 insertions, 43 deletions
diff --git a/lib/Tooling/Refactoring/Stencil.cpp b/lib/Tooling/Refactoring/Stencil.cpp index 8fe589b098..09eca21c3c 100644 --- a/lib/Tooling/Refactoring/Stencil.cpp +++ b/lib/Tooling/Refactoring/Stencil.cpp @@ -55,22 +55,11 @@ struct DebugPrintNodeOpData { explicit DebugPrintNodeOpData(std::string S) : Id(std::move(S)) {} std::string Id; }; -// Whether to associate a trailing semicolon with a node when identifying it's -// text. This flag is needed for expressions (clang::Expr), because their role -// is ambiguous when they are also complete statements. When this flag is -// `Always`, an expression node will be treated like a statement, and will -// therefore be associated with any trailing semicolon. -enum class SemiAssociation : bool { - Always, - Inferred, -}; -// A reference to a particular (bound) AST node. -struct NodeRefData { - explicit NodeRefData(std::string S, SemiAssociation SA) - : Id(std::move(S)), SemiAssoc(SA) {} - std::string Id; - SemiAssociation SemiAssoc; +// The fragment of code corresponding to the selected range. +struct SelectorOpData { + explicit SelectorOpData(RangeSelector S) : Selector(std::move(S)) {} + RangeSelector Selector; }; } // namespace @@ -82,9 +71,8 @@ bool isEqualData(const DebugPrintNodeOpData &A, const DebugPrintNodeOpData &B) { return A.Id == B.Id; } -bool isEqualData(const NodeRefData &A, const NodeRefData &B) { - return A.Id == B.Id && A.SemiAssoc == B.SemiAssoc; -} +// Equality is not (yet) defined for \c RangeSelector. +bool isEqualData(const SelectorOpData &, const SelectorOpData &) { return false; } // The `evalData()` overloads evaluate the given stencil data to a string, given // the match result, and append it to `Result`. We define an overload for each @@ -108,25 +96,12 @@ Error evalData(const DebugPrintNodeOpData &Data, return Error::success(); } -Error evalData(const NodeRefData &Data, const MatchFinder::MatchResult &Match, +Error evalData(const SelectorOpData &Data, const MatchFinder::MatchResult &Match, std::string *Result) { - auto NodeOrErr = getNode(Match.Nodes, Data.Id); - if (auto Err = NodeOrErr.takeError()) - return Err; - auto &Node = *NodeOrErr; - switch (Data.SemiAssoc) { - case SemiAssociation::Inferred: - // Include the semicolon for non-expression statements: - *Result += Node.get<Stmt>() != nullptr && Node.get<Expr>() == nullptr - ? getExtendedText(NodeOrErr.get(), tok::TokenKind::semi, - *Match.Context) - : getText(NodeOrErr.get(), *Match.Context); - break; - case SemiAssociation::Always: - *Result += - getExtendedText(NodeOrErr.get(), tok::TokenKind::semi, *Match.Context); - break; - } + auto Range = Data.Selector(Match); + if (!Range) + return Range.takeError(); + *Result += getText(*Range, *Match.Context); return Error::success(); } @@ -162,13 +137,17 @@ public: namespace { using RawText = StencilPartImpl<RawTextData>; using DebugPrintNodeOp = StencilPartImpl<DebugPrintNodeOpData>; -using NodeRef = StencilPartImpl<NodeRefData>; +using SelectorOp = StencilPartImpl<SelectorOpData>; } // namespace StencilPart Stencil::wrap(StringRef Text) { return stencil::text(Text); } +StencilPart Stencil::wrap(RangeSelector Selector) { + return stencil::selection(std::move(Selector)); +} + void Stencil::append(Stencil OtherStencil) { for (auto &Part : OtherStencil.Parts) Parts.push_back(std::move(Part)); @@ -187,12 +166,8 @@ StencilPart stencil::text(StringRef Text) { return StencilPart(std::make_shared<RawText>(Text)); } -StencilPart stencil::node(StringRef Id) { - return StencilPart(std::make_shared<NodeRef>(Id, SemiAssociation::Inferred)); -} - -StencilPart stencil::sNode(StringRef Id) { - return StencilPart(std::make_shared<NodeRef>(Id, SemiAssociation::Always)); +StencilPart stencil::selection(RangeSelector Selector) { + return StencilPart(std::make_shared<SelectorOp>(std::move(Selector))); } StencilPart stencil::dPrint(StringRef Id) { |