Class: SeeingIsBelieving::Binary::AnnotateMarkedLines
- Inherits:
-
Object
- Object
- SeeingIsBelieving::Binary::AnnotateMarkedLines
- Defined in:
- lib/seeing_is_believing/binary/annotate_marked_lines.rb
Overview
Based on the behaviour of xmpfilter (a binary in the rcodetools gem) See github.com/JoshCheek/seeing_is_believing/issues/44 for more details
Class Method Summary collapse
- .call(body, results, options) ⇒ Object
- .code_rewriter(markers) ⇒ Object
- .map_markers_to_linenos(program, markers) ⇒ Object
Instance Method Summary collapse
-
#call ⇒ Object
seems like maybe this should respect the alignment strategy (not what xmpfilter does, but there are other ways I’d like to deviate anyway) and we should just add a new alignment strategy for default xmpfilter style.
- #exception_prefix ⇒ Object
-
#initialize(body, results, options = {}) ⇒ AnnotateMarkedLines
constructor
A new instance of AnnotateMarkedLines.
- #nextline_prefix ⇒ Object
- #swap_leading_whitespace_in_multiline_comment(comment) ⇒ Object
- #value_prefix ⇒ Object
- #value_regex ⇒ Object
Constructor Details
#initialize(body, results, options = {}) ⇒ AnnotateMarkedLines
Returns a new instance of AnnotateMarkedLines.
87 88 89 90 91 92 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 87 def initialize(body, results, ={}) @options = @body = body @results = results @interline_align = InterlineAlign.new(results) end |
Class Method Details
.call(body, results, options) ⇒ Object
83 84 85 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 83 def self.call(body, results, ) new(body, results, ).call end |
.code_rewriter(markers) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 40 def self.code_rewriter(markers) lambda do |program| inspect_linenos, pp_map = map_markers_to_linenos(program, markers) pp_linenos = pp_map.values should_inspect = false should_pp = false WrapExpressions.call \ program, before_all: -> { "BEGIN { $SiB.file_loaded };" }, before_each: -> line_number { inspect = "$SiB.record_result(:inspect, #{line_number}, (" pp = "$SiB.record_result(:pp, #{line_number}, (" should_inspect = inspect_linenos.include? line_number should_pp = pp_linenos.include? line_number if should_inspect && should_pp then "#{pp}#{inspect}" elsif should_inspect then inspect elsif should_pp then pp else "" end }, after_each: -> line_number { # 74 b/c pretty print_defaults to 79 (guessing 80 chars with 1 reserved for newline), and # 79 - "# => ".length # => 4 # ALSO: This should be configurable, b/c otherwise you have to go into the guts of `pp` # https://gist.github.com/JoshCheek/6472c8f334ae493f4ab1f7865e2470e5 inspect = ")) { |v| v.inspect }" pp = ")) { |v| PP.pp v, '', 74 }" should_inspect = inspect_linenos.include? line_number should_pp = pp_linenos.include? line_number if should_inspect && should_pp then "#{inspect}#{pp}" elsif should_inspect then inspect elsif should_pp then pp else "" end } end end |
.map_markers_to_linenos(program, markers) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 13 def self.map_markers_to_linenos(program, markers) value_regex = markers[:value][:regex] recordable_lines = [] inspect_linenos = [] pp_map = {} WrapExpressions.call program, before_each: -> line_number { recordable_lines << line_number '' } Code.new(program).inline_comments.each do |c| next unless c.text[value_regex] if c.whitespace_col == 0 lineno = c.line_number loop do lineno -= 1 break if recordable_lines.include?(lineno) || lineno.zero? end pp_map[c.line_number] = lineno else inspect_linenos << c.line_number end end return inspect_linenos, pp_map end |
Instance Method Details
#call ⇒ Object
seems like maybe this should respect the alignment strategy (not what xmpfilter does, but there are other ways I’d like to deviate anyway) and we should just add a new alignment strategy for default xmpfilter style
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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 96 def call @new_body ||= begin require 'seeing_is_believing/binary/rewrite_comments' require 'seeing_is_believing/binary/format_comment' include_lines = [] exception_results = {} @results.exceptions.each do |exception| exception_results[exception.line_number] = sprintf "%s: %s", exception.class_name, exception..gsub("\n", '\n') include_lines << exception.line_number end _, pp_map = self.class.map_markers_to_linenos(@body, @options[:markers]) new_body = RewriteComments.call @body, include_lines: include_lines do |comment| exception_result = exception_results[comment.line_number] annotate_this_line = comment.text[value_regex] pp_annotation = annotate_this_line && comment.whitespace_col.zero? normal_annotation = annotate_this_line && !pp_annotation if exception_result && annotate_this_line [comment.whitespace, FormatComment.call(comment.text_col, value_prefix, exception_result, @options)] elsif exception_result && comment.text.empty? whitespace = comment.whitespace whitespace = " " if whitespace.empty? [whitespace, FormatComment.call(0, exception_prefix, exception_result, @options)] elsif normal_annotation if @options[:interline_align] annotation = @interline_align.call comment.line_number, @results[comment.line_number].map { |result| result.gsub "\n", '\n' } [comment.whitespace, FormatComment.call(comment.text_col, value_prefix, annotation, @options)] else annotation = @results[comment.line_number].map { |result| result.gsub "\n", '\n' }.join(', ') [comment.whitespace, FormatComment.call(comment.text_col, value_prefix, annotation, @options)] end elsif pp_annotation result = @results[pp_map[comment.line_number], :pp] annotation = result.map { |result| result.chomp }.join("\n,") # ["1\n2", "1\n2", ... swap_leading_whitespace_in_multiline_comment(annotation) comment_lines = annotation.each_line.map.with_index do |comment_line, result_offest| if result_offest == 0 FormatComment.call(comment.whitespace_col, value_prefix, comment_line.chomp, @options) else leading_whitespace = " " * comment.text_col leading_whitespace << FormatComment.call(comment.whitespace_col, nextline_prefix, comment_line.chomp, @options) end end comment_lines = [value_prefix.rstrip] if comment_lines.empty? [comment.whitespace, comment_lines.join("\n")] else [comment.whitespace, comment.text] end end require 'seeing_is_believing/binary/annotate_end_of_file' AnnotateEndOfFile.add_stdout_stderr_and_exceptions_to new_body, @results, @options new_body end end |
#exception_prefix ⇒ Object
163 164 165 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 163 def exception_prefix @exception_prefix ||= @options[:markers][:exception][:prefix] end |
#nextline_prefix ⇒ Object
159 160 161 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 159 def nextline_prefix @nextline_prefix ||= ('#' + ' '*value_prefix.length.pred) end |
#swap_leading_whitespace_in_multiline_comment(comment) ⇒ Object
171 172 173 174 175 176 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 171 def swap_leading_whitespace_in_multiline_comment(comment) return if comment.scan("\n").size < 2 return if comment[0] =~ /\S/ nonbreaking_space = " " comment[0] = nonbreaking_space end |
#value_prefix ⇒ Object
155 156 157 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 155 def value_prefix @value_prefix ||= @options[:markers][:value][:prefix] end |
#value_regex ⇒ Object
167 168 169 |
# File 'lib/seeing_is_believing/binary/annotate_marked_lines.rb', line 167 def value_regex @value_regex ||= @options[:markers][:value][:regex] end |