Feature #14938
openProvide API to get same result as ruby -wc
Description
I'm the author of an implementation of Ruby Language Server.
Currently, it uses RubyVM::InstructionSequence.compile
to get the result of ruby -wc
and parses message and location by regexp.
Do you have any plan to provide API?
Updated by shevegen (Robert A. Heiler) over 6 years ago
This may also be useful for irb/pry add-ons, I think.
Perhaps Koichi-san can comment on the issue if he has time.
Updated by ko1 (Koichi Sasada) over 6 years ago
Good idea. Do you have an idea about API and implementation?
Maybe parse.y should be modified (== difficult).
Updated by mtsmfm (Fumiaki Matsushima) over 6 years ago
I want to get 3 things.
- Type (warning or error)
- Message
- Location
I think location interface should be the same as RubyVM::AST::Node
https://ruby-doc.org/core-2.6.0.preview2/RubyVM/AST/Node.html
My proposal is the following:
source = <<-RUBY
a = 1
RUBY
results = RubyVM::AST.lint(source) # I'm not sure about suitable class/module for this method
result = results.first
result.type
#=> warning
result.message
#=> assigned but unused variable - a
result.first_lineno
#=> 1
result.last_lineno
#=> 1
result.first_column
#=> 0
result.last_column
#=> 1 (or 5?)
Updated by nobu (Nobuyoshi Nakada) over 6 years ago
Why don't you use ripper?
#!/usr/bin/ruby
require 'ripper'
class Lint < Ripper
def warn(*s)
@results << [:warning, lineno, column, *s]
end
alias warning warn
def results
unless defined?(@results) and @results
@results = []
parse
end
@results
end
end
$VERBOSE = true
results = Lint.new("def f;a = 0;end").results
p results
$ ruby lint.rb
[[:warning, 1, 15, "assigned but unused variable - %s", "a"]]
Updated by mtsmfm (Fumiaki Matsushima) over 6 years ago
Hmm, I tried warn
but it doesn't work in some case:
#!/usr/bin/ruby
require 'ripper'
require 'tempfile'
class Lint < Ripper
def warn(*s)
@results << [:warning, lineno, column, *s]
end
alias warning warn
def results
unless defined?(@results) and @results
@results = []
parse
end
@results
end
end
data = DATA.read
result1 = nil
Tempfile.create do |file|
file.write(data)
file.flush
result1 = `ruby -wc #{file.path}`
end
$VERBOSE = true
result2 = Lint.new(data).results.first
p result1
#=> /tmp/20180729-457-smihk6:1: warning: ambiguous first argument; put parentheses or a space even after `/' operator
#=> "Syntax OK\n"
p result2
#=> nil
__END__
a /#{
}/
In addition,
- How can I get the range of code instead of lineno and column only?
- Is there any way to detect syntax error?
- It seems Ripper#compile_error doesn't work
#!/usr/bin/ruby
require 'ripper'
require 'tempfile'
class Lint < Ripper
def compile_error(*s)
@results << [:error, lineno, column, *s]
end
def results
unless defined?(@results) and @results
@results = []
parse
end
@results
end
end
data = DATA.read
result1 = nil
Tempfile.create do |file|
file.write(data)
file.flush
result1 = `ruby -wc #{file.path}`
end
$VERBOSE = true
result2 = Lint.new(data).results.first
p result1
#=> /tmp/20180729-461-1wcbfr4:1: syntax error, unexpected end-of-input
#=> ""
p result2
#=> nil
__END__
def
Updated by nobu (Nobuyoshi Nakada) over 6 years ago
mtsmfm (Fumiaki Matsushima) wrote:
#=> /tmp/20180729-457-smihk6:1: warning: ambiguous first argument; put parentheses or a space even after `/' operator
This warning dispatches on_arg_ambiguous
method.
- How can I get the range of code instead of lineno and column only?
No way right now.
I think you can propose new methods for them.
#=> /tmp/20180729-461-1wcbfr4:1: syntax error, unexpected end-of-input
It dispatches on_parse_error
method.
Updated by mtsmfm (Fumiaki Matsushima) about 6 years ago
This warning dispatches on_arg_ambiguous method.
It dispatches on_parse_error method.
How can I find the list of all events for warning and compile error?
When should I use compile_error?
https://docs.ruby-lang.org/en/2.5.0/Ripper.html#method-i-compile_error
I think you can propose new methods for them.
You meant adding new methods to Ripper, right?
If Ripper can have first_lineno
, last_lineno
, first_ column
and last_ column
, it's enough for me for now.