Class: Ibex::Frontend::SourceDocument
- Inherits:
-
Object
- Object
- Ibex::Frontend::SourceDocument
- Defined in:
- lib/ibex/frontend/source_document.rb
Overview
Lossless grammar source plus its semantic parse and lexical concrete syntax tree.
Instance Attribute Summary collapse
-
#ast ⇒ Object
readonly
: AST::Root | AST::Fragment | nil.
-
#cst ⇒ Object
readonly
: CST::Document.
-
#file ⇒ Object
readonly
: String.
-
#source ⇒ Object
readonly
: String.
-
#tokens ⇒ Object
readonly
: Array.
Instance Method Summary collapse
- #byte_offset_at(line, column) ⇒ Object
-
#initialize(source:, file:, tokens:, cst:, ast: nil) ⇒ SourceDocument
constructor
A new instance of SourceDocument.
- #position_at(byte_offset) ⇒ Object
- #render ⇒ Object
- #slice(span) ⇒ Object
- #span(start_byte, end_byte) ⇒ Object
- #token_for(segment) ⇒ Object
- #with_ast(ast) ⇒ Object
Constructor Details
#initialize(source:, file:, tokens:, cst:, ast: nil) ⇒ SourceDocument
Returns a new instance of SourceDocument.
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ibex/frontend/source_document.rb', line 106 def initialize(source:, file:, tokens:, cst:, ast: nil) @source = SourceEncoding.validated_utf8(source, file) @file = file.dup.freeze @tokens = tokens.dup.freeze @cst = cst @ast = ast @line_starts = build_line_starts.freeze #: Array[Integer] validate_render freeze end |
Instance Attribute Details
#ast ⇒ Object (readonly)
: AST::Root | AST::Fragment | nil
102 103 104 |
# File 'lib/ibex/frontend/source_document.rb', line 102 def ast @ast end |
#cst ⇒ Object (readonly)
: CST::Document
101 102 103 |
# File 'lib/ibex/frontend/source_document.rb', line 101 def cst @cst end |
#file ⇒ Object (readonly)
: String
99 100 101 |
# File 'lib/ibex/frontend/source_document.rb', line 99 def file @file end |
#source ⇒ Object (readonly)
: String
98 99 100 |
# File 'lib/ibex/frontend/source_document.rb', line 98 def source @source end |
#tokens ⇒ Object (readonly)
: Array
100 101 102 |
# File 'lib/ibex/frontend/source_document.rb', line 100 def tokens @tokens end |
Instance Method Details
#byte_offset_at(line, column) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/ibex/frontend/source_document.rb', line 141 def byte_offset_at(line, column) raise ArgumentError, "line and column must be positive" unless line.positive? && column.positive? line_start = @line_starts[line - 1] raise ArgumentError, "line is outside the source" unless line_start line_end = @line_starts[line] || source.bytesize line_text = source.byteslice(line_start, line_end - line_start) || "" line_text = line_text.delete_suffix("\n") character_count = column - 1 raise ArgumentError, "column is outside the source line" if character_count > line_text.length line_start + line_text.each_char.take(character_count).join.bytesize end |
#position_at(byte_offset) ⇒ Object
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/ibex/frontend/source_document.rb', line 129 def position_at(byte_offset) validate_byte_offset(byte_offset) prefix = source.byteslice(0, byte_offset) || "" raise ArgumentError, "byte offset must be on a UTF-8 character boundary" unless prefix.valid_encoding? line_index = (@line_starts.bsearch_index { |start| start > byte_offset } || @line_starts.length) - 1 line_start = @line_starts.fetch(line_index) line_prefix = source.byteslice(line_start, byte_offset - line_start) || "" SourcePosition.new(byte_offset: byte_offset, line: line_index + 1, column: line_prefix.length + 1) end |
#render ⇒ Object
118 119 120 |
# File 'lib/ibex/frontend/source_document.rb', line 118 def render cst.render end |
#slice(span) ⇒ Object
123 124 125 126 |
# File 'lib/ibex/frontend/source_document.rb', line 123 def slice(span) validate_span(span) source.byteslice(span.start_byte, span.length) || "" end |
#span(start_byte, end_byte) ⇒ Object
157 158 159 |
# File 'lib/ibex/frontend/source_document.rb', line 157 def span(start_byte, end_byte) SourceSpan.new(file: file, start: position_at(start_byte), finish: position_at(end_byte)) end |
#token_for(segment) ⇒ Object
162 163 164 165 |
# File 'lib/ibex/frontend/source_document.rb', line 162 def token_for(segment) index = segment.token_index index && tokens[index] end |
#with_ast(ast) ⇒ Object
168 169 170 |
# File 'lib/ibex/frontend/source_document.rb', line 168 def with_ast(ast) self.class.new(source: source, file: file, tokens: tokens, cst: cst, ast: ast) end |