Class: AnnotateRb::ModelAnnotator::FileParser::CustomParser

Inherits:
Ripper
  • Object
show all
Defined in:
lib/annotate_rb/model_annotator/file_parser/custom_parser.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ CustomParser

Returns a new instance of CustomParser.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 20

def initialize(input, ...)
  super
  @_stack_code_block = []
  @_input = input
  @_const_event_map = {}

  @comments = []
  @block_starts = []
  @block_ends = []
  @const_type_map = {}
end

Instance Attribute Details

#commentsObject (readonly)

Returns the value of attribute comments.



18
19
20
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 18

def comments
  @comments
end

Class Method Details

.parse(string) ⇒ Object



13
14
15
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 13

def parse(string)
  _parser = new(string, "", 0).tap(&:parse)
end

Instance Method Details

#endsObject



36
37
38
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 36

def ends
  @block_ends
end

#on_call(receiver, operator, message) ⇒ Object

Gets the ‘FactoryBot` line in: “`ruby FactoryBot.define do

factory :user do
  ...
end

end “‘



140
141
142
143
144
145
146
147
148
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 140

def on_call(receiver, operator, message)
  # We only want to add the parsed line if the beginning of the Ruby
  if @block_starts.empty?
    add_event(__method__, receiver, lineno)
    @block_starts << [receiver, lineno]
  end

  super
end

#on_class(const, _superclass, _bodystmt) ⇒ Object



73
74
75
76
77
78
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 73

def on_class(const, _superclass, _bodystmt)
  add_event(__method__, const, lineno)
  @const_type_map[const] = :class unless @const_type_map[const]
  @block_ends << [const, lineno]
  super
end

#on_command(message, args) ⇒ Object

Gets the ‘factory` block start in: “`ruby factory :user, aliases: [:author, :commenter] do

...

end “‘



156
157
158
159
160
161
162
163
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 156

def on_command(message, args)
  add_event(__method__, message, lineno)
  @block_starts << [message, lineno]

  # We keep track of blocks using a stack
  @_stack_code_block << message
  super
end

#on_command_call(receiver, operator, method, args) ⇒ Object

Gets the ‘RSpec` opening in: “`ruby RSpec.describe “Collapsed::TestModel” do

# Deliberately left empty

end “‘ receiver: “RSpec”, operator: “.”, method: “describe”



87
88
89
90
91
92
93
94
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 87

def on_command_call(receiver, operator, method, args)
  add_event(__method__, receiver, lineno)
  @block_starts << [receiver, lineno]

  # We keep track of blocks using a stack
  @_stack_code_block << receiver
  super
end

#on_comment(value) ⇒ Object



199
200
201
202
203
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 199

def on_comment(value)
  add_event(__method__, value, lineno)
  @comments << [value.strip, lineno]
  super
end

#on_const_path_ref(_left, const) ⇒ Object

Used for ‘class Foo::User`



60
61
62
63
64
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 60

def on_const_path_ref(_left, const)
  add_event(__method__, const, lineno)
  @block_starts << [const, lineno]
  super
end

#on_const_ref(const) ⇒ Object



53
54
55
56
57
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 53

def on_const_ref(const)
  add_event(__method__, const, lineno)
  @block_starts << [const, lineno]
  super
end

#on_do_block(block_var, bodystmt) ⇒ Object

Matches the ‘end` in: “`ruby factory :user, aliases: [:author, :commenter] do

first_name { "John" }
last_name { "Doe" }
date_of_birth { 18.years.ago }

end “‘



173
174
175
176
177
178
179
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 173

def on_do_block(block_var, bodystmt)
  if block_var.blank? && bodystmt.blank?
    @block_ends << ["end", lineno]
    add_event(__method__, "end", lineno)
  end
  super
end

#on_embdoc(value) ⇒ Object



193
194
195
196
197
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 193

def on_embdoc(value)
  add_event(__method__, value, lineno)
  @comments << [value.strip, lineno]
  super
end

#on_embdoc_beg(value) ⇒ Object



181
182
183
184
185
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 181

def on_embdoc_beg(value)
  add_event(__method__, value, lineno)
  @comments << [value.strip, lineno]
  super
end

#on_embdoc_end(value) ⇒ Object



187
188
189
190
191
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 187

def on_embdoc_end(value)
  add_event(__method__, value, lineno)
  @comments << [value.strip, lineno]
  super
end

#on_method_add_arg(method, args) ⇒ Object



123
124
125
126
127
128
129
130
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 123

def on_method_add_arg(method, args)
  add_event(__method__, method, lineno)
  @block_starts << [method, lineno]

  # We keep track of blocks using a stack
  @_stack_code_block << method
  super
end

#on_method_add_block(method, block) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 96

def on_method_add_block(method, block)
  # When parsing a line with no explicit receiver, the method will be presented in an Array.
  # It's not immediately clear why.
  #
  # Example:
  # ```ruby
  # describe "Collapsed::TestModel" do
  #   # Deliberately left empty
  # end
  # ```
  #
  # => method = ["describe"]
  if method.is_a?(Array) && method.size == 1
    method = method.first
  end

  add_event(__method__, method, lineno)

  if @_stack_code_block.last == method
    @block_ends << [method, lineno]
    @_stack_code_block.pop
  else
    @block_starts << [method, lineno]
  end
  super
end

#on_module(const, _bodystmt) ⇒ Object



66
67
68
69
70
71
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 66

def on_module(const, _bodystmt)
  add_event(__method__, const, lineno)
  @const_type_map[const] = :module unless @const_type_map[const]
  @block_ends << [const, lineno]
  super
end

#on_programObject



44
45
46
47
48
49
50
51
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 44

def on_program(...)
  {
    comments: @comments,
    starts: @block_starts,
    ends: @block_ends,
    type_map: @const_type_map
  }
end

#startsObject



32
33
34
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 32

def starts
  @block_starts
end

#type_mapObject



40
41
42
# File 'lib/annotate_rb/model_annotator/file_parser/custom_parser.rb', line 40

def type_map
  @const_type_map
end