Class: HamlLint::RubyExtraction::Coordinator
- Inherits:
-
Object
- Object
- HamlLint::RubyExtraction::Coordinator
- Defined in:
- lib/haml_lint/ruby_extraction/coordinator.rb
Overview
Coordinates the entire RubyExtraction system.
-
Uses the extractor to generate chunks.
-
Preprocess the chunks to cleanup/fuse some of them.
-
Generates the extracted ruby code from the Chunks.
-
Handles the markers (see below)
-
Use the chunks to transfer corrections from corrected Ruby code back to HAML
The generated Ruby code uses markers to wrap around the Ruby code from the chunks. Those markers look like function calls, like: ‘haml_lint_marker_1`, so are valid ruby. After RuboCop does it’s auto-correction, the markers are used to find the pieces of the corrected Ruby code that correspond to each Chunk.
Instance Attribute Summary collapse
-
#assembled_ruby_lines ⇒ Array<String>
readonly
The ruby lines after extraction from HAML (before RuboCop).
-
#autocorrect ⇒ Symbol?
readonly
The autocorrect mode (:safe, :all, or nil).
-
#corrected_ruby_lines ⇒ Array<String>
readonly
The ruby lines after correction by RuboCop.
-
#marker_prefix ⇒ String
readonly
The prefix used for markers in the Ruby code.
-
#script_output_prefix ⇒ String
readonly
The prefix used for to handle ‘= foo` script’s in the extracted Ruby code.
Instance Method Summary collapse
- #add_lines(lines, haml_line_index:, skip_indexes_in_source_map: []) ⇒ Object
- #add_marker(indent, haml_line_index:, name: 'marker') ⇒ Object
- #extract_from_corrected_lines(start_marker_line_number, nb_lines) ⇒ Object
- #extract_ruby_source ⇒ Object
- #find_line_index_of_marker_in_corrections(line, name: 'marker') ⇒ Object
- #haml_lines_with_corrections_applied(corrected_ruby_source) ⇒ Object
-
#initialize(document, autocorrect:) ⇒ Coordinator
constructor
A new instance of Coordinator.
- #line_count ⇒ Object
-
#markers_conflict?(from_ruby_lines, to_ruby_lines) ⇒ Boolean
If the ruby_lines have different markers in them, or are in a different order, then RuboCop did not alter them in a way that is compatible with this system.
- #pick_a_marker_prefix ⇒ Object
- #pick_a_script_output_prefix ⇒ Object
- #preprocess_chunks ⇒ Object
Constructor Details
#initialize(document, autocorrect:) ⇒ Coordinator
Returns a new instance of Coordinator.
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 34 def initialize(document, autocorrect:) @document = document @autocorrect = autocorrect @ruby_chunks = nil @assembled_ruby_lines = nil @corrected_ruby_lines = nil @source_map = {} @script_output_prefix = nil @haml_lines = nil end |
Instance Attribute Details
#assembled_ruby_lines ⇒ Array<String> (readonly)
Returns The ruby lines after extraction from HAML (before RuboCop).
26 27 28 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 26 def assembled_ruby_lines @assembled_ruby_lines end |
#autocorrect ⇒ Symbol? (readonly)
Returns The autocorrect mode (:safe, :all, or nil).
32 33 34 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 32 def autocorrect @autocorrect end |
#corrected_ruby_lines ⇒ Array<String> (readonly)
Returns The ruby lines after correction by RuboCop.
29 30 31 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 29 def corrected_ruby_lines @corrected_ruby_lines end |
#marker_prefix ⇒ String (readonly)
Returns The prefix used for markers in the Ruby code.
23 24 25 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 23 def marker_prefix @marker_prefix end |
#script_output_prefix ⇒ String (readonly)
Returns The prefix used for to handle ‘= foo` script’s in the extracted Ruby code.
20 21 22 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 20 def script_output_prefix @script_output_prefix end |
Instance Method Details
#add_lines(lines, haml_line_index:, skip_indexes_in_source_map: []) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 106 def add_lines(lines, haml_line_index:, skip_indexes_in_source_map: []) nb_skipped_source_map_lines = 0 lines.size.times do |i| if skip_indexes_in_source_map.include?(i) nb_skipped_source_map_lines += 1 end line_number = haml_line_index + 1 # If we skip the first line, we want to them to have the number of the following line line_number = [line_number, line_number + i - nb_skipped_source_map_lines].max @source_map[@assembled_ruby_lines.size + i + 1] = line_number end @assembled_ruby_lines.concat(lines) end |
#add_marker(indent, haml_line_index:, name: 'marker') ⇒ Object
125 126 127 128 129 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 125 def add_marker(indent, haml_line_index:, name: 'marker') add_lines(["#{' ' * indent}#{marker_prefix}_#{name}_#{@assembled_ruby_lines.size + 1}"], haml_line_index: haml_line_index) line_count end |
#extract_from_corrected_lines(start_marker_line_number, nb_lines) ⇒ Object
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 149 def extract_from_corrected_lines(start_marker_line_number, nb_lines) cur_start_marker_index = find_line_index_of_marker_in_corrections(start_marker_line_number) return if cur_start_marker_index.nil? end_marker_line_number = start_marker_line_number + nb_lines + 1 cur_end_marker_index = find_line_index_of_marker_in_corrections(end_marker_line_number) return if cur_end_marker_index.nil? @corrected_ruby_lines[(cur_start_marker_index + 1)..(cur_end_marker_index - 1)] end |
#extract_ruby_source ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 46 def extract_ruby_source return @ruby_source if @ruby_source pick_a_marker_prefix pick_a_script_output_prefix @ruby_chunks = HamlLint::RubyExtraction::ChunkExtractor.new(@document, script_output_prefix: @script_output_prefix, autocorrect: autocorrect).extract preprocess_chunks @assembled_ruby_lines = [] @ruby_chunks.each do |ruby_chunk| ruby_chunk.full_assemble(self) end # Making sure the generated source has a final newline @assembled_ruby_lines << '' if @assembled_ruby_lines.last && !@assembled_ruby_lines.last.empty? @ruby_source = RubySource.new(@assembled_ruby_lines.join("\n"), @source_map, @ruby_chunks) end |
#find_line_index_of_marker_in_corrections(line, name: 'marker') ⇒ Object
139 140 141 142 143 144 145 146 147 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 139 def find_line_index_of_marker_in_corrections(line, name: 'marker') marker = "#{marker_prefix}_#{name}_#{line}" # In the best cases, the line didn't move # Using end_with? because indentation may have been added return line - 1 if @corrected_ruby_lines[line - 1]&.end_with?(marker) @corrected_ruby_lines.index { |l| l.end_with?(marker) } end |
#haml_lines_with_corrections_applied(corrected_ruby_source) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 83 def haml_lines_with_corrections_applied(corrected_ruby_source) @corrected_ruby_lines = corrected_ruby_source.split("\n") @haml_lines = @document.source_lines.dup if markers_conflict?(@assembled_ruby_lines, @corrected_ruby_lines) raise UnableToTransferCorrections, 'The changes in the corrected ruby are not supported' end finished_with_empty_line = @haml_lines.last.empty? # Going in reverse order, so that if we change the number of lines then the # rest of the file will not be offset, which would make things harder @ruby_chunks.reverse_each do |ruby_chunk| ruby_chunk.transfer_correction(self, @corrected_ruby_lines, @haml_lines) end if finished_with_empty_line && !@haml_lines.last.empty? @haml_lines << '' end @haml_lines end |
#line_count ⇒ Object
121 122 123 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 121 def line_count @assembled_ruby_lines.size end |
#markers_conflict?(from_ruby_lines, to_ruby_lines) ⇒ Boolean
If the ruby_lines have different markers in them, or are in a different order, then RuboCop did not alter them in a way that is compatible with this system.
133 134 135 136 137 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 133 def markers_conflict?(from_ruby_lines, to_ruby_lines) from_markers = from_ruby_lines.grep(/#{marker_prefix}/, &:strip) to_markers = to_ruby_lines.grep(/#{marker_prefix}/, &:strip) from_markers != to_markers end |
#pick_a_marker_prefix ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 160 def pick_a_marker_prefix if @document.source.match?(/\bhaml_lint_/) 100.times do suffix = SecureRandom.hex(10) next if @document.source.include?(suffix) @marker_prefix = "haml_lint#{suffix}" return end else @marker_prefix = 'haml_lint' end end |
#pick_a_script_output_prefix ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 173 def pick_a_script_output_prefix if @document.source.match?(/\bHL\.out\b/) 100.times do suffix = SecureRandom.hex(10) next if @document.source.include?(suffix) @script_output_prefix = "HL.out#{suffix} = " return end else @script_output_prefix = 'HL.out = ' end end |
#preprocess_chunks ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 68 def preprocess_chunks return if @ruby_chunks.size < 2 new_chunks = [@ruby_chunks.first] @ruby_chunks[1..].each do |ruby_chunk| fused_chunk = new_chunks.last.fuse(ruby_chunk) if fused_chunk new_chunks[-1] = fused_chunk else new_chunks << ruby_chunk end end @ruby_chunks = new_chunks end |