Class: Ruber::SyntaxChecker::RubySyntaxChecker

Inherits:
Object
  • Object
show all
Defined in:
plugins/syntax_checker/syntax_checker.rb,
plugins/syntax_checker/syntax_checker.rb

Overview

Class which checks the syntax of a ruby file.

To do so, it runs a separate ruby process (using the ruby interpreter set by the Ruby Runner plugin) passing it the -c and the -e options with the document’s content as argument.

The process is executed using Open3.popen3

Instance Method Summary (collapse)

Constructor Details

- (RubySyntaxChecker) initialize(doc)

Creates a new instance.

Parameters:

  • doc (Document)

    the document to check



482
483
484
# File 'plugins/syntax_checker/syntax_checker.rb', line 482

def initialize doc
  @doc = doc
end

Instance Method Details

- (String) check(str)

Checks the syntax of the given string.

syntax errors or an empty string if there were no syntax error

Parameters:

  • str (String)

    the string to check (usually, it’ll be the document’s text)

Returns:

  • (String)

    a string containing the lines of output produced by ruby concerning



493
494
495
496
497
498
499
500
# File 'plugins/syntax_checker/syntax_checker.rb', line 493

def check str
  ruby = Ruber[:ruby_development].interpreter_for @doc
  Open3.popen3(ruby, '-c', '-e', str) do |in_s, out_s, err_s|
    error = err_s.read
    error.gsub! %r{^-e(?=:\d+:\s+syntax error,)}, @doc.path
    out_s.read.strip != 'Syntax OK' ? error : ''
  end
end

- (<SyntaxCheckerPlugin::ErrorDescription>) convert_check_result(str)

Parses the output of #check

corresponding to the syntax errors mentioned in str

Parameters:

  • str (String)

    the string to parse.

Returns:



509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
# File 'plugins/syntax_checker/syntax_checker.rb', line 509

def convert_check_result str
  groups = [[]]
  lines = str.split "\n"
  lines.each do |l|
    if l.match(/^#{Regexp.quote(@doc.path||'')}:\d+:\s+syntax error,\s+/) then groups << [l]
    else groups[-1] << l
    end
  end
  groups.delete_if{|g| g.empty?}
  groups.map do |a|
    a.shift.match(/^#{Regexp.quote(@doc.path||'')}:(\d+):\s+syntax error,\s+(.*)/)
    msgs = [$2]
    error = SyntaxCheckerPlugin::ErrorDescription.new $1.to_i
    if a[-1] and a[-1].match(/^\s*\^\s*$/)
      error.code = a[-2]
# Sometimes, ruby doesn't report the whole line where the error occurs, but only
# the part nearest it. In this case, the beginning of the line is replaced with ... . 
# In this case, to obtain the correct column number, we try a regexp match
# between the part of code reported by ruby and the whole line. If it works, we
# add that position to the one returned by ruby. If it doesn't (for example because
# the user changed the document in the meantime), we'll just report what ruby reports
      col = a[-1].index('^') 
      if a[-2].match(/^\.\.\./)
        lines = @doc.text.split("\n")
        # error.line is 1-based
        l = lines[error.line-1] || ''
        pos = (l =~ /#{Regexp.quote(a[-2][3..-1])}/)
        error.column = pos ? col + pos - 1 : col
      else error.column = col
      end
      a.pop 2
    end
    a.each{|l| msgs << l}
    error.message = msgs.join ' '
    error
  end
end