Class: RBS::Parser
- Inherits:
-
Object
- Object
- RBS::Parser
- Defined in:
- lib/rbs/wasm/parser.rb,
lib/rbs/parser_aux.rb,
lib/rbs/parser/token.rb,
lib/rbs/parser/lex_result.rb,
ext/rbs_extension/main.c
Overview
WebAssembly-backed implementation of the parser primitives.
On CRuby these come from the C extension (ext/rbs_extension/main.c). JRuby loads this instead: it runs the parser inside WebAssembly, then rebuilds the AST with RBS::WASM::Deserializer. rbs/parser_aux.rb layers the public RBS::Parser API on top, exactly as it does for the C extension.
Defined Under Namespace
Constant Summary collapse
- KEYWORDS =
%w( bool bot class instance interface nil self singleton top void type unchecked in out end def include extend prepend alias module attr_reader attr_writer attr_accessor public private untyped true false ).each_with_object({}) do |keyword, hash| #$ Hash[String, bot] hash[keyword] = _ = nil end
Class Method Summary collapse
- ._lex(buffer, end_pos) ⇒ Object
- ._parse_inline_leading_annotation(buffer, start_pos, end_pos, variables) ⇒ Object
- ._parse_inline_trailing_annotation(buffer, start_pos, end_pos, variables) ⇒ Object
- ._parse_method_type(buffer, start_pos, end_pos, variables, require_eof) ⇒ Object
- ._parse_method_type_to_bytes(buffer, start_pos, end_pos, variables, require_eof) ⇒ Object
- ._parse_signature(buffer, start_pos, end_pos) ⇒ Object
- ._parse_signature_to_bytes(buffer, start_pos, end_pos) ⇒ Object
- ._parse_type(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed) ⇒ Object
- ._parse_type_params(buffer, start_pos, end_pos, module_type_params) ⇒ Object
- ._parse_type_to_bytes(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed) ⇒ Object
- .buffer(source) ⇒ Object
- .byte_range(char_range, content) ⇒ Object
- .lex(source) ⇒ Object
- .magic_comment(buf) ⇒ Object
- .parse_inline_leading_annotation(source, range, variables: []) ⇒ Object
- .parse_inline_trailing_annotation(source, range, variables: []) ⇒ Object
- .parse_method_type(source, range: nil, byte_range: 0, variables: [], require_eof: false) ⇒ Object
- .parse_signature(source) ⇒ Object
- .parse_type(source, range: nil, byte_range: 0, variables: [], require_eof: false, void_allowed: true, self_allowed: true, classish_allowed: true) ⇒ Object
- .parse_type_params(source, module_type_params: true) ⇒ Object
Class Method Details
._lex(buffer, end_pos) ⇒ Object
555 556 557 558 559 560 |
# File 'ext/rbs_extension/main.c', line 555 def _lex(buffer, end_pos) encoding = buffer.content.encoding.name _success, bytes = WASM::Runtime.instance.lex(buffer.content, encoding, end_pos) WASM::Deserializer.deserialize_tokens(bytes, buffer) end |
._parse_inline_leading_annotation(buffer, start_pos, end_pos, variables) ⇒ Object
491 492 493 494 495 496 497 498 499 |
# File 'ext/rbs_extension/main.c', line 491 def _parse_inline_leading_annotation(buffer, start_pos, end_pos, variables) validate_position_range(start_pos, end_pos) validate_variables(variables) encoding = buffer.content.encoding.name success, bytes = WASM::Runtime.instance.parse_inline_leading_annotation(buffer.content, encoding, start_pos, end_pos, variables) raise_parsing_error(buffer, bytes) unless success deserialize_or_nil(bytes, buffer) end |
._parse_inline_trailing_annotation(buffer, start_pos, end_pos, variables) ⇒ Object
534 535 536 537 538 539 540 541 542 |
# File 'ext/rbs_extension/main.c', line 534 def _parse_inline_trailing_annotation(buffer, start_pos, end_pos, variables) validate_position_range(start_pos, end_pos) validate_variables(variables) encoding = buffer.content.encoding.name success, bytes = WASM::Runtime.instance.parse_inline_trailing_annotation(buffer.content, encoding, start_pos, end_pos, variables) raise_parsing_error(buffer, bytes) unless success deserialize_or_nil(bytes, buffer) end |
._parse_method_type(buffer, start_pos, end_pos, variables, require_eof) ⇒ Object
235 236 237 238 239 240 241 242 243 |
# File 'ext/rbs_extension/main.c', line 235 def _parse_method_type(buffer, start_pos, end_pos, variables, require_eof) validate_position_range(start_pos, end_pos) validate_variables(variables) encoding = buffer.content.encoding.name success, bytes = WASM::Runtime.instance.parse_method_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof) raise_parsing_error(buffer, bytes) unless success deserialize_or_nil(bytes, buffer) end |
._parse_method_type_to_bytes(buffer, start_pos, end_pos, variables, require_eof) ⇒ Object
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
# File 'ext/rbs_extension/main.c', line 367
static VALUE rbsparser_parse_method_type_to_bytes(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof) {
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
StringValue(string);
rb_encoding *encoding = rb_enc_get(string);
rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
declare_type_variables(parser, variables, buffer);
struct parse_method_type_arg arg = {
.buffer = buffer,
.encoding = encoding,
.parser = parser,
.require_eof = require_eof
};
VALUE result = rb_ensure(parse_method_type_to_bytes_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
RB_GC_GUARD(string);
return result;
}
|
._parse_signature(buffer, start_pos, end_pos) ⇒ Object
274 275 276 277 278 279 280 281 |
# File 'ext/rbs_extension/main.c', line 274 def _parse_signature(buffer, start_pos, end_pos) validate_position_range(start_pos, end_pos) encoding = buffer.content.encoding.name success, bytes = WASM::Runtime.instance.parse_signature(buffer.content, encoding, start_pos, end_pos) raise_parsing_error(buffer, bytes) unless success WASM::Deserializer.deserialize(bytes, buffer) end |
._parse_signature_to_bytes(buffer, start_pos, end_pos) ⇒ Object
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'ext/rbs_extension/main.c', line 400
static VALUE rbsparser_parse_signature_to_bytes(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos) {
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
StringValue(string);
rb_encoding *encoding = rb_enc_get(string);
rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
struct parse_signature_arg arg = {
.buffer = buffer,
.encoding = encoding,
.parser = parser,
.require_eof = false
};
VALUE result = rb_ensure(parse_signature_to_bytes_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
RB_GC_GUARD(string);
return result;
}
|
._parse_type(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed) ⇒ Object
189 190 191 192 193 194 195 196 197 |
# File 'ext/rbs_extension/main.c', line 189 def _parse_type(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed) validate_position_range(start_pos, end_pos) validate_variables(variables) encoding = buffer.content.encoding.name success, bytes = WASM::Runtime.instance.parse_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed) raise_parsing_error(buffer, bytes) unless success deserialize_or_nil(bytes, buffer) end |
._parse_type_params(buffer, start_pos, end_pos, module_type_params) ⇒ Object
449 450 451 452 453 454 455 456 |
# File 'ext/rbs_extension/main.c', line 449 def _parse_type_params(buffer, start_pos, end_pos, module_type_params) validate_position_range(start_pos, end_pos) encoding = buffer.content.encoding.name success, bytes = WASM::Runtime.instance.parse_type_params(buffer.content, encoding, start_pos, end_pos, module_type_params) raise_parsing_error(buffer, bytes) unless success bytes.empty? ? nil : WASM::Deserializer.deserialize_node_list(bytes, buffer) end |
._parse_type_to_bytes(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed) ⇒ Object
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'ext/rbs_extension/main.c', line 327
static VALUE rbsparser_parse_type_to_bytes(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof, VALUE void_allowed, VALUE self_allowed, VALUE classish_allowed) {
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
StringValue(string);
rb_encoding *encoding = rb_enc_get(string);
rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
declare_type_variables(parser, variables, buffer);
struct parse_type_arg arg = {
.buffer = buffer,
.encoding = encoding,
.parser = parser,
.require_eof = require_eof,
.void_allowed = void_allowed,
.self_allowed = self_allowed,
.classish_allowed = classish_allowed
};
VALUE result = rb_ensure(parse_type_to_bytes_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
RB_GC_GUARD(string);
return result;
}
|
.buffer(source) ⇒ Object
79 80 81 82 83 84 85 86 |
# File 'lib/rbs/parser_aux.rb', line 79 def self.buffer(source) case source when String Buffer.new(content: source, name: Pathname("a.rbs")) when Buffer source end end |
.byte_range(char_range, content) ⇒ Object
132 133 134 135 136 137 138 139 140 |
# File 'lib/rbs/parser_aux.rb', line 132 def self.byte_range(char_range, content) start_offset = char_range.begin end_offset = char_range.end start_prefix = content[0, start_offset] or raise if start_offset end_prefix = content[0, end_offset] or raise if end_offset start_prefix&.bytesize...end_prefix&.bytesize end |
.lex(source) ⇒ Object
70 71 72 73 74 75 76 77 |
# File 'lib/rbs/parser_aux.rb', line 70 def self.lex(source) buf = buffer(source) list = _lex(buf, buf.content.bytesize) value = list.map do |type, location| Token.new(type: type, location: location) end LexResult.new(buffer: buf, value: value) end |
.magic_comment(buf) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/rbs/parser_aux.rb', line 46 def self.magic_comment(buf) start_pos = 0 while true case when match = /\A#\s*(?<keyword>resolve-type-names)\s*(?<colon>:)\s+(?<value>true|false)$/.match(buf.content, start_pos) value = match[:value] or raise kw_offset = match.offset(:keyword) #: [Integer, Integer] colon_offset = match.offset(:colon) #: [Integer, Integer] value_offset = match.offset(:value) #: [Integer, Integer] location = Location.new(buf, kw_offset[0], value_offset[1]) location.add_required_child(:keyword, kw_offset[0]...kw_offset[1]) location.add_required_child(:colon, colon_offset[0]...colon_offset[1]) location.add_required_child(:value, value_offset[0]...value_offset[1]) return AST::Directives::ResolveTypeNames.new(value: value == "true", location: location) else return end end end |
.parse_inline_leading_annotation(source, range, variables: []) ⇒ Object
122 123 124 125 |
# File 'lib/rbs/parser_aux.rb', line 122 def self.parse_inline_leading_annotation(source, range, variables: []) buf = buffer(source) _parse_inline_leading_annotation(buf, range.begin || 0, range.end || buf.last_position, variables) end |
.parse_inline_trailing_annotation(source, range, variables: []) ⇒ Object
127 128 129 130 |
# File 'lib/rbs/parser_aux.rb', line 127 def self.parse_inline_trailing_annotation(source, range, variables: []) buf = buffer(source) _parse_inline_trailing_annotation(buf, range.begin || 0, range.end || buf.last_position, variables) end |
.parse_method_type(source, range: nil, byte_range: 0, variables: [], require_eof: false) ⇒ Object
14 15 16 17 18 |
# File 'lib/rbs/parser_aux.rb', line 14 def self.parse_method_type(source, range: nil, byte_range: 0..., variables: [], require_eof: false) buf = buffer(source) byte_range = byte_range(range, buf.content) if range _parse_method_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof) end |
.parse_signature(source) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/rbs/parser_aux.rb', line 20 def self.parse_signature(source) buf = buffer(source) resolved = magic_comment(buf) start_pos = if resolved (resolved.location || raise).end_pos else 0 end content = buf.content dirs, decls = _parse_signature(buf, start_pos, content.bytesize) if resolved dirs = dirs.dup if dirs.frozen? dirs.unshift(resolved) end [buf, dirs, decls] end |
.parse_type(source, range: nil, byte_range: 0, variables: [], require_eof: false, void_allowed: true, self_allowed: true, classish_allowed: true) ⇒ Object
8 9 10 11 12 |
# File 'lib/rbs/parser_aux.rb', line 8 def self.parse_type(source, range: nil, byte_range: 0..., variables: [], require_eof: false, void_allowed: true, self_allowed: true, classish_allowed: true) buf = buffer(source) byte_range = byte_range(range, buf.content) if range _parse_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof, void_allowed, self_allowed, classish_allowed) end |
.parse_type_params(source, module_type_params: true) ⇒ Object
41 42 43 44 |
# File 'lib/rbs/parser_aux.rb', line 41 def self.parse_type_params(source, module_type_params: true) buf = buffer(source) _parse_type_params(buf, 0, buf.content.bytesize, module_type_params) end |