Clang Project

clang_source_code/include/clang/Tooling/Refactoring/ASTSelection.h
1//===--- ASTSelection.h - Clang refactoring library -----------------------===//
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#ifndef LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
10#define LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
11
12#include "clang/AST/ASTTypeTraits.h"
13#include "clang/Basic/LLVM.h"
14#include "clang/Basic/SourceLocation.h"
15#include <vector>
16
17namespace clang {
18
19class ASTContext;
20
21namespace tooling {
22
23enum class SourceSelectionKind {
24  /// A node that's not selected.
25  None,
26
27  /// A node that's considered to be selected because the whole selection range
28  /// is inside of its source range.
29  ContainsSelection,
30  /// A node that's considered to be selected because the start of the selection
31  /// range is inside its source range.
32  ContainsSelectionStart,
33  /// A node that's considered to be selected because the end of the selection
34  /// range is inside its source range.
35  ContainsSelectionEnd,
36
37  /// A node that's considered to be selected because the node is entirely in
38  /// the selection range.
39  InsideSelection,
40};
41
42/// Represents a selected AST node.
43///
44/// AST selection is represented using a tree of \c SelectedASTNode. The tree
45/// follows the top-down shape of the actual AST. Each selected node has
46/// a selection kind. The kind might be none as the node itself might not
47/// actually be selected, e.g. a statement in macro whose child is in a macro
48/// argument.
49struct SelectedASTNode {
50  ast_type_traits::DynTypedNode Node;
51  SourceSelectionKind SelectionKind;
52  std::vector<SelectedASTNodeChildren;
53
54  SelectedASTNode(const ast_type_traits::DynTypedNode &Node,
55                  SourceSelectionKind SelectionKind)
56      : Node(Node), SelectionKind(SelectionKind) {}
57  SelectedASTNode(SelectedASTNode &&) = default;
58  SelectedASTNode &operator=(SelectedASTNode &&) = default;
59
60  void dump(llvm::raw_ostream &OS = llvm::errs()) const;
61
62  using ReferenceType = std::reference_wrapper<const SelectedASTNode>;
63};
64
65/// Traverses the given ASTContext and creates a tree of selected AST nodes.
66///
67/// \returns None if no nodes are selected in the AST, or a selected AST node
68/// that corresponds to the TranslationUnitDecl otherwise.
69Optional<SelectedASTNodefindSelectedASTNodes(const ASTContext &Context,
70                                               SourceRange SelectionRange);
71
72/// An AST selection value that corresponds to a selection of a set of
73/// statements that belong to one body of code (like one function).
74///
75/// For example, the following selection in the source.
76///
77/// \code
78/// void function() {
79///  // selection begin:
80///  int x = 0;
81///  {
82///     // selection end
83///     x = 1;
84///  }
85///  x = 2;
86/// }
87/// \endcode
88///
89/// Would correspond to a code range selection of statements "int x = 0"
90/// and the entire compound statement that follows it.
91///
92/// A \c CodeRangeASTSelection value stores references to the full
93/// \c SelectedASTNode tree and should not outlive it.
94class CodeRangeASTSelection {
95public:
96  CodeRangeASTSelection(CodeRangeASTSelection &&) = default;
97  CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default;
98
99  /// Returns the parent hierarchy (top to bottom) for the selected nodes.
100  ArrayRef<SelectedASTNode::ReferenceTypegetParents() { return Parents; }
101
102  /// Returns the number of selected statements.
103  size_t size() const {
104    if (!AreChildrenSelected)
105      return 1;
106    return SelectedNode.get().Children.size();
107  }
108
109  const Stmt *operator[](size_t Iconst {
110    if (!AreChildrenSelected) {
111       (0) . __assert_fail ("I == 0 && \"Invalid index\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Tooling/Refactoring/ASTSelection.h", 111, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true">assert(I == 0 && "Invalid index");
112      return SelectedNode.get().Node.get<Stmt>();
113    }
114    return SelectedNode.get().Children[I].Node.get<Stmt>();
115  }
116
117  /// Returns true when a selected code range is in a function-like body
118  /// of code, like a function, method or a block.
119  ///
120  /// This function can be used to test against selected expressions that are
121  /// located outside of a function, e.g. global variable initializers, default
122  /// argument values, or even template arguments.
123  ///
124  /// Use the \c getFunctionLikeNearestParent to get the function-like parent
125  /// declaration.
126  bool isInFunctionLikeBodyOfCode() const;
127
128  /// Returns the nearest function-like parent declaration or null if such
129  /// declaration doesn't exist.
130  const Decl *getFunctionLikeNearestParent() const;
131
132  static Optional<CodeRangeASTSelection>
133  create(SourceRange SelectionRangeconst SelectedASTNode &ASTSelection);
134
135private:
136  CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
137                        ArrayRef<SelectedASTNode::ReferenceTypeParents,
138                        bool AreChildrenSelected)
139      : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
140        AreChildrenSelected(AreChildrenSelected) {}
141
142  /// The reference to the selected node (or reference to the selected
143  /// child nodes).
144  SelectedASTNode::ReferenceType SelectedNode;
145  /// The parent hierarchy (top to bottom) for the selected noe.
146  llvm::SmallVector<SelectedASTNode::ReferenceType8Parents;
147  /// True only when the children of the selected node are actually selected.
148  bool AreChildrenSelected;
149};
150
151// end namespace tooling
152// end namespace clang
153
154#endif // LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
155
clang::tooling::SelectedASTNode::Node
clang::tooling::SelectedASTNode::SelectionKind
clang::tooling::SelectedASTNode::Children
clang::tooling::SelectedASTNode::dump
clang::tooling::CodeRangeASTSelection::getParents
clang::tooling::CodeRangeASTSelection::size
clang::tooling::CodeRangeASTSelection::isInFunctionLikeBodyOfCode
clang::tooling::CodeRangeASTSelection::getFunctionLikeNearestParent
clang::tooling::CodeRangeASTSelection::create
clang::tooling::CodeRangeASTSelection::SelectedNode
clang::tooling::CodeRangeASTSelection::Parents
clang::tooling::CodeRangeASTSelection::AreChildrenSelected