rbs 3.9.2 → 4.0.0.dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.github/workflows/windows.yml +1 -1
  4. data/CHANGELOG.md +0 -13
  5. data/Rakefile +28 -21
  6. data/Steepfile +1 -0
  7. data/config.yml +232 -62
  8. data/ext/rbs_extension/ast_translation.c +1149 -0
  9. data/ext/rbs_extension/ast_translation.h +30 -0
  10. data/{src/constants.c → ext/rbs_extension/class_constants.c} +15 -1
  11. data/{include/rbs/constants.h → ext/rbs_extension/class_constants.h} +10 -1
  12. data/ext/rbs_extension/extconf.rb +3 -1
  13. data/ext/rbs_extension/{location.c → legacy_location.c} +25 -34
  14. data/ext/rbs_extension/legacy_location.h +40 -0
  15. data/ext/rbs_extension/main.c +402 -8
  16. data/ext/rbs_extension/rbs_extension.h +3 -21
  17. data/ext/rbs_extension/rbs_string_bridging.c +9 -0
  18. data/ext/rbs_extension/rbs_string_bridging.h +20 -0
  19. data/include/rbs/ast.h +748 -0
  20. data/include/rbs/defines.h +60 -0
  21. data/{ext/rbs_extension → include/rbs}/lexer.h +40 -32
  22. data/include/rbs/location.h +59 -0
  23. data/include/rbs/parser.h +151 -0
  24. data/include/rbs/string.h +49 -0
  25. data/include/rbs/util/rbs_allocator.h +38 -0
  26. data/include/rbs/util/rbs_assert.h +9 -0
  27. data/include/rbs/util/rbs_buffer.h +83 -0
  28. data/include/rbs/util/rbs_constant_pool.h +3 -64
  29. data/include/rbs/util/rbs_encoding.h +280 -0
  30. data/include/rbs/util/rbs_unescape.h +23 -0
  31. data/include/rbs.h +1 -2
  32. data/lib/rbs/annotate/formatter.rb +3 -13
  33. data/lib/rbs/annotate/rdoc_annotator.rb +3 -1
  34. data/lib/rbs/annotate/rdoc_source.rb +1 -1
  35. data/lib/rbs/ast/ruby/annotations.rb +119 -0
  36. data/lib/rbs/ast/ruby/comment_block.rb +221 -0
  37. data/lib/rbs/ast/ruby/declarations.rb +86 -0
  38. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +24 -0
  39. data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
  40. data/lib/rbs/ast/ruby/members.rb +213 -0
  41. data/lib/rbs/buffer.rb +104 -24
  42. data/lib/rbs/cli/validate.rb +39 -34
  43. data/lib/rbs/cli.rb +4 -5
  44. data/lib/rbs/definition.rb +6 -1
  45. data/lib/rbs/definition_builder/ancestor_builder.rb +63 -60
  46. data/lib/rbs/definition_builder/method_builder.rb +45 -30
  47. data/lib/rbs/definition_builder.rb +44 -9
  48. data/lib/rbs/environment/class_entry.rb +69 -0
  49. data/lib/rbs/environment/module_entry.rb +66 -0
  50. data/lib/rbs/environment.rb +185 -154
  51. data/lib/rbs/environment_loader.rb +2 -2
  52. data/lib/rbs/errors.rb +4 -3
  53. data/lib/rbs/inline_parser/comment_association.rb +117 -0
  54. data/lib/rbs/inline_parser.rb +206 -0
  55. data/lib/rbs/location_aux.rb +35 -3
  56. data/lib/rbs/parser_aux.rb +11 -1
  57. data/lib/rbs/prototype/runtime.rb +2 -2
  58. data/lib/rbs/source.rb +99 -0
  59. data/lib/rbs/subtractor.rb +4 -3
  60. data/lib/rbs/version.rb +1 -1
  61. data/lib/rbs.rb +12 -0
  62. data/lib/rdoc/discover.rb +1 -1
  63. data/lib/rdoc_plugin/parser.rb +2 -2
  64. data/rbs.gemspec +1 -0
  65. data/sig/ancestor_builder.rbs +1 -1
  66. data/sig/annotate/formatter.rbs +2 -2
  67. data/sig/annotate/rdoc_annotater.rbs +1 -1
  68. data/sig/ast/ruby/annotations.rbs +110 -0
  69. data/sig/ast/ruby/comment_block.rbs +119 -0
  70. data/sig/ast/ruby/declarations.rbs +60 -0
  71. data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
  72. data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
  73. data/sig/ast/ruby/members.rbs +72 -0
  74. data/sig/buffer.rbs +63 -5
  75. data/sig/definition.rbs +1 -0
  76. data/sig/definition_builder.rbs +1 -1
  77. data/sig/environment/class_entry.rbs +50 -0
  78. data/sig/environment/module_entry.rbs +50 -0
  79. data/sig/environment.rbs +22 -76
  80. data/sig/errors.rbs +13 -6
  81. data/sig/inline_parser/comment_association.rbs +71 -0
  82. data/sig/inline_parser.rbs +87 -0
  83. data/sig/location.rbs +32 -7
  84. data/sig/method_builder.rbs +7 -4
  85. data/sig/parser.rbs +16 -0
  86. data/sig/source.rbs +48 -0
  87. data/src/ast.c +1345 -0
  88. data/src/lexer.c +2867 -0
  89. data/src/lexer.re +151 -0
  90. data/{ext/rbs_extension → src}/lexstate.c +58 -42
  91. data/src/location.c +71 -0
  92. data/src/parser.c +3739 -0
  93. data/src/string.c +89 -0
  94. data/src/util/rbs_allocator.c +149 -0
  95. data/src/util/rbs_assert.c +19 -0
  96. data/src/util/rbs_buffer.c +54 -0
  97. data/src/util/rbs_constant_pool.c +13 -81
  98. data/src/util/rbs_encoding.c +5273 -0
  99. data/src/util/rbs_unescape.c +130 -0
  100. data/stdlib/rdoc/0/code_object.rbs +2 -2
  101. data/stdlib/rdoc/0/comment.rbs +2 -0
  102. data/stdlib/rdoc/0/options.rbs +76 -0
  103. data/stdlib/rdoc/0/rdoc.rbs +6 -4
  104. data/stdlib/rdoc/0/store.rbs +1 -1
  105. metadata +70 -17
  106. data/ext/rbs_extension/lexer.c +0 -2728
  107. data/ext/rbs_extension/lexer.re +0 -147
  108. data/ext/rbs_extension/location.h +0 -85
  109. data/ext/rbs_extension/parser.c +0 -2982
  110. data/ext/rbs_extension/parser.h +0 -18
  111. data/ext/rbs_extension/parserstate.c +0 -411
  112. data/ext/rbs_extension/parserstate.h +0 -163
  113. data/ext/rbs_extension/unescape.c +0 -32
  114. data/include/rbs/ruby_objs.h +0 -72
  115. data/src/ruby_objs.c +0 -799
data/src/lexer.re ADDED
@@ -0,0 +1,151 @@
1
+ #include "rbs/lexer.h"
2
+
3
+ rbs_token_t rbs_lexer_next_token(rbs_lexer_t *lexer) {
4
+ rbs_lexer_t backup;
5
+
6
+ backup = *lexer;
7
+
8
+ /*!re2c
9
+ re2c:flags:u = 1;
10
+ re2c:api:style = free-form;
11
+ re2c:flags:input = custom;
12
+ re2c:define:YYCTYPE = "unsigned int";
13
+ re2c:define:YYPEEK = "rbs_peek(lexer)";
14
+ re2c:define:YYSKIP = "rbs_skip(lexer);";
15
+ re2c:define:YYBACKUP = "backup = *lexer;";
16
+ re2c:define:YYRESTORE = "*lexer = backup;";
17
+ re2c:yyfill:enable = 0;
18
+
19
+ word = [a-zA-Z0-9_];
20
+
21
+ operator = "/" | "~" | "[]=" | "!" | "!=" | "!~" | "-" | "-@" | "+" | "+@"
22
+ | "==" | "===" | "=~" | "<<" | "<=" | "<=>" | ">" | ">=" | ">>" | "%";
23
+
24
+ "(" { return rbs_next_token(lexer, pLPAREN); }
25
+ ")" { return rbs_next_token(lexer, pRPAREN); }
26
+ "[" { return rbs_next_token(lexer, pLBRACKET); }
27
+ "]" { return rbs_next_token(lexer, pRBRACKET); }
28
+ "{" { return rbs_next_token(lexer, pLBRACE); }
29
+ "}" { return rbs_next_token(lexer, pRBRACE); }
30
+ "," { return rbs_next_token(lexer, pCOMMA); }
31
+ "|" { return rbs_next_token(lexer, pBAR); }
32
+ "^" { return rbs_next_token(lexer, pHAT); }
33
+ "&" { return rbs_next_token(lexer, pAMP); }
34
+ "?" { return rbs_next_token(lexer, pQUESTION); }
35
+ "*" { return rbs_next_token(lexer, pSTAR); }
36
+ "**" { return rbs_next_token(lexer, pSTAR2); }
37
+ "." { return rbs_next_token(lexer, pDOT); }
38
+ "..." { return rbs_next_token(lexer, pDOT3); }
39
+ "`" { return rbs_next_token(lexer, tOPERATOR); }
40
+ "`" [^ :\x00] [^`\x00]* "`" { return rbs_next_token(lexer, tQIDENT); }
41
+ "->" { return rbs_next_token(lexer, pARROW); }
42
+ "=>" { return rbs_next_token(lexer, pFATARROW); }
43
+ "=" { return rbs_next_token(lexer, pEQ); }
44
+ ":" { return rbs_next_token(lexer, pCOLON); }
45
+ "::" { return rbs_next_token(lexer, pCOLON2); }
46
+ "<" { return rbs_next_token(lexer, pLT); }
47
+ "[]" { return rbs_next_token(lexer, pAREF_OPR); }
48
+ operator { return rbs_next_token(lexer, tOPERATOR); }
49
+ "--" [^\x00]* { return rbs_next_token(lexer, tINLINECOMMENT); }
50
+
51
+ number = [0-9] [0-9_]*;
52
+ ("-"|"+")? number { return rbs_next_token(lexer, tINTEGER); }
53
+
54
+ "%a{" [^}\x00]* "}" { return rbs_next_token(lexer, tANNOTATION); }
55
+ "%a(" [^)\x00]* ")" { return rbs_next_token(lexer, tANNOTATION); }
56
+ "%a[" [^\]\x00]* "]" { return rbs_next_token(lexer, tANNOTATION); }
57
+ "%a|" [^|\x00]* "|" { return rbs_next_token(lexer, tANNOTATION); }
58
+ "%a<" [^>\x00]* ">" { return rbs_next_token(lexer, tANNOTATION); }
59
+
60
+ "#" (. \ [\x00])* {
61
+ return rbs_next_token(
62
+ lexer,
63
+ lexer->first_token_of_line ? tLINECOMMENT : tCOMMENT
64
+ );
65
+ }
66
+
67
+ "alias" { return rbs_next_token(lexer, kALIAS); }
68
+ "attr_accessor" { return rbs_next_token(lexer, kATTRACCESSOR); }
69
+ "attr_reader" { return rbs_next_token(lexer, kATTRREADER); }
70
+ "attr_writer" { return rbs_next_token(lexer, kATTRWRITER); }
71
+ "bool" { return rbs_next_token(lexer, kBOOL); }
72
+ "bot" { return rbs_next_token(lexer, kBOT); }
73
+ "class" { return rbs_next_token(lexer, kCLASS); }
74
+ "def" { return rbs_next_token(lexer, kDEF); }
75
+ "end" { return rbs_next_token(lexer, kEND); }
76
+ "extend" { return rbs_next_token(lexer, kEXTEND); }
77
+ "false" { return rbs_next_token(lexer, kFALSE); }
78
+ "in" { return rbs_next_token(lexer, kIN); }
79
+ "include" { return rbs_next_token(lexer, kINCLUDE); }
80
+ "instance" { return rbs_next_token(lexer, kINSTANCE); }
81
+ "interface" { return rbs_next_token(lexer, kINTERFACE); }
82
+ "module" { return rbs_next_token(lexer, kMODULE); }
83
+ "nil" { return rbs_next_token(lexer, kNIL); }
84
+ "out" { return rbs_next_token(lexer, kOUT); }
85
+ "prepend" { return rbs_next_token(lexer, kPREPEND); }
86
+ "private" { return rbs_next_token(lexer, kPRIVATE); }
87
+ "public" { return rbs_next_token(lexer, kPUBLIC); }
88
+ "self" { return rbs_next_token(lexer, kSELF); }
89
+ "singleton" { return rbs_next_token(lexer, kSINGLETON); }
90
+ "top" { return rbs_next_token(lexer, kTOP); }
91
+ "true" { return rbs_next_token(lexer, kTRUE); }
92
+ "type" { return rbs_next_token(lexer, kTYPE); }
93
+ "unchecked" { return rbs_next_token(lexer, kUNCHECKED); }
94
+ "untyped" { return rbs_next_token(lexer, kUNTYPED); }
95
+ "void" { return rbs_next_token(lexer, kVOID); }
96
+ "use" { return rbs_next_token(lexer, kUSE); }
97
+ "as" { return rbs_next_token(lexer, kAS); }
98
+ "__todo__" { return rbs_next_token(lexer, k__TODO__); }
99
+ "@rbs" { return rbs_next_token(lexer, kATRBS); }
100
+ "skip" { return rbs_next_token(lexer, kSKIP); }
101
+ "return" { return rbs_next_token(lexer, kRETURN); }
102
+
103
+ unicode_char = "\\u" [0-9a-fA-F]{4};
104
+ oct_char = "\\x" [0-9a-f]{1,2};
105
+ hex_char = "\\" [0-7]{1,3};
106
+
107
+ dqstring = ["] (unicode_char | oct_char | hex_char | "\\" [^xu] | [^\\"\x00])* ["];
108
+ sqstring = ['] ("\\"['\\] | [^'\x00])* ['];
109
+
110
+ dqstring { return rbs_next_token(lexer, tDQSTRING); }
111
+ sqstring { return rbs_next_token(lexer, tSQSTRING); }
112
+ ":" dqstring { return rbs_next_token(lexer, tDQSYMBOL); }
113
+ ":" sqstring { return rbs_next_token(lexer, tSQSYMBOL); }
114
+
115
+ identifier = [a-zA-Z_] word* [!?=]?;
116
+ symbol_opr = ":|" | ":&" | ":/" | ":%" | ":~" | ":`" | ":^"
117
+ | ":==" | ":=~" | ":===" | ":!" | ":!=" | ":!~"
118
+ | ":<" | ":<=" | ":<<" | ":<=>" | ":>" | ":>=" | ":>>"
119
+ | ":-" | ":-@" | ":+" | ":+@" | ":*" | ":**" | ":[]" | ":[]=";
120
+
121
+ global_ident = [0-9]+
122
+ | "-" [a-zA-Z0-9_]
123
+ | [~*$?!@\\/;,.=:<>"&'`+]
124
+ | [^ \t\r\n:;=.,!"$%&()-+~|\\'[\]{}*/<>^\x00]+;
125
+
126
+ ":" identifier { return rbs_next_token(lexer, tSYMBOL); }
127
+ ":@" identifier { return rbs_next_token(lexer, tSYMBOL); }
128
+ ":@@" identifier { return rbs_next_token(lexer, tSYMBOL); }
129
+ ":$" global_ident { return rbs_next_token(lexer, tSYMBOL); }
130
+ symbol_opr { return rbs_next_token(lexer, tSYMBOL); }
131
+
132
+ [a-z] word* { return rbs_next_token(lexer, tLIDENT); }
133
+ [A-Z] word* { return rbs_next_token(lexer, tUIDENT); }
134
+ "_" [a-z0-9_] word* { return rbs_next_token(lexer, tULLIDENT); }
135
+ "_" [A-Z] word* { return rbs_next_token(lexer, tULIDENT); }
136
+ "_" { return rbs_next_token(lexer, tULLIDENT); }
137
+ [a-zA-Z_] word* "!" { return rbs_next_token(lexer, tBANGIDENT); }
138
+ [a-zA-Z_] word* "=" { return rbs_next_token(lexer, tEQIDENT); }
139
+
140
+ "@" [a-zA-Z_] word* { return rbs_next_token(lexer, tAIDENT); }
141
+ "@@" [a-zA-Z_] word* { return rbs_next_token(lexer, tA2IDENT); }
142
+
143
+ "$" global_ident { return rbs_next_token(lexer, tGIDENT); }
144
+
145
+ skip = ([ \t]+|[\r\n]);
146
+
147
+ skip { return rbs_next_token(lexer, tTRIVIA); }
148
+ "\x00" { return rbs_next_eof_token(lexer); }
149
+ * { return rbs_next_token(lexer, ErrorToken); }
150
+ */
151
+ }
@@ -1,4 +1,4 @@
1
- #include "rbs_extension.h"
1
+ #include "rbs/lexer.h"
2
2
 
3
3
  static const char *RBS_TOKENTYPE_NAMES[] = {
4
4
  "NullType",
@@ -60,6 +60,9 @@ static const char *RBS_TOKENTYPE_NAMES[] = {
60
60
  "kUSE", /* use */
61
61
  "kAS", /* as */
62
62
  "k__TODO__", /* __todo__ */
63
+ "kATRBS", /* @rbs */
64
+ "kSKIP", /* skip */
65
+ "kRETURN", /* return */
63
66
 
64
67
  "tLIDENT", /* Identifiers starting with lower case */
65
68
  "tUIDENT", /* Identifiers starting with upper case */
@@ -76,6 +79,7 @@ static const char *RBS_TOKENTYPE_NAMES[] = {
76
79
 
77
80
  "tCOMMENT",
78
81
  "tLINECOMMENT",
82
+ "tINLINECOMMENT",
79
83
 
80
84
  "tTRIVIA",
81
85
 
@@ -88,88 +92,100 @@ static const char *RBS_TOKENTYPE_NAMES[] = {
88
92
  "tANNOTATION", /* Annotation */
89
93
  };
90
94
 
91
- token NullToken = { NullType };
92
- position NullPosition = { -1, -1, -1, -1 };
93
- range NULL_RANGE = { { -1, -1, -1, -1 }, { -1, -1, -1, -1 } };
95
+ rbs_token_t NullToken = { .type = NullType, .range = {} };
96
+ rbs_position_t NullPosition = { -1, -1, -1, -1 };
97
+ rbs_range_t NULL_RANGE = { { -1, -1, -1, -1 }, { -1, -1, -1, -1 } };
94
98
 
95
- const char *token_type_str(enum TokenType type) {
99
+ const char *rbs_token_type_str(enum RBSTokenType type) {
96
100
  return RBS_TOKENTYPE_NAMES[type];
97
101
  }
98
102
 
99
- int token_chars(token tok) {
103
+ int rbs_token_chars(rbs_token_t tok) {
100
104
  return tok.range.end.char_pos - tok.range.start.char_pos;
101
105
  }
102
106
 
103
- int token_bytes(token tok) {
104
- return RANGE_BYTES(tok.range);
107
+ int rbs_token_bytes(rbs_token_t tok) {
108
+ return RBS_RANGE_BYTES(tok.range);
105
109
  }
106
110
 
107
- unsigned int peek(lexstate *state) {
108
- if (state->current.char_pos == state->end_pos) {
109
- state->last_char = '\0';
111
+ unsigned int rbs_peek(rbs_lexer_t *lexer) {
112
+ if (lexer->current.char_pos == lexer->end_pos) {
113
+ lexer->last_char = '\0';
110
114
  return 0;
111
115
  } else {
112
- unsigned int c = rb_enc_mbc_to_codepoint(RSTRING_PTR(state->string) + state->current.byte_pos, RSTRING_END(state->string), rb_enc_get(state->string));
113
- state->last_char = c;
116
+ rbs_string_t str = rbs_string_new(
117
+ lexer->string.start + lexer->current.byte_pos,
118
+ lexer->string.end
119
+ );
120
+ unsigned int c = rbs_utf8_string_to_codepoint(str);
121
+ lexer->last_char = c;
114
122
  return c;
115
123
  }
116
124
  }
117
125
 
118
- token next_token(lexstate *state, enum TokenType type) {
119
- token t;
126
+ rbs_token_t rbs_next_token(rbs_lexer_t *lexer, enum RBSTokenType type) {
127
+ rbs_token_t t;
120
128
 
121
129
  t.type = type;
122
- t.range.start = state->start;
123
- t.range.end = state->current;
124
- state->start = state->current;
130
+ t.range.start = lexer->start;
131
+ t.range.end = lexer->current;
132
+ lexer->start = lexer->current;
125
133
  if (type != tTRIVIA) {
126
- state->first_token_of_line = false;
134
+ lexer->first_token_of_line = false;
127
135
  }
128
136
 
129
137
  return t;
130
138
  }
131
139
 
132
- token next_eof_token(lexstate *state) {
133
- if (state->current.byte_pos == RSTRING_LEN(state->string)+1) {
140
+ rbs_token_t rbs_next_eof_token(rbs_lexer_t *lexer) {
141
+ if ((size_t) lexer->current.byte_pos == rbs_string_len(lexer->string) + 1) {
134
142
  // End of String
135
- token t;
143
+ rbs_token_t t;
136
144
  t.type = pEOF;
137
- t.range.start = state->start;
138
- t.range.end = state->start;
139
- state->start = state->current;
145
+ t.range.start = lexer->start;
146
+ t.range.end = lexer->start;
147
+ lexer->start = lexer->current;
140
148
 
141
149
  return t;
142
150
  } else {
143
151
  // NULL byte in the middle of the string
144
- return next_token(state, pEOF);
152
+ return rbs_next_token(lexer, pEOF);
145
153
  }
146
154
  }
147
155
 
148
- void rbs_skip(lexstate *state) {
149
- if (!state->last_char) {
150
- peek(state);
156
+ void rbs_skip(rbs_lexer_t *lexer) {
157
+ if (!lexer->last_char) {
158
+ rbs_peek(lexer);
151
159
  }
152
- int byte_len = rb_enc_codelen(state->last_char, rb_enc_get(state->string));
153
160
 
154
- state->current.char_pos += 1;
155
- state->current.byte_pos += byte_len;
161
+ size_t byte_len;
156
162
 
157
- if (state->last_char == '\n') {
158
- state->current.line += 1;
159
- state->current.column = 0;
160
- state->first_token_of_line = true;
163
+ if (lexer->last_char == '\0') {
164
+ byte_len = 1;
161
165
  } else {
162
- state->current.column += 1;
166
+ const char *start = lexer->string.start + lexer->current.byte_pos;
167
+ byte_len = lexer->encoding->char_width((const uint8_t *) start, (ptrdiff_t) (lexer->string.end - start));
168
+ }
169
+
170
+ lexer->current.char_pos += 1;
171
+ lexer->current.byte_pos += byte_len;
172
+
173
+ if (lexer->last_char == '\n') {
174
+ lexer->current.line += 1;
175
+ lexer->current.column = 0;
176
+ lexer->first_token_of_line = true;
177
+ } else {
178
+ lexer->current.column += 1;
163
179
  }
164
180
  }
165
181
 
166
- void skipn(lexstate *state, size_t size) {
182
+ void rbs_skipn(rbs_lexer_t *lexer, size_t size) {
167
183
  for (size_t i = 0; i < size; i ++) {
168
- peek(state);
169
- rbs_skip(state);
184
+ rbs_peek(lexer);
185
+ rbs_skip(lexer);
170
186
  }
171
187
  }
172
188
 
173
- char *peek_token(lexstate *state, token tok) {
174
- return RSTRING_PTR(state->string) + tok.range.start.byte_pos;
189
+ char *rbs_peek_token(rbs_lexer_t *lexer, rbs_token_t tok) {
190
+ return (char *) lexer->string.start + tok.range.start.byte_pos;
175
191
  }
data/src/location.c ADDED
@@ -0,0 +1,71 @@
1
+ #include "rbs/location.h"
2
+ #include "rbs/util/rbs_assert.h"
3
+
4
+ #include <stdio.h>
5
+
6
+ #define RBS_LOC_CHILDREN_SIZE(cap) (sizeof(rbs_loc_children) + sizeof(rbs_loc_entry) * ((cap) - 1))
7
+
8
+ void rbs_loc_alloc_children(rbs_allocator_t *allocator, rbs_location_t *loc, size_t capacity) {
9
+ rbs_assert(capacity <= sizeof(rbs_loc_entry_bitmap) * 8, "Capacity %zu is too large. Max is %zu", capacity, sizeof(rbs_loc_entry_bitmap) * 8);
10
+
11
+ loc->children = rbs_allocator_malloc_impl(allocator, RBS_LOC_CHILDREN_SIZE(capacity), alignof(rbs_loc_children));
12
+
13
+ loc->children->len = 0;
14
+ loc->children->required_p = 0;
15
+ loc->children->cap = capacity;
16
+ }
17
+
18
+ void rbs_loc_add_optional_child(rbs_location_t *loc, rbs_constant_id_t name, rbs_range_t r) {
19
+ rbs_assert(loc->children != NULL, "All children should have been pre-allocated with rbs_loc_alloc_children()");
20
+ rbs_assert((loc->children->len + 1 <= loc->children->cap), "Not enough space was pre-allocated for the children. Children: %hu, Capacity: %hu", loc->children->len, loc->children->cap);
21
+
22
+ unsigned short i = loc->children->len++;
23
+ loc->children->entries[i].name = name;
24
+ loc->children->entries[i].rg = (rbs_loc_range) { r.start.char_pos, r.end.char_pos };
25
+ }
26
+
27
+ void rbs_loc_add_required_child(rbs_location_t *loc, rbs_constant_id_t name, rbs_range_t r) {
28
+ rbs_loc_add_optional_child(loc, name, r);
29
+ unsigned short last_index = loc->children->len - 1;
30
+ loc->children->required_p |= 1 << last_index;
31
+ }
32
+
33
+ rbs_location_t *rbs_location_new(rbs_allocator_t *allocator, rbs_range_t rg) {
34
+ rbs_location_t *location = rbs_allocator_alloc(allocator, rbs_location_t);
35
+ *location = (rbs_location_t) {
36
+ .rg = rg,
37
+ .children = NULL,
38
+ };
39
+
40
+ return location;
41
+ }
42
+
43
+ rbs_location_list_t *rbs_location_list_new(rbs_allocator_t *allocator) {
44
+ rbs_location_list_t *list = rbs_allocator_alloc(allocator, rbs_location_list_t);
45
+ *list = (rbs_location_list_t) {
46
+ .allocator = allocator,
47
+ .head = NULL,
48
+ .tail = NULL,
49
+ .length = 0,
50
+ };
51
+
52
+ return list;
53
+ }
54
+
55
+ void rbs_location_list_append(rbs_location_list_t *list, rbs_location_t *loc) {
56
+ rbs_location_list_node_t *node = rbs_allocator_alloc(list->allocator, rbs_location_list_node_t);
57
+ *node = (rbs_location_list_node_t) {
58
+ .loc = loc,
59
+ .next = NULL,
60
+ };
61
+
62
+ if (list->head == NULL) {
63
+ list->head = node;
64
+ list->tail = node;
65
+ } else {
66
+ list->tail->next = node;
67
+ list->tail = node;
68
+ }
69
+
70
+ list->length++;
71
+ }