Clang Project

clang_source_code/include/clang/Tooling/FixIt.h
1//===--- FixIt.h - FixIt Hint utilities -------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file implements functions to ease source rewriting from AST-nodes.
10//
11//  Example swapping A and B expressions:
12//
13//    Expr *A, *B;
14//    tooling::fixit::createReplacement(*A, *B);
15//    tooling::fixit::createReplacement(*B, *A);
16//
17//===----------------------------------------------------------------------===//
18
19#ifndef LLVM_CLANG_TOOLING_FIXIT_H
20#define LLVM_CLANG_TOOLING_FIXIT_H
21
22#include "clang/AST/ASTContext.h"
23#include "clang/Basic/TokenKinds.h"
24
25namespace clang {
26namespace tooling {
27namespace fixit {
28
29namespace internal {
30StringRef getText(CharSourceRange Rangeconst ASTContext &Context);
31
32/// Returns the token CharSourceRange corresponding to \p Range.
33inline CharSourceRange getSourceRange(const SourceRange &Range) {
34  return CharSourceRange::getTokenRange(Range);
35}
36
37/// Returns the CharSourceRange of the token at Location \p Loc.
38inline CharSourceRange getSourceRange(const SourceLocation &Loc) {
39  return CharSourceRange::getTokenRange(LocLoc);
40}
41
42/// Returns the CharSourceRange of an given Node. \p Node is typically a
43///        'Stmt', 'Expr' or a 'Decl'.
44template <typename T> CharSourceRange getSourceRange(const T &Node) {
45  return CharSourceRange::getTokenRange(Node.getSourceRange());
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.
50CharSourceRange maybeExtendRange(CharSourceRange Rangetok::TokenKind Next,
51                                 ASTContext &Context);
52// end namespace internal
53
54/// Returns a textual representation of \p Node.
55template <typename T>
56StringRef getText(const T &Nodeconst ASTContext &Context) {
57  return internal::getText(internal::getSourceRange(Node), Context);
58}
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.
63template <typename T>
64CharSourceRange getExtendedRange(const T &Nodetok::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
92template <typename T>
93StringRef getExtendedText(const T &Nodetok::TokenKind Next,
94                          ASTContext &Context) {
95  return internal::getText(getExtendedRange(NodeNextContext), Context);
96}
97
98// Returns a FixItHint to remove \p Node.
99// TODO: Add support for related syntactical elements (i.e. comments, ...).
100template <typename T> FixItHint createRemoval(const T &Node) {
101  return FixItHint::CreateRemoval(internal::getSourceRange(Node));
102}
103
104// Returns a FixItHint to replace \p Destination by \p Source.
105template <typename D, typename S>
106FixItHint createReplacement(const D &Destinationconst S &Source,
107                                   const ASTContext &Context) {
108  return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
109                                      getText(SourceContext));
110}
111
112// Returns a FixItHint to replace \p Destination by \p Source.
113template <typename D>
114FixItHint createReplacement(const D &DestinationStringRef Source) {
115  return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
116                                      Source);
117}
118
119// end namespace fixit
120// end namespace tooling
121// end namespace clang
122
123#endif // LLVM_CLANG_TOOLING_FIXINT_H
124