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).
-
#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) ⇒ 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) ⇒ Coordinator
Returns a new instance of Coordinator.
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 31 def initialize(document) @document = document @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 |
#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
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 101 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
120 121 122 123 124 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 120 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
144 145 146 147 148 149 150 151 152 153 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 144 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
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 42 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).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
134 135 136 137 138 139 140 141 142 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 134 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
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 78 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
116 117 118 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 116 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.
128 129 130 131 132 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 128 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
155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 155 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
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 168 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
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/haml_lint/ruby_extraction/coordinator.rb', line 63 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 |