herb 0.7.4-x86-linux-gnu → 0.7.5-x86-linux-gnu

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/config.yml +14 -14
  3. data/ext/herb/extension_helpers.c +9 -15
  4. data/ext/herb/extension_helpers.h +3 -3
  5. data/ext/herb/nodes.c +1 -1
  6. data/lib/herb/3.0/herb.so +0 -0
  7. data/lib/herb/3.1/herb.so +0 -0
  8. data/lib/herb/3.2/herb.so +0 -0
  9. data/lib/herb/3.3/herb.so +0 -0
  10. data/lib/herb/3.4/herb.so +0 -0
  11. data/lib/herb/engine.rb +10 -6
  12. data/lib/herb/version.rb +1 -1
  13. data/src/analyze.c +43 -80
  14. data/src/ast_node.c +10 -13
  15. data/src/ast_nodes.c +31 -33
  16. data/src/buffer.c +10 -1
  17. data/src/errors.c +35 -35
  18. data/src/include/ast_node.h +3 -3
  19. data/src/include/ast_nodes.h +32 -32
  20. data/src/include/errors.h +21 -21
  21. data/src/include/lexer_peek_helpers.h +8 -6
  22. data/src/include/lexer_struct.h +10 -9
  23. data/src/include/location.h +10 -13
  24. data/src/include/parser_helpers.h +1 -1
  25. data/src/include/position.h +3 -14
  26. data/src/include/pretty_print.h +1 -1
  27. data/src/include/prism_helpers.h +1 -1
  28. data/src/include/range.h +4 -13
  29. data/src/include/token.h +0 -3
  30. data/src/include/token_struct.h +2 -2
  31. data/src/include/version.h +1 -1
  32. data/src/lexer.c +3 -2
  33. data/src/lexer_peek_helpers.c +10 -4
  34. data/src/location.c +9 -37
  35. data/src/parser.c +98 -119
  36. data/src/parser_helpers.c +15 -15
  37. data/src/pretty_print.c +7 -12
  38. data/src/prism_helpers.c +7 -7
  39. data/src/range.c +2 -35
  40. data/src/token.c +25 -29
  41. data/templates/javascript/packages/core/src/visitor.ts.erb +29 -1
  42. data/templates/src/ast_nodes.c.erb +1 -3
  43. data/templates/src/errors.c.erb +5 -7
  44. data/templates/src/include/ast_nodes.h.erb +2 -2
  45. data/templates/src/include/errors.h.erb +3 -3
  46. metadata +2 -3
  47. data/src/position.c +0 -33
data/src/parser.c CHANGED
@@ -56,15 +56,14 @@ static AST_CDATA_NODE_T* parser_parse_cdata(parser_T* parser) {
56
56
  buffer_T content = buffer_new();
57
57
 
58
58
  token_T* tag_opening = parser_consume_expected(parser, TOKEN_CDATA_START, errors);
59
- position_T* start = position_copy(parser->current_token->location->start);
59
+ position_T start = parser->current_token->location.start;
60
60
 
61
61
  while (token_is_none_of(parser, TOKEN_CDATA_END, TOKEN_EOF)) {
62
62
  if (token_is(parser, TOKEN_ERB_START)) {
63
63
  parser_append_literal_node_from_buffer(parser, &content, children, start);
64
64
  AST_ERB_CONTENT_NODE_T* erb_node = parser_parse_erb_tag(parser);
65
65
  array_append(children, erb_node);
66
- position_free(start);
67
- start = position_copy(parser->current_token->location->start);
66
+ start = parser->current_token->location.start;
68
67
  continue;
69
68
  }
70
69
 
@@ -80,12 +79,11 @@ static AST_CDATA_NODE_T* parser_parse_cdata(parser_T* parser) {
80
79
  tag_opening,
81
80
  children,
82
81
  tag_closing,
83
- tag_opening->location->start,
84
- tag_closing->location->end,
82
+ tag_opening->location.start,
83
+ tag_closing->location.end,
85
84
  errors
86
85
  );
87
86
 
88
- position_free(start);
89
87
  buffer_free(&content);
90
88
  token_free(tag_opening);
91
89
  token_free(tag_closing);
@@ -97,7 +95,7 @@ static AST_HTML_COMMENT_NODE_T* parser_parse_html_comment(parser_T* parser) {
97
95
  array_T* errors = array_init(8);
98
96
  array_T* children = array_init(8);
99
97
  token_T* comment_start = parser_consume_expected(parser, TOKEN_HTML_COMMENT_START, errors);
100
- position_T* start = position_copy(parser->current_token->location->start);
98
+ position_T start = parser->current_token->location.start;
101
99
 
102
100
  buffer_T comment = buffer_new();
103
101
 
@@ -108,8 +106,7 @@ static AST_HTML_COMMENT_NODE_T* parser_parse_html_comment(parser_T* parser) {
108
106
  AST_ERB_CONTENT_NODE_T* erb_node = parser_parse_erb_tag(parser);
109
107
  array_append(children, erb_node);
110
108
 
111
- position_free(start);
112
- start = position_copy(parser->current_token->location->start);
109
+ start = parser->current_token->location.start;
113
110
 
114
111
  continue;
115
112
  }
@@ -127,13 +124,12 @@ static AST_HTML_COMMENT_NODE_T* parser_parse_html_comment(parser_T* parser) {
127
124
  comment_start,
128
125
  children,
129
126
  comment_end,
130
- comment_start->location->start,
131
- comment_end->location->end,
127
+ comment_start->location.start,
128
+ comment_end->location.end,
132
129
  errors
133
130
  );
134
131
 
135
132
  buffer_free(&comment);
136
- position_free(start);
137
133
  token_free(comment_start);
138
134
  token_free(comment_end);
139
135
 
@@ -147,7 +143,7 @@ static AST_HTML_DOCTYPE_NODE_T* parser_parse_html_doctype(parser_T* parser) {
147
143
 
148
144
  token_T* tag_opening = parser_consume_expected(parser, TOKEN_HTML_DOCTYPE, errors);
149
145
 
150
- position_T* start = position_copy(parser->current_token->location->start);
146
+ position_T start = parser->current_token->location.start;
151
147
 
152
148
  while (token_is_none_of(parser, TOKEN_HTML_TAG_END, TOKEN_EOF)) {
153
149
  if (token_is(parser, TOKEN_ERB_START)) {
@@ -172,12 +168,11 @@ static AST_HTML_DOCTYPE_NODE_T* parser_parse_html_doctype(parser_T* parser) {
172
168
  tag_opening,
173
169
  children,
174
170
  tag_closing,
175
- tag_opening->location->start,
176
- tag_closing->location->end,
171
+ tag_opening->location.start,
172
+ tag_closing->location.end,
177
173
  errors
178
174
  );
179
175
 
180
- position_free(start);
181
176
  token_free(tag_opening);
182
177
  token_free(tag_closing);
183
178
  buffer_free(&content);
@@ -192,7 +187,7 @@ static AST_XML_DECLARATION_NODE_T* parser_parse_xml_declaration(parser_T* parser
192
187
 
193
188
  token_T* tag_opening = parser_consume_expected(parser, TOKEN_XML_DECLARATION, errors);
194
189
 
195
- position_T* start = position_copy(parser->current_token->location->start);
190
+ position_T start = parser->current_token->location.start;
196
191
 
197
192
  while (token_is_none_of(parser, TOKEN_XML_DECLARATION_END, TOKEN_EOF)) {
198
193
  if (token_is(parser, TOKEN_ERB_START)) {
@@ -201,8 +196,7 @@ static AST_XML_DECLARATION_NODE_T* parser_parse_xml_declaration(parser_T* parser
201
196
  AST_ERB_CONTENT_NODE_T* erb_node = parser_parse_erb_tag(parser);
202
197
  array_append(children, erb_node);
203
198
 
204
- position_free(start);
205
- start = position_copy(parser->current_token->location->start);
199
+ start = parser->current_token->location.start;
206
200
 
207
201
  continue;
208
202
  }
@@ -220,12 +214,11 @@ static AST_XML_DECLARATION_NODE_T* parser_parse_xml_declaration(parser_T* parser
220
214
  tag_opening,
221
215
  children,
222
216
  tag_closing,
223
- tag_opening->location->start,
224
- tag_closing->location->end,
217
+ tag_opening->location.start,
218
+ tag_closing->location.end,
225
219
  errors
226
220
  );
227
221
 
228
- position_free(start);
229
222
  token_free(tag_opening);
230
223
  token_free(tag_closing);
231
224
  buffer_free(&content);
@@ -234,7 +227,7 @@ static AST_XML_DECLARATION_NODE_T* parser_parse_xml_declaration(parser_T* parser
234
227
  }
235
228
 
236
229
  static AST_HTML_TEXT_NODE_T* parser_parse_text_content(parser_T* parser, array_T* document_errors) {
237
- position_T* start = position_copy(parser->current_token->location->start);
230
+ position_T start = parser->current_token->location.start;
238
231
 
239
232
  buffer_T content = buffer_new();
240
233
 
@@ -255,13 +248,12 @@ static AST_HTML_TEXT_NODE_T* parser_parse_text_content(parser_T* parser, array_T
255
248
  "Token Error",
256
249
  "not TOKEN_ERROR",
257
250
  token->value,
258
- token->location->start,
259
- token->location->end,
251
+ token->location.start,
252
+ token->location.end,
260
253
  document_errors
261
254
  );
262
255
 
263
256
  token_free(token);
264
- position_free(start);
265
257
 
266
258
  return NULL;
267
259
  }
@@ -275,17 +267,15 @@ static AST_HTML_TEXT_NODE_T* parser_parse_text_content(parser_T* parser, array_T
275
267
 
276
268
  if (buffer_length(&content) > 0) {
277
269
  AST_HTML_TEXT_NODE_T* text_node =
278
- ast_html_text_node_init(buffer_value(&content), start, parser->current_token->location->start, errors);
270
+ ast_html_text_node_init(buffer_value(&content), start, parser->current_token->location.start, errors);
279
271
 
280
- position_free(start);
281
272
  buffer_free(&content);
282
273
 
283
274
  return text_node;
284
275
  }
285
276
 
286
- AST_HTML_TEXT_NODE_T* text_node = ast_html_text_node_init("", start, parser->current_token->location->start, errors);
277
+ AST_HTML_TEXT_NODE_T* text_node = ast_html_text_node_init("", start, parser->current_token->location.start, errors);
287
278
 
288
- position_free(start);
289
279
  buffer_free(&content);
290
280
 
291
281
  return text_node;
@@ -295,7 +285,7 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T
295
285
  array_T* errors = array_init(8);
296
286
  array_T* children = array_init(8);
297
287
  buffer_T buffer = buffer_new();
298
- position_T* start = position_copy(parser->current_token->location->start);
288
+ position_T start = parser->current_token->location.start;
299
289
 
300
290
  while (token_is_none_of(
301
291
  parser,
@@ -312,8 +302,7 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T
312
302
  AST_ERB_CONTENT_NODE_T* erb_node = parser_parse_erb_tag(parser);
313
303
  array_append(children, erb_node);
314
304
 
315
- position_free(start);
316
- start = position_copy(parser->current_token->location->start);
305
+ start = parser->current_token->location.start;
317
306
  continue;
318
307
  }
319
308
 
@@ -324,26 +313,23 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T
324
313
 
325
314
  parser_append_literal_node_from_buffer(parser, &buffer, children, start);
326
315
 
327
- position_T* node_start = NULL;
328
- position_T* node_end = NULL;
316
+ position_T node_start = { 0 };
317
+ position_T node_end = { 0 };
329
318
 
330
319
  if (children->size > 0) {
331
320
  AST_NODE_T* first_child = array_get(children, 0);
332
321
  AST_NODE_T* last_child = array_get(children, children->size - 1);
333
322
 
334
- node_start = position_copy(first_child->location->start);
335
- node_end = position_copy(last_child->location->end);
323
+ node_start = first_child->location.start;
324
+ node_end = last_child->location.end;
336
325
  } else {
337
- node_start = position_copy(parser->current_token->location->start);
338
- node_end = position_copy(parser->current_token->location->start);
326
+ node_start = parser->current_token->location.start;
327
+ node_end = parser->current_token->location.start;
339
328
  }
340
329
 
341
330
  AST_HTML_ATTRIBUTE_NAME_NODE_T* attribute_name =
342
331
  ast_html_attribute_name_node_init(children, node_start, node_end, errors);
343
332
 
344
- position_free(start);
345
- position_free(node_start);
346
- position_free(node_end);
347
333
  buffer_free(&buffer);
348
334
 
349
335
  return attribute_name;
@@ -356,7 +342,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
356
342
  ) {
357
343
  buffer_T buffer = buffer_new();
358
344
  token_T* opening_quote = parser_consume_expected(parser, TOKEN_QUOTE, errors);
359
- position_T* start = position_copy(parser->current_token->location->start);
345
+ position_T start = parser->current_token->location.start;
360
346
 
361
347
  while (!token_is(parser, TOKEN_EOF)
362
348
  && !(
@@ -368,8 +354,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
368
354
 
369
355
  array_append(children, parser_parse_erb_tag(parser));
370
356
 
371
- position_free(start);
372
- start = position_copy(parser->current_token->location->start);
357
+ start = parser->current_token->location.start;
373
358
 
374
359
  continue;
375
360
  }
@@ -414,8 +399,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
414
399
  "Unescaped quote character in attribute value",
415
400
  "escaped quote (\\') or different quote style (\")",
416
401
  opening_quote->value,
417
- potential_closing->location->start,
418
- potential_closing->location->end,
402
+ potential_closing->location.start,
403
+ potential_closing->location.end,
419
404
  errors
420
405
  );
421
406
 
@@ -438,8 +423,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
438
423
 
439
424
  array_append(children, parser_parse_erb_tag(parser));
440
425
 
441
- position_free(start);
442
- start = position_copy(parser->current_token->location->start);
426
+ start = parser->current_token->location.start;
443
427
 
444
428
  continue;
445
429
  }
@@ -458,7 +442,6 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
458
442
  }
459
443
 
460
444
  parser_append_literal_node_from_buffer(parser, &buffer, children, start);
461
- position_free(start);
462
445
  buffer_free(&buffer);
463
446
 
464
447
  token_T* closing_quote = parser_consume_expected(parser, TOKEN_QUOTE, errors);
@@ -467,8 +450,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
467
450
  append_quotes_mismatch_error(
468
451
  opening_quote,
469
452
  closing_quote,
470
- closing_quote->location->start,
471
- closing_quote->location->end,
453
+ closing_quote->location.start,
454
+ closing_quote->location.end,
472
455
  errors
473
456
  );
474
457
  }
@@ -478,8 +461,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
478
461
  children,
479
462
  closing_quote,
480
463
  true,
481
- opening_quote->location->start,
482
- closing_quote->location->end,
464
+ opening_quote->location.start,
465
+ closing_quote->location.end,
483
466
  errors
484
467
  );
485
468
 
@@ -503,8 +486,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser
503
486
  children,
504
487
  NULL,
505
488
  false,
506
- erb_node->base.location->start,
507
- erb_node->base.location->end,
489
+ erb_node->base.location.start,
490
+ erb_node->base.location.end,
508
491
  errors
509
492
  );
510
493
  }
@@ -522,8 +505,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser
522
505
  children,
523
506
  NULL,
524
507
  false,
525
- literal->base.location->start,
526
- literal->base.location->end,
508
+ literal->base.location.start,
509
+ literal->base.location.end,
527
510
  errors
528
511
  );
529
512
  }
@@ -533,8 +516,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser
533
516
 
534
517
  if (token_is(parser, TOKEN_BACKTICK)) {
535
518
  token_T* token = parser_advance(parser);
536
- position_T* start = position_copy(token->location->start);
537
- position_T* end = position_copy(token->location->end);
519
+ position_T start = token->location.start;
520
+ position_T end = token->location.end;
538
521
 
539
522
  append_unexpected_error(
540
523
  "Invalid quote character for HTML attribute",
@@ -548,8 +531,6 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser
548
531
  AST_HTML_ATTRIBUTE_VALUE_NODE_T* value =
549
532
  ast_html_attribute_value_node_init(NULL, children, NULL, false, start, end, errors);
550
533
 
551
- position_free(start);
552
- position_free(end);
553
534
  token_free(token);
554
535
 
555
536
  return value;
@@ -559,8 +540,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser
559
540
  "Unexpected Token",
560
541
  "TOKEN_IDENTIFIER, TOKEN_QUOTE, TOKEN_ERB_START",
561
542
  token_type_to_string(parser->current_token->type),
562
- parser->current_token->location->start,
563
- parser->current_token->location->end,
543
+ parser->current_token->location.start,
544
+ parser->current_token->location.end,
564
545
  errors
565
546
  );
566
547
 
@@ -569,8 +550,8 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_html_attribute_value(parser
569
550
  children,
570
551
  NULL,
571
552
  false,
572
- parser->current_token->location->start,
573
- parser->current_token->location->end,
553
+ parser->current_token->location.start,
554
+ parser->current_token->location.end,
574
555
  errors
575
556
  );
576
557
 
@@ -586,17 +567,19 @@ static AST_HTML_ATTRIBUTE_NODE_T* parser_parse_html_attribute(parser_T* parser)
586
567
 
587
568
  if (has_equals) {
588
569
  buffer_T equals_buffer = buffer_new();
589
- position_T* equals_start = NULL;
590
- position_T* equals_end = NULL;
591
- size_t range_start = 0;
592
- size_t range_end = 0;
570
+ position_T equals_start = { 0 };
571
+ position_T equals_end = { 0 };
572
+ uint32_t range_start = 0;
573
+ uint32_t range_end = 0;
593
574
 
575
+ bool equals_start_present = false;
594
576
  while (token_is_any_of(parser, TOKEN_WHITESPACE, TOKEN_NEWLINE)) {
595
577
  token_T* whitespace = parser_advance(parser);
596
578
 
597
- if (equals_start == NULL) {
598
- equals_start = position_copy(whitespace->location->start);
599
- range_start = whitespace->range->from;
579
+ if (equals_start_present == false) {
580
+ equals_start_present = true;
581
+ equals_start = whitespace->location.start;
582
+ range_start = whitespace->range.from;
600
583
  }
601
584
 
602
585
  buffer_append(&equals_buffer, whitespace->value);
@@ -605,29 +588,30 @@ static AST_HTML_ATTRIBUTE_NODE_T* parser_parse_html_attribute(parser_T* parser)
605
588
 
606
589
  token_T* equals = parser_advance(parser);
607
590
 
608
- if (equals_start == NULL) {
609
- equals_start = position_copy(equals->location->start);
610
- range_start = equals->range->from;
591
+ if (equals_start_present == false) {
592
+ equals_start_present = true;
593
+ equals_start = equals->location.start;
594
+ range_start = equals->range.from;
611
595
  }
612
596
 
613
597
  buffer_append(&equals_buffer, equals->value);
614
- equals_end = position_copy(equals->location->end);
615
- range_end = equals->range->to;
598
+ equals_end = equals->location.end;
599
+ range_end = equals->range.to;
616
600
  token_free(equals);
617
601
 
618
602
  while (token_is_any_of(parser, TOKEN_WHITESPACE, TOKEN_NEWLINE)) {
619
603
  token_T* whitespace = parser_advance(parser);
620
604
  buffer_append(&equals_buffer, whitespace->value);
621
- equals_end = position_copy(whitespace->location->end);
622
- range_end = whitespace->range->to;
605
+ equals_end = whitespace->location.end;
606
+ range_end = whitespace->range.to;
623
607
  token_free(whitespace);
624
608
  }
625
609
 
626
610
  token_T* equals_with_whitespace = calloc(1, sizeof(token_T));
627
611
  equals_with_whitespace->type = TOKEN_EQUALS;
628
612
  equals_with_whitespace->value = herb_strdup(equals_buffer.value);
629
- equals_with_whitespace->location = location_init(equals_start, equals_end);
630
- equals_with_whitespace->range = range_init(range_start, range_end);
613
+ equals_with_whitespace->location = (location_T) { .start = equals_start, .end = equals_end };
614
+ equals_with_whitespace->range = (range_T) { .from = range_start, .to = range_end };
631
615
 
632
616
  buffer_free(&equals_buffer);
633
617
 
@@ -637,8 +621,8 @@ static AST_HTML_ATTRIBUTE_NODE_T* parser_parse_html_attribute(parser_T* parser)
637
621
  attribute_name,
638
622
  equals_with_whitespace,
639
623
  attribute_value,
640
- attribute_name->base.location->start,
641
- attribute_value->base.location->end,
624
+ attribute_name->base.location.start,
625
+ attribute_value->base.location.end,
642
626
  NULL
643
627
  );
644
628
  } else {
@@ -646,8 +630,8 @@ static AST_HTML_ATTRIBUTE_NODE_T* parser_parse_html_attribute(parser_T* parser)
646
630
  attribute_name,
647
631
  NULL,
648
632
  NULL,
649
- attribute_name->base.location->start,
650
- attribute_name->base.location->end,
633
+ attribute_name->base.location.start,
634
+ attribute_name->base.location.end,
651
635
  NULL
652
636
  );
653
637
  }
@@ -666,8 +650,8 @@ static AST_HTML_ATTRIBUTE_NODE_T* parser_parse_html_attribute(parser_T* parser)
666
650
  attribute_name,
667
651
  equals,
668
652
  attribute_value,
669
- attribute_name->base.location->start,
670
- attribute_value->base.location->end,
653
+ attribute_name->base.location.start,
654
+ attribute_value->base.location.end,
671
655
  NULL
672
656
  );
673
657
 
@@ -680,8 +664,8 @@ static AST_HTML_ATTRIBUTE_NODE_T* parser_parse_html_attribute(parser_T* parser)
680
664
  attribute_name,
681
665
  NULL,
682
666
  NULL,
683
- attribute_name->base.location->start,
684
- attribute_name->base.location->end,
667
+ attribute_name->base.location.start,
668
+ attribute_name->base.location.end,
685
669
  NULL
686
670
  );
687
671
  }
@@ -849,8 +833,8 @@ static AST_HTML_OPEN_TAG_NODE_T* parser_parse_html_open_tag(parser_T* parser) {
849
833
  tag_end,
850
834
  children,
851
835
  is_self_closing,
852
- tag_start->location->start,
853
- tag_end->location->end,
836
+ tag_start->location.start,
837
+ tag_end->location.end,
854
838
  errors
855
839
  );
856
840
 
@@ -883,8 +867,8 @@ static AST_HTML_CLOSE_TAG_NODE_T* parser_parse_html_close_tag(parser_T* parser)
883
867
  tag_name,
884
868
  expected,
885
869
  got,
886
- tag_opening->location->start,
887
- tag_closing->location->end,
870
+ tag_opening->location.start,
871
+ tag_closing->location.end,
888
872
  errors
889
873
  );
890
874
 
@@ -897,8 +881,8 @@ static AST_HTML_CLOSE_TAG_NODE_T* parser_parse_html_close_tag(parser_T* parser)
897
881
  tag_name,
898
882
  children,
899
883
  tag_closing,
900
- tag_opening->location->start,
901
- tag_closing->location->end,
884
+ tag_opening->location.start,
885
+ tag_closing->location.end,
902
886
  errors
903
887
  );
904
888
 
@@ -921,8 +905,8 @@ static AST_HTML_ELEMENT_NODE_T* parser_parse_html_self_closing_element(
921
905
  NULL,
922
906
  true,
923
907
  ELEMENT_SOURCE_HTML,
924
- open_tag->base.location->start,
925
- open_tag->base.location->end,
908
+ open_tag->base.location.start,
909
+ open_tag->base.location.end,
926
910
  NULL
927
911
  );
928
912
  }
@@ -970,8 +954,8 @@ static AST_HTML_ELEMENT_NODE_T* parser_parse_html_regular_element(
970
954
  close_tag,
971
955
  false,
972
956
  ELEMENT_SOURCE_HTML,
973
- open_tag->base.location->start,
974
- close_tag->base.location->end,
957
+ open_tag->base.location.start,
958
+ close_tag->base.location.end,
975
959
  errors
976
960
  );
977
961
  }
@@ -1001,8 +985,8 @@ static AST_HTML_ELEMENT_NODE_T* parser_parse_html_element(parser_T* parser) {
1001
985
  NULL,
1002
986
  false,
1003
987
  ELEMENT_SOURCE_HTML,
1004
- open_tag->base.location->start,
1005
- open_tag->base.location->end,
988
+ open_tag->base.location.start,
989
+ open_tag->base.location.end,
1006
990
  errors
1007
991
  );
1008
992
  }
@@ -1021,8 +1005,8 @@ static AST_ERB_CONTENT_NODE_T* parser_parse_erb_tag(parser_T* parser) {
1021
1005
  NULL,
1022
1006
  false,
1023
1007
  false,
1024
- opening_tag->location->start,
1025
- closing_tag->location->end,
1008
+ opening_tag->location.start,
1009
+ closing_tag->location.end,
1026
1010
  errors
1027
1011
  );
1028
1012
 
@@ -1035,12 +1019,11 @@ static AST_ERB_CONTENT_NODE_T* parser_parse_erb_tag(parser_T* parser) {
1035
1019
 
1036
1020
  static void parser_parse_foreign_content(parser_T* parser, array_T* children, array_T* errors) {
1037
1021
  buffer_T content = buffer_new();
1038
- position_T* start = position_copy(parser->current_token->location->start);
1022
+ position_T start = parser->current_token->location.start;
1039
1023
  const char* expected_closing_tag = parser_get_foreign_content_closing_tag(parser->foreign_content_type);
1040
1024
 
1041
1025
  if (expected_closing_tag == NULL) {
1042
1026
  parser_exit_foreign_content(parser);
1043
- position_free(start);
1044
1027
  buffer_free(&content);
1045
1028
 
1046
1029
  return;
@@ -1053,8 +1036,7 @@ static void parser_parse_foreign_content(parser_T* parser, array_T* children, ar
1053
1036
  AST_ERB_CONTENT_NODE_T* erb_node = parser_parse_erb_tag(parser);
1054
1037
  array_append(children, erb_node);
1055
1038
 
1056
- position_free(start);
1057
- start = position_copy(parser->current_token->location->start);
1039
+ start = parser->current_token->location.start;
1058
1040
 
1059
1041
  continue;
1060
1042
  }
@@ -1077,7 +1059,6 @@ static void parser_parse_foreign_content(parser_T* parser, array_T* children, ar
1077
1059
  parser_append_literal_node_from_buffer(parser, &content, children, start);
1078
1060
  parser_exit_foreign_content(parser);
1079
1061
 
1080
- position_free(start);
1081
1062
  buffer_free(&content);
1082
1063
 
1083
1064
  return;
@@ -1091,7 +1072,6 @@ static void parser_parse_foreign_content(parser_T* parser, array_T* children, ar
1091
1072
 
1092
1073
  parser_append_literal_node_from_buffer(parser, &content, children, start);
1093
1074
  parser_exit_foreign_content(parser);
1094
- position_free(start);
1095
1075
  buffer_free(&content);
1096
1076
  }
1097
1077
 
@@ -1167,8 +1147,8 @@ static void parser_parse_unclosed_html_tags(const parser_T* parser, array_T* err
1167
1147
 
1168
1148
  append_unclosed_element_error(
1169
1149
  unclosed_tag,
1170
- parser->current_token->location->start,
1171
- parser->current_token->location->end,
1150
+ parser->current_token->location.start,
1151
+ parser->current_token->location.end,
1172
1152
  errors
1173
1153
  );
1174
1154
 
@@ -1192,8 +1172,8 @@ static void parser_parse_stray_closing_tags(parser_T* parser, array_T* children,
1192
1172
  if (!is_void_element(close_tag->tag_name->value)) {
1193
1173
  append_missing_opening_tag_error(
1194
1174
  close_tag->tag_name,
1195
- close_tag->base.location->start,
1196
- close_tag->base.location->end,
1175
+ close_tag->base.location.start,
1176
+ close_tag->base.location.end,
1197
1177
  close_tag->base.errors
1198
1178
  );
1199
1179
  }
@@ -1207,7 +1187,7 @@ static void parser_parse_stray_closing_tags(parser_T* parser, array_T* children,
1207
1187
  static AST_DOCUMENT_NODE_T* parser_parse_document(parser_T* parser) {
1208
1188
  array_T* children = array_init(8);
1209
1189
  array_T* errors = array_init(8);
1210
- position_T* start = position_copy(parser->current_token->location->start);
1190
+ position_T start = parser->current_token->location.start;
1211
1191
 
1212
1192
  parser_parse_in_data_state(parser, children, errors);
1213
1193
  parser_parse_unclosed_html_tags(parser, errors);
@@ -1215,9 +1195,8 @@ static AST_DOCUMENT_NODE_T* parser_parse_document(parser_T* parser) {
1215
1195
 
1216
1196
  token_T* eof = parser_consume_expected(parser, TOKEN_EOF, errors);
1217
1197
 
1218
- AST_DOCUMENT_NODE_T* document_node = ast_document_node_init(children, start, eof->location->end, errors);
1198
+ AST_DOCUMENT_NODE_T* document_node = ast_document_node_init(children, start, eof->location.end, errors);
1219
1199
 
1220
- position_free(start);
1221
1200
  token_free(eof);
1222
1201
 
1223
1202
  return document_node;
@@ -1232,8 +1211,8 @@ static void parser_handle_whitespace(parser_T* parser, token_T* whitespace_token
1232
1211
  array_T* errors = array_init(8);
1233
1212
  AST_WHITESPACE_NODE_T* whitespace_node = ast_whitespace_node_init(
1234
1213
  whitespace_token,
1235
- whitespace_token->location->start,
1236
- whitespace_token->location->end,
1214
+ whitespace_token->location.start,
1215
+ whitespace_token->location.end,
1237
1216
  errors
1238
1217
  );
1239
1218
  array_append(children, whitespace_node);