SyntaxSuggest

SyntaxSuggest (문법 오류 위치 진단)

SyntaxSuggest문법 오류가 난 위치를 찾아 안내해 주는 모듈이에요. SyntaxError가 발생했을 때 그 메시지를 바탕으로 파일을 분석해서, 오류가 어디쯤인지 찾아 stderr로 출력해 줘요.

begin
  require 'bad_file'
rescue => e
  SyntaxSuggest.handle_error(e)
end

출처: Ruby 4.0 API

본문

상수 (Constants)

  • DEFAULT_VALUE - 다른 입력과 혼동되지 않도록 쓰는 기본값 표시용 상수예요.
  • TIMEOUT_DEFAULT
  • VERSION

클래스 메서드 (Public Class Methods)

call(source:, filename: DEFAULT_VALUE, terminal: DEFAULT_VALUE, record_dir: DEFAULT_VALUE, timeout: TIMEOUT_DEFAULT, io: $stderr) [Private]

주요한 private 인터페이스예요. 내부 진단 흐름의 진입점이라 생각하면 돼요.

handle_error(e, re_raise: true, io: $stderr) [Public]

SyntaxError 예외를 받아서, 그 메시지로 파일을 찾아내고 파일을 분석해 문법 오류 위치를 찾아 stderr로 출력해요.

begin
  require 'bad_file'
rescue => e
  SyntaxSuggest.handle_error(e)
end

기본적으로 예외를 다시 던지지만, re_raise: false로 주면 다시 던지지 않아요. 출력 위치는 io: $stderr 인자로 바꿀 수 있어요. 파일명을 알아낼 수 없는 경우에는 re_raise: false여도 원래 예외를 다시 던져요.

invalid?(source) [Private]

주어진 소스가 유효한 문법이 아니면 참(truthy)을 돌려줘요. valid?의 반대 개념이에요.

module_for_detailed_message() [Private]

Module.prepend으로 SyntaxError를 몽키패치(monkeypatch)하는 데 쓰여요.

record_dir(dir) [Private]

디버깅용으로 검색 단계를 기록할 고유한 디렉터리를 만드는 데 써요.

use_prism_parser?() [Private]

prism 파서를 쓸 수 있는지 알려줘요. 못 쓰면 Ripper로 대체(fallback)해야 해요.

valid?(source) [Private]

주어진 소스가 유효한 문법이면 참(truthy)을 돌려줘요.

SyntaxSuggest.valid?(<<~EOM) # => true
  def foo
  end
EOM

SyntaxSuggest.valid?(<<~EOM) # => false
  def foo
    def bar # 여기가 문법 오류
  end
EOM

여러 줄의 배열을 넘기면 이어붙인 뒤 평가해요.

SyntaxSuggest.valid?(
  [
    "def foo\n",
    "end\n"
  ]
) # => true

SyntaxSuggest.valid?(
  [
    "def foo\n",
    "  def bar\n", # 여기가 문법 오류
    "end\n"
  ]
) # => false

참고로 SyntaxSuggest::CodeLine 인스턴스는 to_s에 응답하므로, CodeLine 객체를 그대로(또는 배열로) 넘기면 코드 표현으로 바뀌어 처리돼요.

valid_without?(without_lines:, code_lines:) [Private]

code_lines에서 without_lines를 제거했을 때 유효한 문법인지 알려줘요. 즉 문서에서 아직 문법 오류가 있는 줄을 찾아냈는지 판별하는 방법이에요.

code_lines = [
  CodeLine.new(line: "def foo\n",   index: 0),
  CodeLine.new(line: "  def bar\n", index: 1),
  CodeLine.new(line: "end\n",       index: 2)
]

SyntaxSuggest.valid_without?(
  without_lines: code_lines[1],
  code_lines: code_lines
)                                    # => true

SyntaxSuggest.valid?(code_lines) # => false

인스턴스 메서드 (Public Instance Methods)

detailed_message(highlight: true, syntax_suggest: true, **kwargs)

SyntaxError#detailed_message을 확장하는 메서드예요. 상위 클래스 메서드를 호출해요.