Class: Ibex::LSP::ParserConfigurationAssistance
- Inherits:
-
Object
- Object
- Ibex::LSP::ParserConfigurationAssistance
- Defined in:
- lib/ibex/lsp/parser_configuration_assistance.rb,
sig/ibex/lsp/parser_configuration_assistance.rbs
Overview
Provides static editor assistance for the root parser declaration without evaluating grammar code.
Constant Summary collapse
- SETTING_VALUES =
Frontend::ParserConfigurationSupport::PARSER_SETTING_VALUES
- SETTING_DOCUMENTATION =
{ "algorithm" => "`parser.algorithm` selects parser-table construction. Values: `slr`, `lalr`, `ielr`, `lr1`.", "entries" => "`parser.entries` selects shared or isolated construction for multiple start symbols. " \ "Values: `shared`, `isolated`.", "cst_trivia" => "`cst.trivia` selects CST trivia ownership. Values: `leading`, `balanced`, `drop`; " \ "requires `pragma cst`." }.freeze
- VALUE_DOCUMENTATION =
{ "slr" => "`slr` — SLR parser-table construction.", "lalr" => "`lalr` — LALR parser-table construction.", "ielr" => "`ielr` — IELR parser-table construction with canonical LR(1) verification support.", "lr1" => "`lr1` — canonical LR(1) parser-table construction.", "shared" => "`shared` — construct multiple entries in one shared automaton.", "isolated" => "`isolated` — construct each of multiple entries independently.", "leading" => "`leading` — attach leading trivia to the following CST node.", "balanced" => "`balanced` — attach trivia between the surrounding CST nodes.", "drop" => "`drop` — omit CST trivia; location and incremental APIs are unavailable." }.freeze
Instance Method Summary collapse
- #completion(position) ⇒ lsp_object
- #completion_item(label, kind, documentation) ⇒ lsp_object
- #completion_list(items) ⇒ lsp_object
- #hover(position) ⇒ lsp_object?
- #hovered_token(match, line, line_start, offset) ⇒ [ String?, Integer, Integer ]
-
#initialize(store, path) ⇒ ParserConfigurationAssistance
constructor
A new instance of ParserConfigurationAssistance.
- #line_start(source, offset) ⇒ Integer
- #parser_block_open?(source) ⇒ Boolean
- #setting_items ⇒ Array[lsp_object]
- #source! ⇒ String
- #value_items(setting) ⇒ Array[lsp_object]
Constructor Details
#initialize(store, path) ⇒ ParserConfigurationAssistance
Returns a new instance of ParserConfigurationAssistance.
28 29 30 31 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 28 def initialize(store, path) @store = store @path = path end |
Instance Method Details
#completion(position) ⇒ lsp_object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 34 def completion(position) source = source! codec = PositionCodec.new(source) offset = codec.byte_offset(position) line_start = line_start(source, offset) return completion_list([]) unless parser_block_open?(source.byteslice(0, line_start) || "") prefix = source.byteslice(line_start, offset - line_start) || "" value_match = prefix.match(/\A\s*(algorithm|entries|cst_trivia)\s+([A-Za-z_]*)\z/) if value_match setting = value_match[1] || raise("parser setting capture is missing") return completion_list(value_items(setting)) end return completion_list(setting_items) if prefix.match?(/\A\s*[A-Za-z_]*\z/) completion_list([]) end |
#completion_item(label, kind, documentation) ⇒ lsp_object
125 126 127 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 125 def completion_item(label, kind, documentation) { "label" => label, "kind" => kind, "documentation" => { "kind" => "markdown", "value" => documentation } } end |
#completion_list(items) ⇒ lsp_object
130 131 132 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 130 def completion_list(items) { "isIncomplete" => false, "items" => items } end |
#hover(position) ⇒ lsp_object?
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 53 def hover(position) source = source! codec = PositionCodec.new(source) offset = codec.byte_offset(position) start = line_start(source, offset) return unless parser_block_open?(source.byteslice(0, start) || "") finish = source.index("\n", start) || source.bytesize line = source.byteslice(start, finish - start) || "" match = line.match( /\A\s*(algorithm|entries|cst_trivia)\s+(slr|lalr|ielr|lr1|shared|isolated|leading|balanced|drop)\s*(?:#.*)?\z/ ) return unless match token, token_start, token_end = hovered_token(match, line, start, offset) return unless token documentation = SETTING_DOCUMENTATION[token] || VALUE_DOCUMENTATION[token] { "contents" => { "kind" => "markdown", "value" => documentation }, "range" => { "start" => codec.position(token_start), "end" => codec.position(token_end) } } end |
#hovered_token(match, line, line_start, offset) ⇒ [ String?, Integer, Integer ]
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 135 def hovered_token(match, line, line_start, offset) [1, 2].each do |capture| token = match[capture] next unless token before = line[0...match.begin(capture)] || "" start = line_start + before.bytesize finish = start + token.bytesize return [token, start, finish] if offset.between?(start, finish - 1) end [nil, offset, offset] end |
#line_start(source, offset) ⇒ Integer
88 89 90 91 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 88 def line_start(source, offset) newline = offset.positive? ? source.rindex("\n", offset - 1) : nil newline ? newline + 1 : 0 end |
#parser_block_open?(source) ⇒ Boolean
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 94 def parser_block_open?(source) root = false open = false source.each_line do |line| content = line.sub(/#.*/, "").strip next if content.empty? root = true if content.match?(/\Aclass\b/) root = false if content.match?(/\Afragment\b/) open = true if root && content == "parser" open = false if open && content == "end" return false if content.match?(/\Arule\b/) end root && open end |
#setting_items ⇒ Array[lsp_object]
111 112 113 114 115 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 111 def setting_items SETTING_VALUES.keys.map do |name| completion_item(name, 10, SETTING_DOCUMENTATION.fetch(name)) end end |
#source! ⇒ String
80 81 82 83 84 85 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 80 def source! snapshot = @store.snapshot_for(@path) raise ArgumentError, "document is unavailable" unless snapshot snapshot.fetch(:source) end |
#value_items(setting) ⇒ Array[lsp_object]
118 119 120 121 122 |
# File 'lib/ibex/lsp/parser_configuration_assistance.rb', line 118 def value_items(setting) SETTING_VALUES.fetch(setting).map do |name| completion_item(name, 12, VALUE_DOCUMENTATION.fetch(name)) end end |