Skip to content

Commit 818ada3

Browse files
committed
refactor: extract CommandLineRunner
Each of the out-of-process parser classes implemented its own CommandLineRunner, and they were all functionally the same (with some small differences that weren't actually used). This pulls the class up to one reused class.
1 parent 86723c6 commit 818ada3

File tree

4 files changed

+52
-114
lines changed

4 files changed

+52
-114
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require "open3"
2+
require "timeout"
3+
4+
module CC
5+
module Engine
6+
module Analyzers
7+
class CommandLineRunner
8+
DEFAULT_TIMEOUT = 20
9+
10+
def initialize(command, timeout = DEFAULT_TIMEOUT)
11+
@command = command
12+
@timeout = timeout
13+
end
14+
15+
def run(input)
16+
Timeout.timeout(timeout) do
17+
Open3.popen3 command, "r+" do |stdin, stdout, stderr, wait_thr|
18+
stdin.puts input
19+
stdin.close
20+
21+
exit_code = wait_thr.value
22+
23+
output = stdout.gets
24+
stdout.close
25+
26+
err_output = stderr.gets
27+
stderr.close
28+
29+
if 0 == exit_code
30+
yield output
31+
else
32+
raise ::CC::Engine::Analyzers::ParserError, "Python parser exited with code #{exit_code}:\n#{err_output}"
33+
end
34+
end
35+
end
36+
end
37+
38+
private
39+
40+
attr_reader :command, :timeout
41+
end
42+
end
43+
end
44+
end
45+

lib/cc/engine/analyzers/javascript/parser.rb

+2-43
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
require "open3"
2-
require "timeout"
3-
1+
require "cc/engine/analyzers/command_line_runner"
42

53
module CC
64
module Engine
@@ -15,7 +13,7 @@ def initialize(code, filename)
1513
end
1614

1715
def parse
18-
runner = CommandLineRunner.new(js_command, self)
16+
runner = CommandLineRunner.new(js_command)
1917
runner.run(strip_shebang(code)) do |ast|
2018
json_ast = JSON.parse(ast)
2119
@syntax_tree = json_ast
@@ -39,45 +37,6 @@ def strip_shebang(code)
3937
end
4038
end
4139
end
42-
43-
class CommandLineRunner
44-
attr_reader :command, :delegate
45-
46-
DEFAULT_TIMEOUT = 20
47-
EXCEPTIONS = [
48-
StandardError,
49-
Timeout::Error,
50-
SystemStackError
51-
]
52-
53-
def initialize(command, delegate)
54-
@command = command
55-
@delegate = delegate
56-
end
57-
58-
def run(input, timeout = DEFAULT_TIMEOUT)
59-
Timeout.timeout(timeout) do
60-
Open3.popen3 command, "r+" do |stdin, stdout, stderr, wait_thr|
61-
stdin.puts input
62-
stdin.close
63-
64-
exit_code = wait_thr.value
65-
66-
output = stdout.gets
67-
stdout.close
68-
69-
err_output = stderr.gets
70-
stderr.close
71-
72-
if 0 == exit_code
73-
yield output
74-
else
75-
raise ::CC::Engine::Analyzers::ParserError, "Python parser exited with code #{exit_code}:\n#{err_output}"
76-
end
77-
end
78-
end
79-
end
80-
end
8140
end
8241
end
8342
end

lib/cc/engine/analyzers/php/parser.rb

+3-35
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
require 'cc/engine/analyzers/php/ast'
2-
require 'cc/engine/analyzers/php/nodes'
1+
require "cc/engine/analyzers/command_line_runner"
2+
require "cc/engine/analyzers/php/ast"
3+
require "cc/engine/analyzers/php/nodes"
34

45
module CC
56
module Engine
@@ -36,39 +37,6 @@ def parser_path
3637
)
3738
end
3839
end
39-
40-
class CommandLineRunner
41-
attr_reader :command, :delegate
42-
43-
DEFAULT_TIMEOUT = 20
44-
45-
def initialize(command)
46-
@command = command
47-
end
48-
49-
def run(input, timeout = DEFAULT_TIMEOUT)
50-
Timeout.timeout(timeout) do
51-
Open3.popen3 command, "r+" do |stdin, stdout, stderr, wait_thr|
52-
stdin.puts input
53-
stdin.close
54-
55-
exit_code = wait_thr.value
56-
57-
output = stdout.gets
58-
stdout.close
59-
60-
err_output = stderr.gets
61-
stderr.close
62-
63-
if 0 == exit_code
64-
yield output
65-
else
66-
raise ::CC::Engine::Analyzers::ParserError, "Python parser exited with code #{exit_code}:\n#{err_output}"
67-
end
68-
end
69-
end
70-
end
71-
end
7240
end
7341
end
7442
end

lib/cc/engine/analyzers/python/parser.rb

+2-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
require "cc/engine/analyzers/command_line_runner"
12
require "timeout"
23
require "json"
3-
require "open3"
44

55
module CC
66
module Engine
@@ -15,7 +15,7 @@ def initialize(code, filename)
1515
end
1616

1717
def parse
18-
runner = CommandLineRunner.new(python_command, self)
18+
runner = CommandLineRunner.new(python_command)
1919
runner.run(code) do |ast|
2020
json_ast = JSON.parse(ast)
2121
@syntax_tree = json_ast
@@ -29,40 +29,6 @@ def python_command
2929
"python #{file}"
3030
end
3131
end
32-
33-
class CommandLineRunner
34-
DEFAULT_TIMEOUT = 20
35-
36-
attr_reader :command, :delegate
37-
38-
def initialize(command, delegate)
39-
@command = command
40-
@delegate = delegate
41-
end
42-
43-
def run(input, timeout = DEFAULT_TIMEOUT)
44-
Timeout.timeout(timeout) do
45-
Open3.popen3 command, "r+" do |stdin, stdout, stderr, wait_thr|
46-
stdin.puts input
47-
stdin.close
48-
49-
exit_code = wait_thr.value
50-
51-
output = stdout.gets
52-
stdout.close
53-
54-
err_output = stderr.gets
55-
stderr.close
56-
57-
if 0 == exit_code
58-
yield output
59-
else
60-
raise ::CC::Engine::Analyzers::ParserError, "Python parser exited with code #{exit_code}:\n#{err_output}"
61-
end
62-
end
63-
end
64-
end
65-
end
6632
end
6733
end
6834
end

0 commit comments

Comments
 (0)