Class: RBI::TreeBuilder

Inherits:
ASTVisitor show all
Extended by:
T::Sig
Defined in:
lib/rbi/parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ASTVisitor

#visit_all

Constructor Details

#initialize(file:, comments: {}) ⇒ TreeBuilder

Returns a new instance of TreeBuilder.



105
106
107
108
109
110
111
112
# File 'lib/rbi/parser.rb', line 105

def initialize(file:, comments: {})
  super()
  @file = file
  @comments = comments
  @tree = T.let(Tree.new, Tree)
  @scopes_stack = T.let([@tree], T::Array[Tree])
  @last_sigs = T.let([], T::Array[RBI::Sig])
end

Instance Attribute Details

#treeObject (readonly)

Returns the value of attribute tree.



97
98
99
# File 'lib/rbi/parser.rb', line 97

def tree
  @tree
end

Instance Method Details

#assoc_dangling_comments(comments) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/rbi/parser.rb', line 166

def assoc_dangling_comments(comments)
  last_line = T.let(nil, T.nilable(Integer))
  (comments - @comments.values.flatten).each do |comment|
    comment_line = comment.location.last_line
    text = comment.text[1..-1].strip
    loc = Loc.from_ast_loc(@file, comment.location)

    if last_line && comment_line > last_line + 1
      # Preserve empty lines in file headers
      tree.comments << EmptyComment.new(loc: loc)
    end

    tree.comments << Comment.new(text, loc: loc)
    last_line = comment_line
  end
end

#separate_header_commentsObject



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/rbi/parser.rb', line 144

def separate_header_comments
  return if @comments.empty?

  keep = []
  node = T.must(@comments.keys.first)
  comments = T.must(@comments.values.first)

  last_line = T.let(nil, T.nilable(Integer))
  comments.reverse.each do |comment|
    comment_line = comment.location.last_line

    break if last_line && comment_line < last_line - 1 ||
      !last_line && comment_line < node.first_line - 1

    keep << comment
    last_line = comment_line
  end

  @comments[node] = keep.reverse
end

#visit(node) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/rbi/parser.rb', line 115

def visit(node)
  return unless node.is_a?(AST::Node)
  case node.type
  when :module, :class, :sclass
    scope = parse_scope(node)
    current_scope << scope
    @scopes_stack << scope
    visit_all(node.children)
    @scopes_stack.pop
  when :casgn
    current_scope << parse_const_assign(node)
  when :def, :defs
    current_scope << parse_def(node)
  when :send
    node = parse_send(node)
    current_scope << node if node
  when :block
    node = parse_block(node)
    if node.is_a?(Sig)
      @last_sigs << node
    elsif node
      current_scope << node
    end
  else
    visit_all(node.children)
  end
end