Skip to content

Commit 2b98002

Browse files
authored
Merge pull request #30 from mtsmfm/use-iseq
Use RubyVM::InstructionSequence.compile instead of open3
2 parents 9789bfc + 474b1a0 commit 2b98002

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

benchmark/ruby_wc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'bundler/setup'
4+
require 'benchmark/ips'
5+
require 'language_server'
6+
7+
error_code = <<-EOS
8+
require "foo
9+
if a == "\\n"
10+
EOS
11+
warn_code = <<-EOS
12+
a = 1
13+
EOS
14+
valid_code = File.read(__FILE__)
15+
16+
Benchmark.ips do |x|
17+
x.report do
18+
[error_code, warn_code, valid_code].each do |code|
19+
LanguageServer::Linter::RubyWC.new(code).call
20+
end
21+
end
22+
end

language_server.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
3535
spec.add_development_dependency "minitest-power_assert"
3636
spec.add_development_dependency "m"
3737
spec.add_development_dependency "awesome_print"
38+
spec.add_development_dependency "benchmark-ips"
3839
end

lib/language_server/linter/ruby_wc.rb

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require "open3"
1+
require "stringio"
22

33
module LanguageServer
44
module Linter
@@ -26,12 +26,55 @@ def initialize(source)
2626
end
2727

2828
def call
29-
_, err, _ = Open3.capture3("ruby -wc", stdin_data: @source)
30-
31-
err.scan(/.+:(\d+):\s*(.+?)[,:]\s(.+)/).map do |line_num, type, message|
29+
error_message.scan(/.+:(\d+):\s*(.+?)[,:]\s(.+)/).map do |line_num, type, message|
3230
Error.new(line_num: line_num.to_i - 1, message: message, type: type)
3331
end
3432
end
33+
34+
private
35+
36+
# Since Ruby 2.4, syntax error information is outputted to Exception#message instead of stderr
37+
if begin; stderr = $stderr; $stderr = StringIO.new; RubyVM::InstructionSequence.compile('='); rescue SyntaxError => e; e.message != 'compile error'; ensure; $stderr = stderr; end
38+
def error_message
39+
with_verbose do
40+
begin
41+
capture_stderr { RubyVM::InstructionSequence.compile(@source) }
42+
rescue SyntaxError => e
43+
e.message
44+
end
45+
end
46+
end
47+
else
48+
def error_message
49+
with_verbose do
50+
capture_stderr do
51+
begin
52+
RubyVM::InstructionSequence.compile(@source)
53+
rescue SyntaxError
54+
end
55+
end
56+
end
57+
end
58+
end
59+
60+
def with_verbose
61+
origin = $VERBOSE
62+
$VERBOSE = true
63+
yield
64+
ensure
65+
$VERBOSE = origin
66+
end
67+
68+
def capture_stderr
69+
origin = $stderr
70+
$stderr = StringIO.new
71+
72+
yield
73+
74+
$stderr.string
75+
ensure
76+
$stderr = origin
77+
end
3578
end
3679
end
3780
end

0 commit comments

Comments
 (0)