clang-tools  9.0.0
Selection.h
Go to the documentation of this file.
1 //===--- Selection.h - What's under the cursor? -------------------*-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 // Many features are triggered at locations/ranges and operate on AST nodes.
9 // (e.g. go-to-definition or code tweaks).
10 // At a high level, such features need to work out which node is the correct
11 // target.
12 //
13 // There are a few levels of ambiguity here:
14 //
15 // Which tokens are included:
16 // int x = one + two; // what should "go to definition" do?
17 // ^^^^^^
18 //
19 // Same token means multiple things:
20 // string("foo") // class string, or a constructor?
21 // ^
22 //
23 // Which level of the AST is interesting?
24 // if (err) { // reference to 'err', or operator bool(),
25 // ^ // or the if statement itself?
26 //
27 // Here we build and expose a data structure that allows features to resolve
28 // these ambiguities in an appropriate way:
29 // - we determine which low-level nodes are partly or completely covered
30 // by the selection.
31 // - we expose a tree of the selected nodes and their lexical parents.
32 //===----------------------------------------------------------------------===//
33 
34 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SELECTION_H
35 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SELECTION_H
36 #include "clang/AST/ASTTypeTraits.h"
37 #include "clang/AST/PrettyPrinter.h"
38 #include "llvm/ADT/SmallVector.h"
39 
40 namespace clang {
41 namespace clangd {
42 class ParsedAST;
43 
44 // A selection can partially or completely cover several AST nodes.
45 // The SelectionTree contains nodes that are covered, and their parents.
46 // SelectionTree does not contain all AST nodes, rather only:
47 // Decl, Stmt, TypeLoc, NestedNamespaceSpecifierLoc, CXXCtorInitializer.
48 // (These are the nodes with source ranges that fit in DynTypedNode).
49 //
50 // Usually commonAncestor() is the place to start:
51 // - it's the simplest answer to "what node is under the cursor"
52 // - the selected Expr (for example) can be found by walking up the parent
53 // chain and checking Node->ASTNode.
54 // - if you want to traverse the selected nodes, they are all under
55 // commonAncestor() in the tree.
56 //
57 // The SelectionTree owns the Node structures, but the ASTNode attributes
58 // point back into the AST it was constructed with.
60 public:
61  // Creates a selection tree at the given byte offset in the main file.
62  // This is approximately equivalent to a range of one character.
63  // (Usually, the character to the right of Offset, sometimes to the left).
64  SelectionTree(ASTContext &AST, unsigned Offset);
65  // Creates a selection tree for the given range in the main file.
66  // The range includes bytes [Start, End).
67  // If Start == End, uses the same heuristics as SelectionTree(AST, Start).
68  SelectionTree(ASTContext &AST, unsigned Start, unsigned End);
69 
70  // Describes to what extent an AST node is covered by the selection.
71  enum Selection {
72  // The AST node owns no characters covered by the selection.
73  // Note that characters owned by children don't count:
74  // if (x == 0) scream();
75  // ^^^^^^
76  // The IfStmt would be Unselected because all the selected characters are
77  // associated with its children.
78  // (Invisible nodes like ImplicitCastExpr are always unselected).
80  // The AST node owns selected characters, but is not completely covered.
82  // The AST node owns characters, and is covered by the selection.
84  };
85  // An AST node that is implicated in the selection.
86  // (Either selected directly, or some descendant is selected).
87  struct Node {
88  // The parent within the selection tree. nullptr for TranslationUnitDecl.
90  // Direct children within the selection tree.
91  llvm::SmallVector<const Node *, 8> Children;
92  // The corresponding node from the full AST.
93  ast_type_traits::DynTypedNode ASTNode;
94  // The extent to which this node is covered by the selection.
96  // Walk up the AST to get the DeclContext of this Node,
97  // which is not the node itself.
98  const DeclContext& getDeclContext() const;
99  };
100 
101  // The most specific common ancestor of all the selected nodes.
102  // If there is no selection, this is nullptr.
103  const Node *commonAncestor() const;
104  // The selection node corresponding to TranslationUnitDecl.
105  // If there is no selection, this is nullptr.
106  const Node *root() const { return Root; }
107 
108 private:
109  std::deque<Node> Nodes; // Stable-pointer storage.
110  const Node *Root;
111  clang::PrintingPolicy PrintPolicy;
112 
113  void print(llvm::raw_ostream &OS, const Node &N, int Indent) const;
114  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
115  const SelectionTree &T) {
116  if (auto R = T.root())
117  T.print(OS, *R, 0);
118  else
119  OS << "(empty selection)\n";
120  return OS;
121  }
122 };
123 
124 } // namespace clangd
125 } // namespace clang
126 #endif
const Node * root() const
Definition: Selection.h:106
llvm::SmallVector< const Node *, 8 > Children
Definition: Selection.h:91
friend llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const SelectionTree &T)
Definition: Selection.h:114
size_t Offset
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
ast_type_traits::DynTypedNode ASTNode
Definition: Selection.h:93
SelectionTree(ASTContext &AST, unsigned Offset)
Definition: Selection.cpp:355
const Node * commonAncestor() const
Definition: Selection.cpp:358
const DeclContext & getDeclContext() const
Definition: Selection.cpp:367