|
20 | 20 | #define LLVM_CLANG_TOOLING_FIXIT_H
|
21 | 21 |
|
22 | 22 | #include "clang/AST/ASTContext.h"
|
| 23 | +#include "clang/Basic/TokenKinds.h" |
23 | 24 |
|
24 | 25 | namespace clang {
|
25 | 26 | namespace tooling {
|
26 | 27 | namespace fixit {
|
27 | 28 |
|
28 | 29 | namespace internal {
|
29 |
| -StringRef getText(SourceRange Range, const ASTContext &Context); |
| 30 | +StringRef getText(CharSourceRange Range, const ASTContext &Context); |
30 | 31 |
|
31 |
| -/// Returns the SourceRange of a SourceRange. This identity function is |
32 |
| -/// used by the following template abstractions. |
33 |
| -inline SourceRange getSourceRange(const SourceRange &Range) { return Range; } |
| 32 | +/// Returns the token CharSourceRange corresponding to \p Range. |
| 33 | +inline CharSourceRange getSourceRange(const SourceRange &Range) { |
| 34 | + return CharSourceRange::getTokenRange(Range); |
| 35 | +} |
34 | 36 |
|
35 |
| -/// Returns the SourceRange of the token at Location \p Loc. |
36 |
| -inline SourceRange getSourceRange(const SourceLocation &Loc) { |
37 |
| - return SourceRange(Loc); |
| 37 | +/// Returns the CharSourceRange of the token at Location \p Loc. |
| 38 | +inline CharSourceRange getSourceRange(const SourceLocation &Loc) { |
| 39 | + return CharSourceRange::getTokenRange(Loc, Loc); |
38 | 40 | }
|
39 | 41 |
|
40 |
| -/// Returns the SourceRange of an given Node. \p Node is typically a |
| 42 | +/// Returns the CharSourceRange of an given Node. \p Node is typically a |
41 | 43 | /// 'Stmt', 'Expr' or a 'Decl'.
|
42 |
| -template <typename T> SourceRange getSourceRange(const T &Node) { |
43 |
| - return Node.getSourceRange(); |
| 44 | +template <typename T> CharSourceRange getSourceRange(const T &Node) { |
| 45 | + return CharSourceRange::getTokenRange(Node.getSourceRange()); |
44 | 46 | }
|
| 47 | + |
| 48 | +/// Extends \p Range to include the token \p Next, if it immediately follows the |
| 49 | +/// end of the range. Otherwise, returns \p Range unchanged. |
| 50 | +CharSourceRange maybeExtendRange(CharSourceRange Range, tok::TokenKind Next, |
| 51 | + ASTContext &Context); |
45 | 52 | } // end namespace internal
|
46 | 53 |
|
47 |
| -// Returns a textual representation of \p Node. |
| 54 | +/// Returns a textual representation of \p Node. |
48 | 55 | template <typename T>
|
49 | 56 | StringRef getText(const T &Node, const ASTContext &Context) {
|
50 | 57 | return internal::getText(internal::getSourceRange(Node), Context);
|
51 | 58 | }
|
52 | 59 |
|
| 60 | +/// Returns the source range spanning the node, extended to include \p Next, if |
| 61 | +/// it immediately follows \p Node. Otherwise, returns the normal range of \p |
| 62 | +/// Node. See comments on `getExtendedText()` for examples. |
| 63 | +template <typename T> |
| 64 | +CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next, |
| 65 | + ASTContext &Context) { |
| 66 | + return internal::maybeExtendRange(internal::getSourceRange(Node), Next, |
| 67 | + Context); |
| 68 | +} |
| 69 | + |
| 70 | +/// Returns the source text of the node, extended to include \p Next, if it |
| 71 | +/// immediately follows the node. Otherwise, returns the text of just \p Node. |
| 72 | +/// |
| 73 | +/// For example, given statements S1 and S2 below: |
| 74 | +/// \code |
| 75 | +/// { |
| 76 | +/// // S1: |
| 77 | +/// if (!x) return foo(); |
| 78 | +/// // S2: |
| 79 | +/// if (!x) { return 3; } |
| 80 | +// } |
| 81 | +/// \endcode |
| 82 | +/// then |
| 83 | +/// \code |
| 84 | +/// getText(S1, Context) = "if (!x) return foo()" |
| 85 | +/// getExtendedText(S1, tok::TokenKind::semi, Context) |
| 86 | +/// = "if (!x) return foo();" |
| 87 | +/// getExtendedText(*S1.getThen(), tok::TokenKind::semi, Context) |
| 88 | +/// = "return foo();" |
| 89 | +/// getExtendedText(*S2.getThen(), tok::TokenKind::semi, Context) |
| 90 | +/// = getText(S2, Context) = "{ return 3; }" |
| 91 | +/// \endcode |
| 92 | +template <typename T> |
| 93 | +StringRef getExtendedText(const T &Node, tok::TokenKind Next, |
| 94 | + ASTContext &Context) { |
| 95 | + return internal::getText(getExtendedRange(Node, Next, Context), Context); |
| 96 | +} |
| 97 | + |
53 | 98 | // Returns a FixItHint to remove \p Node.
|
54 | 99 | // TODO: Add support for related syntactical elements (i.e. comments, ...).
|
55 | 100 | template <typename T> FixItHint createRemoval(const T &Node) {
|
|
0 commit comments