Class: Astel::Rewriter
Defined Under Namespace
Classes: ConflictError, Edit, EditIndex, ValidationError
Instance Attribute Summary collapse
Instance Method Summary
collapse
#to_diff
Methods included from Refactor
#comment_out, #dedent, #find_keyword_argument, #indent, #indentation_of, #insert_into_body, #insert_keyword_argument, #insert_line_after, #insert_line_before, #insert_list_element, #leading_comments, #reindent, #remove_keyword_argument, #remove_line, #remove_list_element, #remove_list_elements, #remove_with_comments, #replace_keyword_key, #replace_keyword_value, #trailing_comment
Constructor Details
#initialize(source_file, duplicate_insertions: :accept) ⇒ Rewriter
Returns a new instance of Rewriter.
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# File 'lib/astel/rewriter.rb', line 113
def initialize(source_file, duplicate_insertions: :accept)
unless %i[accept raise].include?(duplicate_insertions)
raise ArgumentError, 'duplicate_insertions must be :accept or :raise'
end
@source_file = source_file
@duplicate_insertions = duplicate_insertions
@edits = []
@edits_snapshot = nil
@edit_index = EditIndex.new
@sequence = 0
@result_size_delta = 0
@transaction_staging = false
@transaction_failed = false
end
|
Instance Attribute Details
#source_file ⇒ Object
Returns the value of attribute source_file.
111
112
113
|
# File 'lib/astel/rewriter.rb', line 111
def source_file
@source_file
end
|
Instance Method Details
#edits ⇒ Object
129
130
131
|
# File 'lib/astel/rewriter.rb', line 129
def edits
@edits_snapshot ||= @edits.dup.freeze
end
|
#insert_after(location, content) ⇒ Object
143
144
145
146
|
# File 'lib/astel/rewriter.rb', line 143
def insert_after(location, content)
_, end_offset = offsets(location)
add_edit(end_offset, end_offset, content)
end
|
#insert_before(location, content) ⇒ Object
138
139
140
141
|
# File 'lib/astel/rewriter.rb', line 138
def insert_before(location, content)
start_offset, = offsets(location)
add_edit(start_offset, start_offset, content)
end
|
#merge!(other) ⇒ Object
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
# File 'lib/astel/rewriter.rb', line 160
def merge!(other)
unless other.is_a?(Rewriter) && other.source_file.equal?(@source_file)
raise ArgumentError, 'cannot merge edits for a different source'
end
validation_index = EditIndex.new
@edit_index.each { |edit| validation_index.add(edit) { false } }
other.edits.each do |edit|
conflict = validation_index.find_conflict(edit) { |existing| conflict?(edit, existing) }
raise ConflictError.new(edit, conflict) if conflict
validation_index.add(edit) { false }
end
other.edits.each { |edit| add_edit(edit.start_offset, edit.end_offset, edit.replacement) }
self
end
|
#remove(location) ⇒ Object
148
149
150
|
# File 'lib/astel/rewriter.rb', line 148
def remove(location)
replace(location, '')
end
|
#replace(location, replacement) ⇒ Object
133
134
135
136
|
# File 'lib/astel/rewriter.rb', line 133
def replace(location, replacement)
start_offset, end_offset = offsets(location)
add_edit(start_offset, end_offset, replacement)
end
|
#rewrite(validate: false) ⇒ Object
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
# File 'lib/astel/rewriter.rb', line 192
def rewrite(validate: false)
source = @source_file.source
result = String.new(capacity: source.bytesize + @result_size_delta, encoding: source.encoding)
cursor = 0
@edit_index.each do |edit|
result << source.byteslice(cursor, edit.start_offset - cursor)
result << edit.replacement
cursor = edit.end_offset
end
result << source.byteslice(cursor, source.bytesize - cursor)
validate_result(result, validate)
result
end
|
#transaction(raise_on_conflict: false) ⇒ Object
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
# File 'lib/astel/rewriter.rb', line 177
def transaction(raise_on_conflict: false)
staging = Rewriter.new(@source_file, duplicate_insertions: @duplicate_insertions)
staging.instance_variable_set(:@transaction_staging, true)
yield staging
return transaction_failed if staging.instance_variable_get(:@transaction_failed)
merge!(staging)
true
rescue ConflictError
@transaction_failed = true if @transaction_staging
raise if raise_on_conflict
false
end
|
#wrap(location, before, after) ⇒ Object
152
153
154
155
156
157
158
|
# File 'lib/astel/rewriter.rb', line 152
def wrap(location, before, after)
transaction(raise_on_conflict: true) do |rewriter|
rewriter.insert_before(location, before)
rewriter.insert_after(location, after)
end
self
end
|