Class: Rufo::Parser

Inherits:
Ripper
  • Object
show all
Defined in:
lib/rufo/parser.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.detect_unparsable_code_type(code) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/rufo/parser.rb', line 36

def self.detect_unparsable_code_type(code)
  tokens = self.lex(code)
  token = tokens.find { |_, kind| kind != :on_sp && kind != :on_ignored_nl }

  case token
  in [_, :on_kw, "yield" | "next" | "break" | "retry" | "redo" => kw, _]
    kw.to_sym
  else
    nil
  end
end

.extract_original_code_sexp(decorated_code, extractor) ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'lib/rufo/parser.rb', line 48

def self.extract_original_code_sexp(decorated_code, extractor)
  sexp = self.sexp(decorated_code)
  return nil unless sexp

  # [:program, [exp]]
  exp = sexp[1][0]
  code_exps = extractor.call(exp)
  [:program, code_exps]
end

.sexp_unparsable_code(code) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/rufo/parser.rb', line 14

def self.sexp_unparsable_code(code)
  code_type = detect_unparsable_code_type(code)

  case code_type
  when :yield
    extract_original_code_sexp(
      "def __rufo_dummy; #{code}; end",
      ->(exp) { exp => [:def, *, [:bodystmt, exps, *]]; exps }
    )
  when :next, :break, :redo
    extract_original_code_sexp(
      "loop do; #{code}; end",
      ->(exp) { exp => [:method_add_block, *, [:do_block, nil, [:bodystmt, [[:void_stmt], *exps], *]]]; exps }
    )
  when :retry
    extract_original_code_sexp(
      "begin; rescue; #{code}; end",
      ->(exp) { exp => [:begin, [:bodystmt, Array, [:rescue, nil, nil, exps, *], *]]; exps }
    )
  end
end

Instance Method Details

#compile_error(msg) ⇒ Object



6
7
8
# File 'lib/rufo/parser.rb', line 6

def compile_error(msg)
  raise ::Rufo::SyntaxError.new(msg, lineno)
end

#on_parse_error(msg) ⇒ Object



10
11
12
# File 'lib/rufo/parser.rb', line 10

def on_parse_error(msg)
  raise ::Rufo::SyntaxError.new(msg, lineno)
end