prism 2.0.0.rc1 → 2.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -2
- data/CODE_OF_CONDUCT.md +1 -1
- data/LICENSE.md +1 -1
- data/docs/serialization.md +20 -6
- data/ext/prism/api_node.c +81 -81
- data/ext/prism/extension.c +54 -69
- data/ext/prism/extension.h +1 -1
- data/include/prism/arena.h +8 -0
- data/include/prism/arena.hpp +42 -0
- data/include/prism/ast.h +11 -1
- data/include/prism/ast.hpp +641 -0
- data/include/prism/buffer.h +8 -0
- data/include/prism/buffer.hpp +55 -0
- data/include/prism/comments.h +17 -0
- data/include/prism/compiler/accel.h +3 -1
- data/include/prism/compiler/branch.h +26 -0
- data/include/prism/compiler/bswap.h +46 -0
- data/include/prism/compiler/cplusplus.hpp +16 -0
- data/include/prism/compiler/endianness.h +34 -0
- data/include/prism/compiler/exceptions.hpp +17 -0
- data/include/prism/compiler/format.h +2 -0
- data/include/prism/compiler/lifetimebound.hpp +25 -0
- data/include/prism/constant_pool.h +25 -0
- data/include/prism/diagnostic.h +18 -0
- data/include/prism/errors_format.h +8 -0
- data/include/prism/internal/buffer.h +3 -0
- data/include/prism/internal/node.h +8 -4
- data/include/prism/internal/parser.h +20 -0
- data/include/prism/internal/stringy.h +1 -6
- data/include/prism/internal/xxh3.h +16 -0
- data/include/prism/json.h +8 -0
- data/include/prism/line_offset_list.h +8 -0
- data/include/prism/magic_comments.h +18 -0
- data/include/prism/node.h +55 -10
- data/include/prism/node.hpp +272 -0
- data/include/prism/node_type.hpp +38 -0
- data/include/prism/options.h +10 -1
- data/include/prism/options.hpp +43 -0
- data/include/prism/parser.h +93 -64
- data/include/prism/parser.hpp +274 -0
- data/include/prism/prettyprint.h +8 -0
- data/include/prism/serialize.h +8 -0
- data/include/prism/source.h +8 -0
- data/include/prism/stream.h +8 -0
- data/include/prism/string_query.h +19 -0
- data/include/prism/stringy.h +16 -27
- data/include/prism/stringy.hpp +31 -0
- data/include/prism/version.h +9 -1
- data/include/prism.h +0 -8
- data/include/prism.hpp +24 -0
- data/lib/prism/ffi.rb +6 -0
- data/lib/prism/node.rb +736 -0
- data/lib/prism/parse_result.rb +23 -8
- data/lib/prism/serialize.rb +2567 -3286
- data/lib/prism/string_query.rb +8 -0
- data/prism.gemspec +21 -4
- data/rbi/generated/prism/node.rbi +2430 -968
- data/rbi/generated/prism/parse_result.rbi +16 -4
- data/rbi/generated/prism/serialize.rbi +8 -4
- data/rbi/generated/prism/string_query.rbi +7 -0
- data/sig/generated/prism/node.rbs +2439 -967
- data/sig/generated/prism/parse_result.rbs +16 -4
- data/sig/generated/prism/serialize.rbs +9 -4
- data/sig/generated/prism/string_query.rbs +7 -0
- data/src/buffer.c +9 -0
- data/src/comments.c +2 -2
- data/src/diagnostic.c +8 -0
- data/src/node.c +216 -368
- data/src/options.c +7 -13
- data/src/parser.c +70 -48
- data/src/prism.c +581 -419
- data/src/regexp.c +0 -1
- data/src/serialize.c +2301 -1950
- data/src/source.c +8 -2
- data/src/string_query.c +14 -0
- data/src/stringy.c +3 -33
- data/src/xxh3.c +292 -0
- metadata +20 -3
data/ext/prism/extension.c
CHANGED
|
@@ -192,7 +192,7 @@ build_options_scopes(pm_options_t *options, VALUE scopes) {
|
|
|
192
192
|
// Add the local to the scope.
|
|
193
193
|
pm_string_t *scope_local = pm_options_scope_local_mut(options_scope, local_index);
|
|
194
194
|
const char *name = rb_id2name(SYM2ID(local));
|
|
195
|
-
|
|
195
|
+
pm_string_init(scope_local, (const uint8_t *) name, strlen(name));
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
// Now set the forwarding options.
|
|
@@ -633,28 +633,19 @@ parser_comment(VALUE source, bool freeze, const pm_comment_t *comment) {
|
|
|
633
633
|
return rb_class_new_instance_freeze(1, argv, type, freeze);
|
|
634
634
|
}
|
|
635
635
|
|
|
636
|
-
typedef struct {
|
|
637
|
-
VALUE comments;
|
|
638
|
-
VALUE source;
|
|
639
|
-
bool freeze;
|
|
640
|
-
long index;
|
|
641
|
-
} parser_comments_each_data_t;
|
|
642
|
-
|
|
643
|
-
static void
|
|
644
|
-
parser_comments_each(const pm_comment_t *comment, void *data) {
|
|
645
|
-
parser_comments_each_data_t *each_data = (parser_comments_each_data_t *) data;
|
|
646
|
-
VALUE value = parser_comment(each_data->source, each_data->freeze, comment);
|
|
647
|
-
rb_ary_store(each_data->comments, each_data->index++, value);
|
|
648
|
-
}
|
|
649
|
-
|
|
650
636
|
/**
|
|
651
637
|
* Extract the comments out of the parser into the given array, which was
|
|
652
|
-
* created before the source so that the source could hold it.
|
|
638
|
+
* created before the source so that the source could hold it. The caller may
|
|
639
|
+
* have already resized it to the number of comments, so each comment is stored
|
|
640
|
+
* at its index rather than pushed.
|
|
653
641
|
*/
|
|
654
642
|
static void
|
|
655
643
|
parser_comments(const pm_parser_t *parser, VALUE comments, VALUE source, bool freeze) {
|
|
656
|
-
|
|
657
|
-
|
|
644
|
+
long index = 0;
|
|
645
|
+
for (const pm_comment_t *comment = pm_parser_comments_first(parser); comment != NULL; comment = pm_comment_next(comment)) {
|
|
646
|
+
rb_ary_store(comments, index++, parser_comment(source, freeze, comment));
|
|
647
|
+
}
|
|
648
|
+
|
|
658
649
|
if (freeze) rb_obj_freeze(comments);
|
|
659
650
|
}
|
|
660
651
|
|
|
@@ -673,19 +664,6 @@ parser_magic_comment(VALUE source, bool freeze, const pm_magic_comment_t *magic_
|
|
|
673
664
|
return rb_class_new_instance_freeze(2, argv, rb_cPrismMagicComment, freeze);
|
|
674
665
|
}
|
|
675
666
|
|
|
676
|
-
typedef struct {
|
|
677
|
-
VALUE magic_comments;
|
|
678
|
-
VALUE source;
|
|
679
|
-
bool freeze;
|
|
680
|
-
} parser_magic_comments_each_data_t;
|
|
681
|
-
|
|
682
|
-
static void
|
|
683
|
-
parser_magic_comments_each(const pm_magic_comment_t *magic_comment, void *data) {
|
|
684
|
-
parser_magic_comments_each_data_t *each_data = (parser_magic_comments_each_data_t *) data;
|
|
685
|
-
VALUE value = parser_magic_comment(each_data->source, each_data->freeze, magic_comment);
|
|
686
|
-
rb_ary_push(each_data->magic_comments, value);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
667
|
/**
|
|
690
668
|
* Extract the magic comments out of the parser into an array.
|
|
691
669
|
*/
|
|
@@ -693,8 +671,9 @@ static VALUE
|
|
|
693
671
|
parser_magic_comments(const pm_parser_t *parser, VALUE source, bool freeze) {
|
|
694
672
|
VALUE magic_comments = rb_ary_new_capa(pm_parser_magic_comments_size(parser));
|
|
695
673
|
|
|
696
|
-
|
|
697
|
-
|
|
674
|
+
for (const pm_magic_comment_t *magic_comment = pm_parser_magic_comments_first(parser); magic_comment != NULL; magic_comment = pm_magic_comment_next(magic_comment)) {
|
|
675
|
+
rb_ary_push(magic_comments, parser_magic_comment(source, freeze, magic_comment));
|
|
676
|
+
}
|
|
698
677
|
|
|
699
678
|
if (freeze) rb_obj_freeze(magic_comments);
|
|
700
679
|
return magic_comments;
|
|
@@ -715,20 +694,14 @@ parser_data_loc(const pm_parser_t *parser, VALUE source, bool freeze) {
|
|
|
715
694
|
}
|
|
716
695
|
}
|
|
717
696
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
} parser_errors_each_data_t;
|
|
724
|
-
|
|
725
|
-
static void
|
|
726
|
-
parser_errors_each(const pm_diagnostic_t *diagnostic, void *data) {
|
|
727
|
-
parser_errors_each_data_t *each_data = (parser_errors_each_data_t *) data;
|
|
728
|
-
|
|
697
|
+
/**
|
|
698
|
+
* Build a new ParseError instance from the given error.
|
|
699
|
+
*/
|
|
700
|
+
static VALUE
|
|
701
|
+
parser_error(const pm_diagnostic_t *diagnostic, rb_encoding *encoding, VALUE source, bool freeze) {
|
|
729
702
|
VALUE type = ID2SYM(rb_intern(pm_diagnostic_type(diagnostic)));
|
|
730
|
-
VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(pm_diagnostic_message(diagnostic),
|
|
731
|
-
VALUE location = PARSER_LOCATION(
|
|
703
|
+
VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(pm_diagnostic_message(diagnostic), encoding));
|
|
704
|
+
VALUE location = PARSER_LOCATION(source, freeze, pm_diagnostic_location(diagnostic));
|
|
732
705
|
|
|
733
706
|
pm_error_level_t error_level = pm_diagnostic_error_level(diagnostic);
|
|
734
707
|
VALUE level = Qnil;
|
|
@@ -748,8 +721,7 @@ parser_errors_each(const pm_diagnostic_t *diagnostic, void *data) {
|
|
|
748
721
|
}
|
|
749
722
|
|
|
750
723
|
VALUE argv[] = { type, message, location, level };
|
|
751
|
-
|
|
752
|
-
rb_ary_push(each_data->errors, value);
|
|
724
|
+
return rb_class_new_instance_freeze(4, argv, rb_cPrismParseError, freeze);
|
|
753
725
|
}
|
|
754
726
|
|
|
755
727
|
/**
|
|
@@ -759,27 +731,22 @@ static VALUE
|
|
|
759
731
|
parser_errors(const pm_parser_t *parser, rb_encoding *encoding, VALUE source, bool freeze) {
|
|
760
732
|
VALUE errors = rb_ary_new_capa(pm_parser_errors_size(parser));
|
|
761
733
|
|
|
762
|
-
|
|
763
|
-
|
|
734
|
+
for (const pm_diagnostic_t *error = pm_parser_errors_first(parser); error != NULL; error = pm_diagnostic_next(error)) {
|
|
735
|
+
rb_ary_push(errors, parser_error(error, encoding, source, freeze));
|
|
736
|
+
}
|
|
764
737
|
|
|
765
738
|
if (freeze) rb_obj_freeze(errors);
|
|
766
739
|
return errors;
|
|
767
740
|
}
|
|
768
741
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
} parser_warnings_each_data_t;
|
|
775
|
-
|
|
776
|
-
static void
|
|
777
|
-
parser_warnings_each(const pm_diagnostic_t *diagnostic, void *data) {
|
|
778
|
-
parser_warnings_each_data_t *each_data = (parser_warnings_each_data_t *) data;
|
|
779
|
-
|
|
742
|
+
/**
|
|
743
|
+
* Build a new ParseWarning instance from the given warning.
|
|
744
|
+
*/
|
|
745
|
+
static VALUE
|
|
746
|
+
parser_warning(const pm_diagnostic_t *diagnostic, rb_encoding *encoding, VALUE source, bool freeze) {
|
|
780
747
|
VALUE type = ID2SYM(rb_intern(pm_diagnostic_type(diagnostic)));
|
|
781
|
-
VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(pm_diagnostic_message(diagnostic),
|
|
782
|
-
VALUE location = PARSER_LOCATION(
|
|
748
|
+
VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(pm_diagnostic_message(diagnostic), encoding));
|
|
749
|
+
VALUE location = PARSER_LOCATION(source, freeze, pm_diagnostic_location(diagnostic));
|
|
783
750
|
|
|
784
751
|
pm_warning_level_t warning_level = pm_diagnostic_warning_level(diagnostic);
|
|
785
752
|
VALUE level = Qnil;
|
|
@@ -796,8 +763,7 @@ parser_warnings_each(const pm_diagnostic_t *diagnostic, void *data) {
|
|
|
796
763
|
}
|
|
797
764
|
|
|
798
765
|
VALUE argv[] = { type, message, location, level };
|
|
799
|
-
|
|
800
|
-
rb_ary_push(each_data->warnings, value);
|
|
766
|
+
return rb_class_new_instance_freeze(4, argv, rb_cPrismParseWarning, freeze);
|
|
801
767
|
}
|
|
802
768
|
|
|
803
769
|
/**
|
|
@@ -807,8 +773,9 @@ static VALUE
|
|
|
807
773
|
parser_warnings(const pm_parser_t *parser, rb_encoding *encoding, VALUE source, bool freeze) {
|
|
808
774
|
VALUE warnings = rb_ary_new_capa(pm_parser_warnings_size(parser));
|
|
809
775
|
|
|
810
|
-
|
|
811
|
-
|
|
776
|
+
for (const pm_diagnostic_t *warning = pm_parser_warnings_first(parser); warning != NULL; warning = pm_diagnostic_next(warning)) {
|
|
777
|
+
rb_ary_push(warnings, parser_warning(warning, encoding, source, freeze));
|
|
778
|
+
}
|
|
812
779
|
|
|
813
780
|
if (freeze) rb_obj_freeze(warnings);
|
|
814
781
|
return warnings;
|
|
@@ -983,8 +950,9 @@ parse_lex_input(const uint8_t *input, size_t input_length, const pm_options_t *o
|
|
|
983
950
|
|
|
984
951
|
result_t result = check_raise_error_option(parser, options, path_encoding);
|
|
985
952
|
if (result.type == RESULT_OK) {
|
|
986
|
-
/* Update the Source object with the correct encoding
|
|
987
|
-
* which are only available after pm_parse()
|
|
953
|
+
/* Update the Source object with the correct encoding, line offsets,
|
|
954
|
+
* and source hash, which are only available after pm_parse()
|
|
955
|
+
* completes. */
|
|
988
956
|
rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
|
|
989
957
|
rb_enc_associate(source_string, encoding);
|
|
990
958
|
|
|
@@ -993,6 +961,8 @@ parse_lex_input(const uint8_t *input, size_t input_length, const pm_options_t *o
|
|
|
993
961
|
rb_ary_store(offsets, (long) index, ULONG2NUM(line_offsets->offsets[index]));
|
|
994
962
|
}
|
|
995
963
|
|
|
964
|
+
rb_funcall(source, rb_intern("replace_checksum"), 1, ULL2NUM(pm_parser_checksum(parser)));
|
|
965
|
+
|
|
996
966
|
if (pm_options_freeze(options)) {
|
|
997
967
|
rb_obj_freeze(source_string);
|
|
998
968
|
rb_obj_freeze(offsets);
|
|
@@ -1678,6 +1648,20 @@ string_query_method_name_p(VALUE self, VALUE string) {
|
|
|
1678
1648
|
return string_query(pm_string_query_method_name(source, RSTRING_LEN(string), rb_enc_get(string)->name));
|
|
1679
1649
|
}
|
|
1680
1650
|
|
|
1651
|
+
/**
|
|
1652
|
+
* :markup: markdown
|
|
1653
|
+
* call-seq:
|
|
1654
|
+
* keyword?(string) -> bool
|
|
1655
|
+
*
|
|
1656
|
+
* Returns true if the string is a valid keyword, such as `if`, `defined?`, or
|
|
1657
|
+
* `__FILE__`.
|
|
1658
|
+
*/
|
|
1659
|
+
static VALUE
|
|
1660
|
+
string_query_keyword_p(VALUE self, VALUE string) {
|
|
1661
|
+
const uint8_t *source = (const uint8_t *) check_string(string);
|
|
1662
|
+
return string_query(pm_string_query_keyword(source, RSTRING_LEN(string), rb_enc_get(string)->name));
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1681
1665
|
/******************************************************************************/
|
|
1682
1666
|
/* Initialization of the extension */
|
|
1683
1667
|
/******************************************************************************/
|
|
@@ -1778,6 +1762,7 @@ Init_prism(void) {
|
|
|
1778
1762
|
rb_define_singleton_method(rb_cPrismStringQuery, "local?", string_query_local_p, 1);
|
|
1779
1763
|
rb_define_singleton_method(rb_cPrismStringQuery, "constant?", string_query_constant_p, 1);
|
|
1780
1764
|
rb_define_singleton_method(rb_cPrismStringQuery, "method_name?", string_query_method_name_p, 1);
|
|
1765
|
+
rb_define_singleton_method(rb_cPrismStringQuery, "keyword?", string_query_keyword_p, 1);
|
|
1781
1766
|
|
|
1782
1767
|
Init_prism_api_node();
|
|
1783
1768
|
}
|
data/ext/prism/extension.h
CHANGED
data/include/prism/arena.h
CHANGED
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
#include <stddef.h>
|
|
14
14
|
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
15
19
|
/**
|
|
16
20
|
* An opaque pointer to an arena that is used for allocations.
|
|
17
21
|
*/
|
|
@@ -34,4 +38,8 @@ PRISM_NODISCARD PRISM_EXPORTED_FUNCTION pm_arena_t * pm_arena_new(void);
|
|
|
34
38
|
*/
|
|
35
39
|
PRISM_EXPORTED_FUNCTION void pm_arena_free(pm_arena_t *arena) PRISM_NONNULL(1);
|
|
36
40
|
|
|
41
|
+
#ifdef __cplusplus
|
|
42
|
+
}
|
|
43
|
+
#endif
|
|
44
|
+
|
|
37
45
|
#endif
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file arena.hpp
|
|
3
|
+
*
|
|
4
|
+
* Ownership of arenas from C++.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PRISM_ARENA_HPP
|
|
7
|
+
#define PRISM_ARENA_HPP
|
|
8
|
+
|
|
9
|
+
#include "prism/compiler/cplusplus.hpp"
|
|
10
|
+
|
|
11
|
+
#include "prism/arena.h"
|
|
12
|
+
|
|
13
|
+
#include <memory>
|
|
14
|
+
|
|
15
|
+
namespace prism {
|
|
16
|
+
|
|
17
|
+
/** Frees an arena with pm_arena_free. */
|
|
18
|
+
struct arena_deleter {
|
|
19
|
+
/**
|
|
20
|
+
* Frees the given arena.
|
|
21
|
+
*
|
|
22
|
+
* @param arena The arena to free.
|
|
23
|
+
*/
|
|
24
|
+
void operator()(pm_arena_t *arena) const noexcept { pm_arena_free(arena); }
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** An owned arena. */
|
|
28
|
+
using unique_arena = std::unique_ptr<pm_arena_t, arena_deleter>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Allocate a new arena. Allocation failure aborts, so this never throws.
|
|
32
|
+
*
|
|
33
|
+
* @return A unique_arena managing the newly allocated arena.
|
|
34
|
+
*/
|
|
35
|
+
[[nodiscard]] inline unique_arena
|
|
36
|
+
make_arena() noexcept {
|
|
37
|
+
return unique_arena(pm_arena_new());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#endif
|
data/include/prism/ast.h
CHANGED
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
#include <stddef.h>
|
|
28
28
|
#include <stdint.h>
|
|
29
29
|
|
|
30
|
+
#ifdef __cplusplus
|
|
31
|
+
extern "C" {
|
|
32
|
+
#endif
|
|
33
|
+
|
|
30
34
|
/**
|
|
31
35
|
* This enum represents every type of token in the Ruby source.
|
|
32
36
|
*/
|
|
@@ -1103,7 +1107,9 @@ typedef struct pm_node {
|
|
|
1103
1107
|
|
|
1104
1108
|
/**
|
|
1105
1109
|
* The unique identifier for this node, which is deterministic based on the
|
|
1106
|
-
* source. It is used to identify unique nodes across parses.
|
|
1110
|
+
* source. It is used to identify unique nodes across parses. Nodes created
|
|
1111
|
+
* outside of parsing have no position in the source and can use 0, which
|
|
1112
|
+
* no parsed node uses.
|
|
1107
1113
|
*/
|
|
1108
1114
|
uint32_t node_id;
|
|
1109
1115
|
|
|
@@ -10368,4 +10374,8 @@ PRISM_EXPORTED_FUNCTION pm_yield_node_t * pm_yield_node_new(pm_arena_t *arena, u
|
|
|
10368
10374
|
*/
|
|
10369
10375
|
#define PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS 0
|
|
10370
10376
|
|
|
10377
|
+
#ifdef __cplusplus
|
|
10378
|
+
}
|
|
10379
|
+
#endif
|
|
10380
|
+
|
|
10371
10381
|
#endif
|