Class: RBS::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/rbs/parser_aux.rb,
lib/rbs/parser/token.rb,
lib/rbs/parser/lex_result.rb,
ext/rbs_extension/main.c

Defined Under Namespace

Classes: LexResult, Token

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

Class Method Details

._lex(buffer, end_pos) ⇒ Object



423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'ext/rbs_extension/main.c', line 423

static VALUE rbsparser_lex(VALUE self, VALUE buffer, VALUE end_pos) {
    VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
    StringValue(string);
    rb_encoding *encoding = rb_enc_get(string);

    rbs_allocator_t *allocator = rbs_allocator_init();
    rbs_lexer_t *lexer = alloc_lexer_from_buffer(allocator, string, encoding, 0, FIX2INT(end_pos));

    VALUE results = rb_ary_new();
    rbs_token_t token = NullToken;
    while (token.type != pEOF) {
        token = rbs_lexer_next_token(lexer);
        VALUE type = ID2SYM(rb_intern(rbs_token_type_str(token.type)));
        VALUE location = rbs_new_location(buffer, token.range);
        VALUE pair = rb_ary_new3(2, type, location);
        rb_ary_push(results, pair);
    }

    rbs_allocator_free(allocator);
    RB_GC_GUARD(string);

    return results;
}

._parse_inline_leading_annotation(buffer, start_pos, end_pos, variables) ⇒ Object



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'ext/rbs_extension/main.c', line 359

static VALUE rbsparser_parse_inline_leading_annotation(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables) {
    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 = Qfalse
    };

    VALUE result = rb_ensure(parse_inline_leading_annotation_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);

    RB_GC_GUARD(string);

    return result;
}

._parse_inline_trailing_annotation(buffer, start_pos, end_pos, variables) ⇒ Object



402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'ext/rbs_extension/main.c', line 402

static VALUE rbsparser_parse_inline_trailing_annotation(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables) {
    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 = Qfalse
    };

    VALUE result = rb_ensure(parse_inline_trailing_annotation_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);

    RB_GC_GUARD(string);

    return result;
}

._parse_method_type(buffer, start_pos, end_pos, variables, require_eof) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'ext/rbs_extension/main.c', line 229

static VALUE rbsparser_parse_method_type(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_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);

    RB_GC_GUARD(string);

    return result;
}

._parse_signature(buffer, start_pos, end_pos) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'ext/rbs_extension/main.c', line 268

static VALUE rbsparser_parse_signature(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_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



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'ext/rbs_extension/main.c', line 183

static VALUE rbsparser_parse_type(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_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);

    RB_GC_GUARD(string);

    return result;
}

._parse_type_params(buffer, start_pos, end_pos, module_type_params) ⇒ Object



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'ext/rbs_extension/main.c', line 317

static VALUE rbsparser_parse_type_params(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE module_type_params) {
    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_type_params_arg arg = {
        .buffer = buffer,
        .encoding = encoding,
        .parser = parser,
        .module_type_params = module_type_params
    };

    VALUE result = rb_ensure(parse_type_params_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