模块 SyntaxSuggest
常量
- DEFAULT_VALUE
用于指示一个默认值,该值不会与其他输入混淆。
- TIMEOUT_DEFAULT
- VERSION
公共类方法
call(source:, filename: DEFAULT_VALUE, terminal: DEFAULT_VALUE, record_dir: DEFAULT_VALUE, timeout: TIMEOUT_DEFAULT, io: $stderr) 点击切换源代码
SyntaxSuggest.call
[私有]
主要私有接口
# File lib/syntax_suggest/api.rb, line 91 def self.call(source:, filename: DEFAULT_VALUE, terminal: DEFAULT_VALUE, record_dir: DEFAULT_VALUE, timeout: TIMEOUT_DEFAULT, io: $stderr) search = nil filename = nil if filename == DEFAULT_VALUE Timeout.timeout(timeout) do record_dir ||= ENV["DEBUG"] ? "tmp" : nil search = CodeSearch.new(source, record_dir: record_dir).call end blocks = search.invalid_blocks DisplayInvalidBlocks.new( io: io, blocks: blocks, filename: filename, terminal: terminal, code_lines: search.code_lines ).call rescue Timeout::Error => e io.puts "Search timed out SYNTAX_SUGGEST_TIMEOUT=#{timeout}, run with SYNTAX_SUGGEST_DEBUG=1 for more info" io.puts e.backtrace.first(3).join($/) end
handle_error(e, re_raise: true, io: $stderr) 点击切换源代码
SyntaxSuggest.handle_error
[公共]
接收一个 ‘SyntaxError` 异常,使用错误消息定位文件。然后分析文件以找到语法错误的位置,并将该位置输出到 stderr。
示例
begin require 'bad_file' rescue => e SyntaxSuggest.handle_error(e) end
默认情况下,它会重新抛出异常,除非 ‘re_raise: false`。消息输出位置可以使用 `io: $stderr` 输入进行配置。
如果无法确定有效的文件名,则会重新抛出原始异常(即使 ‘re_raise: false`)。
# File lib/syntax_suggest/api.rb, line 68 def self.handle_error(e, re_raise: true, io: $stderr) unless e.is_a?(SyntaxError) io.puts("SyntaxSuggest: Must pass a SyntaxError, got: #{e.class}") raise e end file = PathnameFromMessage.new(e.message, io: io).call.name raise e unless file io.sync = true call( io: io, source: file.read, filename: file ) raise e if re_raise end
invalid?(source) 点击切换源代码
# File lib/syntax_suggest/api.rb, line 160 def self.invalid?(source) source = source.join if source.is_a?(Array) source = source.to_s Prism.parse(source).failure? end
module_for_detailed_message() 点击切换源代码
SyntaxSuggest.module_for_detailed_message
[私有]
用于通过 Module.prepend
对 SyntaxError
进行猴子补丁。
# File lib/syntax_suggest/core_ext.rb, line 27 def self.module_for_detailed_message Module.new { def detailed_message(highlight: true, syntax_suggest: true, **kwargs) return super unless syntax_suggest require "syntax_suggest/api" unless defined?(SyntaxSuggest::DEFAULT_VALUE) message = super if path file = Pathname.new(path) io = SyntaxSuggest::MiniStringIO.new SyntaxSuggest.call( io: io, source: file.read, filename: file, terminal: highlight ) annotation = io.string annotation += "\n" unless annotation.end_with?("\n") annotation + message else message end rescue => e if ENV["SYNTAX_SUGGEST_DEBUG"] $stderr.warn(e.message) $stderr.warn(e.backtrace) end # Ignore internal errors message end } end
record_dir(dir) 点击切换源代码
用于生成一个唯一的目录来记录搜索步骤以进行调试。
# File lib/syntax_suggest/api.rb, line 116 def self.record_dir(dir) time = Time.now.strftime("%Y-%m-%d-%H-%M-%s-%N") dir = Pathname(dir) dir.join(time).tap { |path| path.mkpath alias_dir = dir.join("last") FileUtils.rm_rf(alias_dir) if alias_dir.exist? FileUtils.ln_sf(time, alias_dir) } end
use_prism_parser?() 点击切换源代码
SyntaxSuggest.use_prism_parser?
[私有]
告诉我们是否可以使用 prism 解析器,或者我们是否应该回退到“Ripper”。
# File lib/syntax_suggest/api.rb, line 42 def self.use_prism_parser? defined?(Prism) end
valid?(source) 点击切换源代码
SyntaxSuggest.valid?
[私有]
如果给定的输入源是有效的语法,则返回真值。
SyntaxSuggest.valid?(<<~EOM) # => true def foo end EOM SyntaxSuggest.valid?(<<~EOM) # => false def foo def bar # Syntax error here end EOM
您也可以传入一个行数组,它们将在评估之前被连接。
SyntaxSuggest.valid?( [ "def foo\n", "end\n" ] ) # => true SyntaxSuggest.valid?( [ "def foo\n", " def bar\n", # Syntax error here "end\n" ] ) # => false
作为 FYI,CodeLine
类实例响应“to_s”,因此将 CodeLine
作为对象或数组传入将将其转换为其代码表示形式。
# File lib/syntax_suggest/api.rb, line 211 def self.valid?(source) !invalid?(source) end
valid_without?(without_lines:, code_lines:) 点击切换源代码
SyntaxSuggest.valid_without?
[私有]
这将告诉您,如果您删除了 `without_lines`,`code_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
# File lib/syntax_suggest/api.rb, line 146 def self.valid_without?(without_lines:, code_lines:) lines = code_lines - Array(without_lines).flatten if lines.empty? true else valid?(lines) end end
公共实例方法
detailed_message(highlight: true, syntax_suggest: true, **kwargs) 点击切换源代码
调用超类方法
# File lib/syntax_suggest/core_ext.rb, line 29 def detailed_message(highlight: true, syntax_suggest: true, **kwargs) return super unless syntax_suggest require "syntax_suggest/api" unless defined?(SyntaxSuggest::DEFAULT_VALUE) message = super if path file = Pathname.new(path) io = SyntaxSuggest::MiniStringIO.new SyntaxSuggest.call( io: io, source: file.read, filename: file, terminal: highlight ) annotation = io.string annotation += "\n" unless annotation.end_with?("\n") annotation + message else message end rescue => e if ENV["SYNTAX_SUGGEST_DEBUG"] $stderr.warn(e.message) $stderr.warn(e.backtrace) end # Ignore internal errors message end