Module: Semdiff::IOUtils

Includes:
Typeguard::TypeModel::Builder
Included in:
CLI
Defined in:
lib/semdiff/utils/io_utils.rb

Constant Summary collapse

FILE_PREFIX =
'source'
FILE_SUFFIX =
'.rb'
DIR_PREFIX =
'yard_'
DIR_SUFFIX =
'_db'
RUBY_VERSION_F =
RUBY_VERSION.to_f

Instance Method Summary collapse

Instance Method Details

#temp_dir(prefix: DIR_PREFIX, suffix: DIR_SUFFIX) ⇒ Object



221
222
223
# File 'lib/semdiff/utils/io_utils.rb', line 221

def temp_dir(prefix: DIR_PREFIX, suffix: DIR_SUFFIX)
  Dir.mktmpdir([prefix, suffix])
end

#temp_file(content, prefix: FILE_PREFIX, suffix: FILE_SUFFIX) ⇒ Object



214
215
216
217
218
219
# File 'lib/semdiff/utils/io_utils.rb', line 214

def temp_file(content, prefix: FILE_PREFIX, suffix: FILE_SUFFIX)
  f = Tempfile.create([prefix, suffix])
  f.write(content)
  f.close
  f
end

#with_diff_files(contents, names, output_directory: nil) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/semdiff/utils/io_utils.rb', line 166

def with_diff_files(contents, names, output_directory: nil)
  prefix = 'unparsed_'
  if output_directory
    FileUtils.mkdir_p(output_directory)
    b, a = contents.zip(names).map do |c, n|
      path = File.join(output_directory, "#{prefix}#{n}")
      File.write(path, c)
      File.open(path, 'r')
    end
    begin
      yield b, a
    ensure
      b.close
      a.close
    end
  else
    b_temp, a_temp = contents.zip(names).map do |c, n|
      temp_file(c, prefix: '', suffix: "_#{prefix}#{n}")
    end
    begin
      yield b_temp, a_temp
    ensure
      File.unlink(b_temp.path)
      File.unlink(a_temp.path)
    end
  end
end

#with_full_prism(*contents) ⇒ Object



62
63
64
65
66
67
68
69
70
71
# File 'lib/semdiff/utils/io_utils.rb', line 62

def with_full_prism(*contents)
  with_temp_files(*contents) do |files|
    with_temp_dir do |dir|
      system(*yardoc_cmd(files, dir))
      program_node = Prism.parse_file(files.first.path).value
      types = YardBuilder.new(dir, false).build
      yield files, dir, program_node, types
    end
  end
end

#with_full_prism_desugared(*contents) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/semdiff/utils/io_utils.rb', line 40

def with_full_prism_desugared(*contents)
  with_temp_files(*contents) do |files|
    with_temp_dir do |dir|
      system(*yardoc_cmd(files, dir))
      program_nodes = files.map do |f|
        Prism.parse_file(f.path).value.accept(Prism::DesugarCompiler.new)
      end
      types = YardBuilder.new(dir, false).build
      yield files, dir, program_nodes, types
    end
  end
end

#with_prism(*contents) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/semdiff/utils/io_utils.rb', line 73

def with_prism(*contents)
  with_temp_files(*contents) do |files|
    program_node = files.map do |f|
      Prism.parse_file(f.path).value
    end
    yield files, program_node
  end
end

#with_prism_and_yard_types(*contents) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/semdiff/utils/io_utils.rb', line 27

def with_prism_and_yard_types(*contents)
  with_temp_files(*contents) do |files|
    with_temp_dir do |dir|
      system(*yardoc_cmd(files, dir))
      parse_lex_results = files.map do |f|
        Prism.parse_lex_file(f.path)
      end
      types = YardBuilder.new(dir, false).build
      yield files, dir, parse_lex_results, types
    end
  end
end

#with_prism_desugared(*contents) ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/semdiff/utils/io_utils.rb', line 53

def with_prism_desugared(*contents)
  with_temp_files(*contents) do |files|
    program_node = files.map do |f|
      Prism.parse_file(f.path).value.accept(Prism::DesugarCompiler.new)
    end
    yield files, program_node
  end
end

#with_prism_parse_lex(*contents) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/semdiff/utils/io_utils.rb', line 104

def with_prism_parse_lex(*contents)
  with_temp_files(*contents) do |files|
    parse_lex_results = files.map do |f|
      Prism.parse_lex_file(f.path)
    end
    yield files, parse_lex_results
  end
end

#with_rubocop_ast(*contents) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/semdiff/utils/io_utils.rb', line 153

def with_rubocop_ast(*contents)
  with_temp_files(*contents) do |files|
    ast_results = files.map do |f|
      RuboCop::AST::ProcessedSource.from_file(
        f.path,
        RUBY_VERSION_F,
        parser_engine: :parser_prism
      )
    end
    yield files, ast_results
  end
end

#with_rubocop_ast_and_yard_types(*contents) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/semdiff/utils/io_utils.rb', line 122

def with_rubocop_ast_and_yard_types(*contents)
  with_temp_files(*contents) do |files|
    with_temp_dir do |dir|
      system(*yardoc_cmd(files, dir))
      ast_results = files.map do |f|
        RuboCop::AST::ProcessedSource.from_file(
          f.path,
          RUBY_VERSION_F,
          parser_engine: :parser_prism
        )
      end
      types = YardBuilder.new(dir, false).build
      yield files, dir, ast_results, types
    end
  end
end

#with_rubocop_ast_bypass(*file_prism_pairs) {|ast_results| ... } ⇒ Object

Yields:

  • (ast_results)


139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/semdiff/utils/io_utils.rb', line 139

def with_rubocop_ast_bypass(*file_prism_pairs)
  ast_results = file_prism_pairs.map do |f, prism_result|
    source = File.read(f.path)
    RuboCop::AST::ProcessedSource.new(
      source,
      RUBY_VERSION_F,
      f.path,
      parser_engine: :parser_prism,
      prism_result: prism_result
    )
  end
  yield ast_results
end

#with_temp_dir(prefix: DIR_PREFIX, suffix: DIR_SUFFIX) ⇒ Object



205
206
207
208
209
210
211
212
# File 'lib/semdiff/utils/io_utils.rb', line 205

def with_temp_dir(prefix: DIR_PREFIX, suffix: DIR_SUFFIX)
  dir = temp_dir(prefix: prefix, suffix: suffix)
  begin
    yield dir
  ensure
    FileUtils.remove_entry_secure(dir)
  end
end

#with_temp_files(*contents, prefix: FILE_PREFIX, suffix: FILE_SUFFIX) ⇒ Object



194
195
196
197
198
199
200
201
202
203
# File 'lib/semdiff/utils/io_utils.rb', line 194

def with_temp_files(*contents, prefix: FILE_PREFIX, suffix: FILE_SUFFIX)
  files = contents.map.with_index do |content, i|
    temp_file(content, prefix: "#{prefix}#{i}_", suffix: suffix)
  end
  begin
    yield files
  ensure
    files.each { |f| File.unlink(f.path) }
  end
end

#with_types_desugared(*content) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/semdiff/utils/io_utils.rb', line 15

def with_types_desugared(*content)
  with_temp_files(*content) do |files|
    with_temp_dir do |dir|
      system(*yardoc_cmd(files, dir))
      program_node = Prism.parse_file(files.first.path).value
      types = YardBuilder.new(dir, false).build
      node_types = TypeVisitor.new(types).visit(program_node)
      yield program_node, node_types
    end
  end
end

#with_yard_types(*contents) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/semdiff/utils/io_utils.rb', line 82

def with_yard_types(*contents)
  with_temp_files(*contents) do |files|
    with_temp_dir do |dir|
      system(*yardoc_cmd(files, dir))
      types = YardBuilder.new(dir, false).build
      yield files, dir, types
    end
  end
end

#with_yardoc(*contents) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/semdiff/utils/io_utils.rb', line 113

def with_yardoc(*contents)
  with_temp_dir do |dir|
    with_temp_files(*contents) do |files|
      system(*yardoc_cmd(files, dir))
      yield files, dir
    end
  end
end

#with_yardoc_and_prism(*contents) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/semdiff/utils/io_utils.rb', line 92

def with_yardoc_and_prism(*contents)
  with_temp_files(*contents) do |files|
    with_temp_dir do |dir|
      system(*yardoc_cmd(files, dir))
      parse_lex_results = files.map do |f|
        Prism.parse_lex_file(f.path)
      end
      yield files, dir, parse_lex_results
    end
  end
end

#yardoc_cmd(files, db_dir) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/semdiff/utils/io_utils.rb', line 225

def yardoc_cmd(files, db_dir)
  [
    'bundle', 'exec', 'yardoc',
    *files.map(&:path),
    '--db', db_dir,
    '--quiet',
    '--no-output',
    '--no-cache',
    '--fail-on-warning',
    '--embed-mixins'
  ]
end