Module: Ibex::CLIDiagnostics
- Defined in:
- lib/ibex/cli/diagnostics.rb,
sig/ibex/cli/diagnostics.rbs
Overview
Batch frontend diagnostics subcommand.
Constant Summary collapse
- DIAGNOSTICS_SCHEMA_VERSION =
1- DEFAULT_MAX_DIAGNOSTICS =
20
Instance Method Summary collapse
- #diagnostics_document(result) ⇒ Hash[String, untyped]
- #diagnostics_option_parser(settings) ⇒ OptionParser
- #positive_diagnostic_limit(value) ⇒ Integer
- #resolution_diagnostic(error, fallback_file) ⇒ Frontend::Diagnostic
-
#resolve_diagnostic_result(result, path, mode) ⇒ Frontend::ParseResult
Cross-file recovery is deliberately bounded to the first resolver error.
- #run_diagnose_command(arguments) ⇒ Integer
- #write_diagnostics(result, format:) ⇒ void
Instance Method Details
#diagnostics_document(result) ⇒ Hash[String, untyped]
106 107 108 109 110 111 112 113 114 |
# File 'lib/ibex/cli/diagnostics.rb', line 106 def diagnostics_document(result) { "ibex_diagnostics" => "frontend", "schema_version" => DIAGNOSTICS_SCHEMA_VERSION, "success" => result.success?, "ast_available" => !result.ast.nil?, "diagnostics" => result.diagnostics.map(&:to_h) } end |
#diagnostics_option_parser(settings) ⇒ OptionParser
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/ibex/cli/diagnostics.rb', line 74 def diagnostics_option_parser(settings) OptionParser.new do || . = "Usage: ibex diagnose [options] grammarfile" .on("--format=FORMAT", %w[text json], "text or json") { |value| settings[:format] = value } .on("--max-diagnostics=N", "positive diagnostic limit") do |value| settings[:max_diagnostics] = positive_diagnostic_limit(value) end .on("--mode=MODE", %w[default extended], "grammar mode") { |value| settings[:mode] = value.to_sym } .on("--help", "show help") { settings[:help] = true } end end |
#positive_diagnostic_limit(value) ⇒ Integer
87 88 89 90 91 92 93 94 |
# File 'lib/ibex/cli/diagnostics.rb', line 87 def positive_diagnostic_limit(value) limit = Integer(value, 10) return limit if limit.positive? raise OptionParser::InvalidArgument, "max diagnostics must be positive" rescue ArgumentError raise OptionParser::InvalidArgument, "max diagnostics must be a positive integer" end |
#resolution_diagnostic(error, fallback_file) ⇒ Frontend::Diagnostic
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/ibex/cli/diagnostics.rb', line 57 def resolution_diagnostic(error, fallback_file) match = error..match(/\A(.+):(\d+):(\d+): (.*)\z/m) location = if match Frontend::Location.new( file: match[1].to_s, line: Integer(match[2].to_s), column: Integer(match[3].to_s) ) else Frontend::Location.new(file: fallback_file, line: 1, column: 1) end = match ? match[4].to_s : error. Frontend::Diagnostic.new( code: "frontend.resolution_error", phase: :syntax, message: , location: location, rendered: error. ) end |
#resolve_diagnostic_result(result, path, mode) ⇒ Frontend::ParseResult
Cross-file recovery is deliberately bounded to the first resolver error.
47 48 49 50 51 52 53 54 |
# File 'lib/ibex/cli/diagnostics.rb', line 47 def resolve_diagnostic_result(result, path, mode) Frontend::Resolver.new(path, mode: mode).resolve result rescue Frontend::ResolutionIOError raise rescue Ibex::Error => e Frontend::ParseResult.new(diagnostics: [resolution_diagnostic(e, path)], ast: nil, document: nil) end |
#run_diagnose_command(arguments) ⇒ Integer
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ibex/cli/diagnostics.rb', line 26 def run_diagnose_command(arguments) settings = { format: "text", max_diagnostics: DEFAULT_MAX_DIAGNOSTICS, mode: :default } #: diagnostic_settings parser = diagnostics_option_parser(settings) remaining = parser.parse(arguments) if settings[:help] @stdout.puts(parser) return 0 end path = input_path(remaining) result = Frontend::Parser.new(File.binread(path), file: path, mode: settings.fetch(:mode)) .parse_with_diagnostics(max_diagnostics: settings.fetch(:max_diagnostics)) result = resolve_diagnostic_result(result, path, settings.fetch(:mode)) if result.success? write_diagnostics(result, format: settings.fetch(:format)) result.success? ? 0 : 1 end |
#write_diagnostics(result, format:) ⇒ void
This method returns an undefined value.
97 98 99 100 101 102 103 |
# File 'lib/ibex/cli/diagnostics.rb', line 97 def write_diagnostics(result, format:) if format == "json" @stdout.puts(JSON.pretty_generate(diagnostics_document(result))) else result.diagnostics.each { |diagnostic| @stdout.puts(diagnostic.to_s) } end end |