Class: TreeStand::Tree

Inherits:
Object
  • Object
show all
Extended by:
Forwardable, T::Sig
Includes:
Enumerable
Defined in:
lib/tree_stand/tree.rb

Overview

Wrapper around a TreeSitter tree.

This class exposes a convient API for working with the tree. There are dangers in using this class. The tree is mutable and the document can be changed. This class does not protect against that.

Some of the moetods on this class edit and re-parse the document updating the tree. Because the document is re-parsed, the tree will be different. Which means all outstanding nodes & ranges will be invalid.

Methods that edit the document are suffixed with ‘!`, e.g. `#edit!`.

It’s often the case that you will want perfrom multiple edits. One such pattern is to call #query & #edit on all matches in a loop. It’s important to keep the destructive nature of #edit in mind and re-issue the query after each edit.

Another thing to keep in mind is that edits done later in the document will likely not affect the ranges that occur earlier in the document. This can be a convient property that could allow you to apply edits in a reverse order. This is not always possible and depends on the edits you make, beware that the tree will be different after each edit and this approach may cause bugs.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parser, tree, document) ⇒ Tree

Returns a new instance of Tree.



82
83
84
85
86
# File 'lib/tree_stand/tree.rb', line 82

def initialize(parser, tree, document)
  @parser = parser
  @ts_tree = tree
  @document = document
end

Instance Attribute Details

#documentObject (readonly)

Returns the value of attribute document.



33
34
35
# File 'lib/tree_stand/tree.rb', line 33

def document
  @document
end

#parserObject (readonly)

Returns the value of attribute parser.



39
40
41
# File 'lib/tree_stand/tree.rb', line 39

def parser
  @parser
end

#ts_treeObject (readonly)

Returns the value of attribute ts_tree.



36
37
38
# File 'lib/tree_stand/tree.rb', line 36

def ts_tree
  @ts_tree
end

Instance Method Details

#delete!(range) ⇒ Object



108
109
110
111
112
113
# File 'lib/tree_stand/tree.rb', line 108

def delete!(range)
  new_document = +''
  new_document << @document[0...range.start_byte]
  new_document << @document[range.end_byte..]
  replace_with_new_doc(new_document)
end

#edit!(range, replacement) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/tree_stand/tree.rb', line 97

def edit!(range, replacement)
  new_document = +''
  new_document << @document[0...range.start_byte]
  new_document << replacement
  new_document << @document[range.end_byte..]
  replace_with_new_doc(new_document)
end

#find_node(query_string) ⇒ Object

Note:

This is a convenience method that calls Node#find_node on #root_node.



69
70
71
72
73
74
75
76
# File 'lib/tree_stand/tree.rb', line 69

def_delegators(
  :root_node,
  :query,
  :find_node,
  :find_node!,
  :walk,
  :text,
)

#find_node!(query_string) ⇒ Object

Note:

This is a convenience method that calls Node#find_node! on #root_node.



69
70
71
72
73
74
75
76
# File 'lib/tree_stand/tree.rb', line 69

def_delegators(
  :root_node,
  :query,
  :find_node,
  :find_node!,
  :walk,
  :text,
)

#query(query_string) ⇒ Object

Note:

This is a convenience method that calls Node#query on #root_node.



69
70
71
72
73
74
75
76
# File 'lib/tree_stand/tree.rb', line 69

def_delegators(
  :root_node,
  :query,
  :find_node,
  :find_node!,
  :walk,
  :text,
)

#root_nodeObject



89
90
91
# File 'lib/tree_stand/tree.rb', line 89

def root_node
  TreeStand::Node.new(self, @ts_tree.root_node)
end

#textObject

Note:

This is a convenience method that calls Node#text on #root_node.



69
70
71
72
73
74
75
76
# File 'lib/tree_stand/tree.rb', line 69

def_delegators(
  :root_node,
  :query,
  :find_node,
  :find_node!,
  :walk,
  :text,
)

#walk(&block) ⇒ Object Also known as: each

Note:

This is a convenience method that calls Node#walk on #root_node.

Examples:

Tree includes Enumerable

tree.any? { |node| node.type == :error }


69
70
71
72
73
74
75
76
# File 'lib/tree_stand/tree.rb', line 69

def_delegators(
  :root_node,
  :query,
  :find_node,
  :find_node!,
  :walk,
  :text,
)