andyw8-seeing_is_believing 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/test.yml +60 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/Gemfile +2 -0
- data/README.md +70 -0
- data/Rakefile +88 -0
- data/appveyor.yml +32 -0
- data/bin/seeing_is_believing +7 -0
- data/docs/example.gif +0 -0
- data/docs/frog-brown.png +0 -0
- data/docs/sib-streaming.gif +0 -0
- data/features/deprecated-flags.feature +91 -0
- data/features/errors.feature +155 -0
- data/features/examples.feature +423 -0
- data/features/flags.feature +852 -0
- data/features/regression.feature +898 -0
- data/features/support/env.rb +102 -0
- data/features/xmpfilter-style.feature +471 -0
- data/lib/seeing_is_believing/binary/align_chunk.rb +47 -0
- data/lib/seeing_is_believing/binary/align_file.rb +24 -0
- data/lib/seeing_is_believing/binary/align_line.rb +25 -0
- data/lib/seeing_is_believing/binary/annotate_end_of_file.rb +56 -0
- data/lib/seeing_is_believing/binary/annotate_every_line.rb +52 -0
- data/lib/seeing_is_believing/binary/annotate_marked_lines.rb +179 -0
- data/lib/seeing_is_believing/binary/comment_lines.rb +36 -0
- data/lib/seeing_is_believing/binary/commentable_lines.rb +126 -0
- data/lib/seeing_is_believing/binary/config.rb +455 -0
- data/lib/seeing_is_believing/binary/data_structures.rb +58 -0
- data/lib/seeing_is_believing/binary/engine.rb +161 -0
- data/lib/seeing_is_believing/binary/format_comment.rb +79 -0
- data/lib/seeing_is_believing/binary/interline_align.rb +57 -0
- data/lib/seeing_is_believing/binary/remove_annotations.rb +113 -0
- data/lib/seeing_is_believing/binary/rewrite_comments.rb +62 -0
- data/lib/seeing_is_believing/binary.rb +73 -0
- data/lib/seeing_is_believing/code.rb +139 -0
- data/lib/seeing_is_believing/compatibility.rb +28 -0
- data/lib/seeing_is_believing/debugger.rb +32 -0
- data/lib/seeing_is_believing/error.rb +17 -0
- data/lib/seeing_is_believing/evaluate_by_moving_files.rb +195 -0
- data/lib/seeing_is_believing/event_stream/consumer.rb +221 -0
- data/lib/seeing_is_believing/event_stream/events.rb +193 -0
- data/lib/seeing_is_believing/event_stream/handlers/debug.rb +61 -0
- data/lib/seeing_is_believing/event_stream/handlers/record_exit_events.rb +26 -0
- data/lib/seeing_is_believing/event_stream/handlers/stream_json_events.rb +23 -0
- data/lib/seeing_is_believing/event_stream/handlers/update_result.rb +41 -0
- data/lib/seeing_is_believing/event_stream/producer.rb +178 -0
- data/lib/seeing_is_believing/hard_core_ensure.rb +58 -0
- data/lib/seeing_is_believing/hash_struct.rb +206 -0
- data/lib/seeing_is_believing/result.rb +89 -0
- data/lib/seeing_is_believing/safe.rb +112 -0
- data/lib/seeing_is_believing/swap_files.rb +90 -0
- data/lib/seeing_is_believing/the_matrix.rb +97 -0
- data/lib/seeing_is_believing/version.rb +3 -0
- data/lib/seeing_is_believing/wrap_expressions.rb +265 -0
- data/lib/seeing_is_believing/wrap_expressions_with_inspect.rb +19 -0
- data/lib/seeing_is_believing.rb +69 -0
- data/seeing_is_believing.gemspec +84 -0
- data/spec/binary/alignment_specs.rb +27 -0
- data/spec/binary/comment_lines_spec.rb +852 -0
- data/spec/binary/config_spec.rb +831 -0
- data/spec/binary/engine_spec.rb +114 -0
- data/spec/binary/format_comment_spec.rb +210 -0
- data/spec/binary/marker_spec.rb +71 -0
- data/spec/binary/remove_annotations_spec.rb +342 -0
- data/spec/binary/rewrite_comments_spec.rb +106 -0
- data/spec/code_spec.rb +233 -0
- data/spec/debugger_spec.rb +45 -0
- data/spec/evaluate_by_moving_files_spec.rb +204 -0
- data/spec/event_stream_spec.rb +762 -0
- data/spec/hard_core_ensure_spec.rb +120 -0
- data/spec/hash_struct_spec.rb +514 -0
- data/spec/seeing_is_believing_spec.rb +1094 -0
- data/spec/sib_spec_helpers/version.rb +17 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/spec_helper_spec.rb +16 -0
- data/spec/wrap_expressions_spec.rb +1013 -0
- metadata +340 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'seeing_is_believing/binary' # defines the markers
|
2
|
+
require 'seeing_is_believing/binary/format_comment'
|
3
|
+
|
4
|
+
class SeeingIsBelieving
|
5
|
+
module Binary
|
6
|
+
module AnnotateEndOfFile
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def add_stdout_stderr_and_exceptions_to(new_body, results, options)
|
10
|
+
output = stdout_ouptut_for(results, options) <<
|
11
|
+
stderr_ouptut_for(results, options) <<
|
12
|
+
exception_output_for(results, options)
|
13
|
+
|
14
|
+
code = Code.new(new_body)
|
15
|
+
code.rewriter.insert_after code.body_range, output
|
16
|
+
new_body.replace code.rewriter.process
|
17
|
+
end
|
18
|
+
|
19
|
+
def stdout_ouptut_for(results, options)
|
20
|
+
return '' unless results.has_stdout?
|
21
|
+
output = "\n"
|
22
|
+
results.stdout.each_line do |line|
|
23
|
+
output << FormatComment.call(0, options[:markers][:stdout][:prefix], line.chomp, options) << "\n"
|
24
|
+
end
|
25
|
+
output
|
26
|
+
end
|
27
|
+
|
28
|
+
def stderr_ouptut_for(results, options)
|
29
|
+
return '' unless results.has_stderr?
|
30
|
+
output = "\n"
|
31
|
+
results.stderr.each_line do |line|
|
32
|
+
output << FormatComment.call(0, options[:markers][:stderr][:prefix], line.chomp, options) << "\n"
|
33
|
+
end
|
34
|
+
output
|
35
|
+
end
|
36
|
+
|
37
|
+
def exception_output_for(results, options)
|
38
|
+
return '' unless results.has_exception?
|
39
|
+
exception_marker = options[:markers][:exception][:prefix]
|
40
|
+
output = ""
|
41
|
+
results.exceptions.each do |exception|
|
42
|
+
output << "\n"
|
43
|
+
output << FormatComment.new(0, exception_marker, exception.class_name, options).call << "\n"
|
44
|
+
exception.message.each_line do |line|
|
45
|
+
output << FormatComment.new(0, exception_marker, line.chomp, options).call << "\n"
|
46
|
+
end
|
47
|
+
output << exception_marker.sub(/\s+$/, '') << "\n"
|
48
|
+
exception.backtrace.each do |line|
|
49
|
+
output << FormatComment.new(0, exception_marker, line.chomp, options).call << "\n"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
output
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'seeing_is_believing/binary/interline_align'
|
2
|
+
|
3
|
+
class SeeingIsBelieving
|
4
|
+
module Binary
|
5
|
+
class AnnotateEveryLine
|
6
|
+
def self.call(body, results, options)
|
7
|
+
new(body, results, options).call
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(body, results, options={})
|
11
|
+
@options = options
|
12
|
+
@body = body
|
13
|
+
@results = results
|
14
|
+
@interline_align = InterlineAlign.new(results)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
@new_body ||= begin
|
19
|
+
require 'seeing_is_believing/binary/comment_lines'
|
20
|
+
require 'seeing_is_believing/binary/format_comment'
|
21
|
+
exception_prefix = @options[:markers][:exception][:prefix]
|
22
|
+
value_prefix = @options[:markers][:value][:prefix]
|
23
|
+
exceptions = Hash.[] @results.exceptions.map { |e| [e.line_number, e] }
|
24
|
+
|
25
|
+
alignment_strategy = @options[:alignment_strategy].new(@body)
|
26
|
+
new_body = CommentLines.call @body do |line, line_number|
|
27
|
+
exception = exceptions[line_number]
|
28
|
+
options = @options.merge pad_to: alignment_strategy.line_length_for(line_number)
|
29
|
+
if exception
|
30
|
+
result = sprintf "%s: %s", exception.class_name, exception.message.gsub("\n", '\n')
|
31
|
+
FormatComment.call(line.size, exception_prefix, result, options)
|
32
|
+
elsif @results[line_number].any?
|
33
|
+
if @options[:interline_align]
|
34
|
+
result = @interline_align.call line_number, @results[line_number].map { |result| result.gsub "\n", '\n' }
|
35
|
+
else
|
36
|
+
result = @results[line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
|
37
|
+
end
|
38
|
+
FormatComment.call(line.size, value_prefix, result, options)
|
39
|
+
else
|
40
|
+
''
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
require 'seeing_is_believing/binary/annotate_end_of_file'
|
45
|
+
AnnotateEndOfFile.add_stdout_stderr_and_exceptions_to new_body, @results, @options
|
46
|
+
|
47
|
+
new_body
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'seeing_is_believing/code'
|
3
|
+
|
4
|
+
# *sigh* need to find a way to join the annotators.
|
5
|
+
# They are sinful ugly, kinda hard to work with,
|
6
|
+
# and absurdly duplicated.
|
7
|
+
|
8
|
+
class SeeingIsBelieving
|
9
|
+
module Binary
|
10
|
+
# Based on the behaviour of xmpfilter (a binary in the rcodetools gem)
|
11
|
+
# See https://github.com/JoshCheek/seeing_is_believing/issues/44 for more details
|
12
|
+
class AnnotateMarkedLines
|
13
|
+
def self.map_markers_to_linenos(program, markers)
|
14
|
+
value_regex = markers[:value][:regex]
|
15
|
+
recordable_lines = []
|
16
|
+
inspect_linenos = []
|
17
|
+
pp_map = {}
|
18
|
+
WrapExpressions.call program, before_each: -> line_number {
|
19
|
+
recordable_lines << line_number
|
20
|
+
''
|
21
|
+
}
|
22
|
+
|
23
|
+
Code.new(program).inline_comments.each do |c|
|
24
|
+
next unless c.text[value_regex]
|
25
|
+
if c.whitespace_col == 0
|
26
|
+
lineno = c.line_number
|
27
|
+
loop do
|
28
|
+
lineno -= 1
|
29
|
+
break if recordable_lines.include?(lineno) || lineno.zero?
|
30
|
+
end
|
31
|
+
pp_map[c.line_number] = lineno
|
32
|
+
else
|
33
|
+
inspect_linenos << c.line_number
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
return inspect_linenos, pp_map
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.code_rewriter(markers)
|
41
|
+
lambda do |program|
|
42
|
+
inspect_linenos, pp_map = map_markers_to_linenos(program, markers)
|
43
|
+
pp_linenos = pp_map.values
|
44
|
+
|
45
|
+
should_inspect = false
|
46
|
+
should_pp = false
|
47
|
+
WrapExpressions.call \
|
48
|
+
program,
|
49
|
+
before_all: -> { "BEGIN { $SiB.file_loaded };" },
|
50
|
+
before_each: -> line_number {
|
51
|
+
inspect = "$SiB.record_result(:inspect, #{line_number}, ("
|
52
|
+
pp = "$SiB.record_result(:pp, #{line_number}, ("
|
53
|
+
|
54
|
+
should_inspect = inspect_linenos.include? line_number
|
55
|
+
should_pp = pp_linenos.include? line_number
|
56
|
+
|
57
|
+
if should_inspect && should_pp then "#{pp}#{inspect}"
|
58
|
+
elsif should_inspect then inspect
|
59
|
+
elsif should_pp then pp
|
60
|
+
else ""
|
61
|
+
end
|
62
|
+
},
|
63
|
+
after_each: -> line_number {
|
64
|
+
# 74 b/c pretty print_defaults to 79 (guessing 80 chars with 1 reserved for newline), and
|
65
|
+
# 79 - "# => ".length # => 4
|
66
|
+
# ALSO: This should be configurable, b/c otherwise you have to go into the guts of `pp`
|
67
|
+
# https://gist.github.com/JoshCheek/6472c8f334ae493f4ab1f7865e2470e5
|
68
|
+
inspect = ")) { |v| v.inspect }"
|
69
|
+
pp = ")) { |v| PP.pp v, '', 74 }"
|
70
|
+
|
71
|
+
should_inspect = inspect_linenos.include? line_number
|
72
|
+
should_pp = pp_linenos.include? line_number
|
73
|
+
|
74
|
+
if should_inspect && should_pp then "#{inspect}#{pp}"
|
75
|
+
elsif should_inspect then inspect
|
76
|
+
elsif should_pp then pp
|
77
|
+
else ""
|
78
|
+
end
|
79
|
+
}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.call(body, results, options)
|
84
|
+
new(body, results, options).call
|
85
|
+
end
|
86
|
+
|
87
|
+
def initialize(body, results, options={})
|
88
|
+
@options = options
|
89
|
+
@body = body
|
90
|
+
@results = results
|
91
|
+
@interline_align = InterlineAlign.new(results)
|
92
|
+
end
|
93
|
+
|
94
|
+
# seems like maybe this should respect the alignment strategy (not what xmpfilter does, but there are other ways I'd like to deviate anyway)
|
95
|
+
# and we should just add a new alignment strategy for default xmpfilter style
|
96
|
+
def call
|
97
|
+
@new_body ||= begin
|
98
|
+
require 'seeing_is_believing/binary/rewrite_comments'
|
99
|
+
require 'seeing_is_believing/binary/format_comment'
|
100
|
+
include_lines = []
|
101
|
+
exception_results = {}
|
102
|
+
|
103
|
+
@results.exceptions.each do |exception|
|
104
|
+
exception_results[exception.line_number] =
|
105
|
+
sprintf "%s: %s", exception.class_name, exception.message.gsub("\n", '\n')
|
106
|
+
include_lines << exception.line_number
|
107
|
+
end
|
108
|
+
|
109
|
+
_, pp_map = self.class.map_markers_to_linenos(@body, @options[:markers])
|
110
|
+
new_body = RewriteComments.call @body, include_lines: include_lines do |comment|
|
111
|
+
exception_result = exception_results[comment.line_number]
|
112
|
+
annotate_this_line = comment.text[value_regex]
|
113
|
+
pp_annotation = annotate_this_line && comment.whitespace_col.zero?
|
114
|
+
normal_annotation = annotate_this_line && !pp_annotation
|
115
|
+
if exception_result && annotate_this_line
|
116
|
+
[comment.whitespace, FormatComment.call(comment.text_col, value_prefix, exception_result, @options)]
|
117
|
+
elsif exception_result && comment.text.empty?
|
118
|
+
whitespace = comment.whitespace
|
119
|
+
whitespace = " " if whitespace.empty?
|
120
|
+
[whitespace, FormatComment.call(0, exception_prefix, exception_result, @options)]
|
121
|
+
elsif normal_annotation
|
122
|
+
if @options[:interline_align]
|
123
|
+
annotation = @interline_align.call comment.line_number, @results[comment.line_number].map { |result| result.gsub "\n", '\n' }
|
124
|
+
[comment.whitespace, FormatComment.call(comment.text_col, value_prefix, annotation, @options)]
|
125
|
+
else
|
126
|
+
annotation = @results[comment.line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
|
127
|
+
[comment.whitespace, FormatComment.call(comment.text_col, value_prefix, annotation, @options)]
|
128
|
+
end
|
129
|
+
elsif pp_annotation
|
130
|
+
result = @results[pp_map[comment.line_number], :pp]
|
131
|
+
annotation = result.map { |result| result.chomp }.join("\n,") # ["1\n2", "1\n2", ...
|
132
|
+
swap_leading_whitespace_in_multiline_comment(annotation)
|
133
|
+
comment_lines = annotation.each_line.map.with_index do |comment_line, result_offest|
|
134
|
+
if result_offest == 0
|
135
|
+
FormatComment.call(comment.whitespace_col, value_prefix, comment_line.chomp, @options)
|
136
|
+
else
|
137
|
+
leading_whitespace = " " * comment.text_col
|
138
|
+
leading_whitespace << FormatComment.call(comment.whitespace_col, nextline_prefix, comment_line.chomp, @options)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
comment_lines = [value_prefix.rstrip] if comment_lines.empty?
|
142
|
+
[comment.whitespace, comment_lines.join("\n")]
|
143
|
+
else
|
144
|
+
[comment.whitespace, comment.text]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
require 'seeing_is_believing/binary/annotate_end_of_file'
|
149
|
+
AnnotateEndOfFile.add_stdout_stderr_and_exceptions_to new_body, @results, @options
|
150
|
+
|
151
|
+
new_body
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def value_prefix
|
156
|
+
@value_prefix ||= @options[:markers][:value][:prefix]
|
157
|
+
end
|
158
|
+
|
159
|
+
def nextline_prefix
|
160
|
+
@nextline_prefix ||= ('#' + ' '*value_prefix.length.pred)
|
161
|
+
end
|
162
|
+
|
163
|
+
def exception_prefix
|
164
|
+
@exception_prefix ||= @options[:markers][:exception][:prefix]
|
165
|
+
end
|
166
|
+
|
167
|
+
def value_regex
|
168
|
+
@value_regex ||= @options[:markers][:value][:regex]
|
169
|
+
end
|
170
|
+
|
171
|
+
def swap_leading_whitespace_in_multiline_comment(comment)
|
172
|
+
return if comment.scan("\n").size < 2
|
173
|
+
return if comment[0] =~ /\S/
|
174
|
+
nonbreaking_space = " "
|
175
|
+
comment[0] = nonbreaking_space
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'seeing_is_believing/binary/commentable_lines'
|
2
|
+
|
3
|
+
class SeeingIsBelieving
|
4
|
+
module Binary
|
5
|
+
# takes a body and a block
|
6
|
+
# passes the block the line
|
7
|
+
# the block returns the comment to add at the end of it
|
8
|
+
class CommentLines
|
9
|
+
def self.call(raw_code, &commenter)
|
10
|
+
new(raw_code, &commenter).call
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(raw_code, &commenter)
|
14
|
+
self.raw_code, self.commenter = raw_code, commenter
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
@call ||= begin
|
19
|
+
commentable_lines = CommentableLines.new raw_code
|
20
|
+
commentable_lines.call.each do |line_number, (index_of_newline, _col)|
|
21
|
+
first_index = last_index = index_of_newline
|
22
|
+
first_index -= 1 while first_index > 0 && raw_code[first_index-1] != "\n"
|
23
|
+
comment_text = commenter.call raw_code[first_index...last_index], line_number
|
24
|
+
range = Parser::Source::Range.new(commentable_lines.buffer, first_index, last_index)
|
25
|
+
commentable_lines.rewriter.insert_after range, comment_text
|
26
|
+
end
|
27
|
+
commentable_lines.rewriter.process
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_accessor :raw_code, :commenter
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'seeing_is_believing/code'
|
2
|
+
|
3
|
+
class SeeingIsBelieving
|
4
|
+
module Binary
|
5
|
+
|
6
|
+
class CommentableLines
|
7
|
+
def self.call(code)
|
8
|
+
new(code).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(code)
|
12
|
+
self.code = code
|
13
|
+
self.code_obj = Code.new(code, 'finding_commentable_lines')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
@call ||= begin
|
18
|
+
line_num_to_location = line_nums_to_last_index_and_col(buffer)
|
19
|
+
remove_lines_after_data_segment line_num_to_location
|
20
|
+
remove_lines_whose_newline_is_escaped line_num_to_location
|
21
|
+
remove_lines_ending_in_comments line_num_to_location, code_obj.raw_comments
|
22
|
+
remove_lines_inside_of_strings_and_things line_num_to_location, root
|
23
|
+
line_num_to_location
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def buffer
|
28
|
+
code_obj.buffer
|
29
|
+
end
|
30
|
+
|
31
|
+
def rewriter
|
32
|
+
code_obj.rewriter
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_writer :buffer, :rewriter
|
38
|
+
attr_accessor :code, :code_obj
|
39
|
+
|
40
|
+
def root
|
41
|
+
code_obj.root
|
42
|
+
end
|
43
|
+
|
44
|
+
def line_nums_to_last_index_and_col(buffer)
|
45
|
+
code.each_char
|
46
|
+
.with_index
|
47
|
+
.select { |char, index| char == "\n" }
|
48
|
+
.each_with_object(Hash.new) do |(_, index), hash|
|
49
|
+
line, col = buffer.decompose_position index
|
50
|
+
hash[line] = [index, col]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_lines_whose_newline_is_escaped(line_num_to_location)
|
55
|
+
ors_indexes = code_obj.indexes_of_ors_at_eol
|
56
|
+
line_num_to_location
|
57
|
+
.select { |line_number, (index_of_newline, _col)|
|
58
|
+
code[index_of_newline-1] == '\\'
|
59
|
+
}
|
60
|
+
.reject { |line_number, (index_of_newline, _col)|
|
61
|
+
ors_indexes.include? index_of_newline
|
62
|
+
}
|
63
|
+
.each { |line_number, (_index_of_newline, _col)|
|
64
|
+
line_num_to_location.delete line_number
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def remove_lines_ending_in_comments(line_num_to_location, comments)
|
69
|
+
comments.each do |comment|
|
70
|
+
if comment.type == :inline
|
71
|
+
line_num_to_location.delete comment.location.line
|
72
|
+
else
|
73
|
+
begin_pos = comment.location.expression.begin_pos
|
74
|
+
end_pos = comment.location.expression.end_pos
|
75
|
+
range = begin_pos...end_pos
|
76
|
+
line_num_to_location.select { |line_number, (index_of_newline, _col)| range.include? index_of_newline }
|
77
|
+
.each { |line_number, (_index_of_newline, _col)| line_num_to_location.delete line_number }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def remove_lines_inside_of_strings_and_things(line_num_to_location, ast)
|
83
|
+
invalid_boundaries = ranges_of_atomic_expressions ast, []
|
84
|
+
invalid_boundaries.each do |invalid_boundary|
|
85
|
+
line_num_to_location.select { |line_number, (index_of_newline, _col)| invalid_boundary.include? index_of_newline }
|
86
|
+
.each { |line_number, (_index_of_newline, _col)| line_num_to_location.delete line_number }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def ranges_of_atomic_expressions(ast, found_ranges)
|
91
|
+
return found_ranges unless ast.kind_of? ::AST::Node
|
92
|
+
if no_comment_zone?(ast) && code_obj.heredoc?(ast)
|
93
|
+
begin_pos = ast.location.heredoc_body.begin_pos
|
94
|
+
end_pos = ast.location.heredoc_end.end_pos.next
|
95
|
+
found_ranges << (begin_pos...end_pos)
|
96
|
+
elsif no_comment_zone? ast
|
97
|
+
begin_pos = ast.location.expression.begin.begin_pos
|
98
|
+
end_pos = ast.location.expression.end.end_pos
|
99
|
+
found_ranges << (begin_pos...end_pos)
|
100
|
+
else
|
101
|
+
ast.children.each { |child| ranges_of_atomic_expressions child, found_ranges }
|
102
|
+
end
|
103
|
+
found_ranges
|
104
|
+
end
|
105
|
+
|
106
|
+
def no_comment_zone?(ast)
|
107
|
+
case ast.type
|
108
|
+
when :dstr, :str, :xstr, :regexp
|
109
|
+
true
|
110
|
+
when :array
|
111
|
+
the_begin = ast.location.begin
|
112
|
+
the_begin && the_begin.source =~ /\A%/
|
113
|
+
else
|
114
|
+
false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def remove_lines_after_data_segment(line_num_to_location)
|
119
|
+
end_index = code_obj.body_range.end_pos
|
120
|
+
body_end = code_obj.index_to_linenum end_index
|
121
|
+
file_end = line_num_to_location.keys.max
|
122
|
+
body_end.upto(file_end) { |line_number| line_num_to_location.delete line_number }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|