prism 0.29.0 → 1.3.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 +115 -1
- data/CONTRIBUTING.md +0 -4
- data/Makefile +1 -1
- data/README.md +4 -0
- data/config.yml +920 -148
- data/docs/build_system.md +8 -11
- data/docs/fuzzing.md +1 -1
- data/docs/parsing_rules.md +4 -1
- data/docs/relocation.md +34 -0
- data/docs/ripper_translation.md +22 -0
- data/docs/serialization.md +3 -0
- data/ext/prism/api_node.c +2863 -2079
- data/ext/prism/extconf.rb +14 -37
- data/ext/prism/extension.c +241 -391
- data/ext/prism/extension.h +2 -2
- data/include/prism/ast.h +2156 -453
- data/include/prism/defines.h +58 -7
- data/include/prism/diagnostic.h +24 -6
- data/include/prism/node.h +0 -21
- data/include/prism/options.h +94 -3
- data/include/prism/parser.h +82 -40
- data/include/prism/regexp.h +18 -8
- data/include/prism/static_literals.h +3 -2
- data/include/prism/util/pm_char.h +1 -2
- data/include/prism/util/pm_constant_pool.h +0 -8
- data/include/prism/util/pm_integer.h +22 -15
- data/include/prism/util/pm_newline_list.h +11 -0
- data/include/prism/util/pm_string.h +28 -12
- data/include/prism/version.h +3 -3
- data/include/prism.h +47 -11
- data/lib/prism/compiler.rb +3 -0
- data/lib/prism/desugar_compiler.rb +111 -74
- data/lib/prism/dispatcher.rb +16 -1
- data/lib/prism/dot_visitor.rb +55 -34
- data/lib/prism/dsl.rb +660 -468
- data/lib/prism/ffi.rb +113 -8
- data/lib/prism/inspect_visitor.rb +296 -64
- data/lib/prism/lex_compat.rb +1 -1
- data/lib/prism/mutation_compiler.rb +11 -6
- data/lib/prism/node.rb +4262 -5023
- data/lib/prism/node_ext.rb +91 -14
- data/lib/prism/parse_result/comments.rb +0 -7
- data/lib/prism/parse_result/errors.rb +65 -0
- data/lib/prism/parse_result/newlines.rb +101 -11
- data/lib/prism/parse_result.rb +183 -6
- data/lib/prism/reflection.rb +12 -10
- data/lib/prism/relocation.rb +504 -0
- data/lib/prism/serialize.rb +496 -609
- data/lib/prism/string_query.rb +30 -0
- data/lib/prism/translation/parser/compiler.rb +185 -155
- data/lib/prism/translation/parser/lexer.rb +26 -4
- data/lib/prism/translation/parser.rb +9 -4
- data/lib/prism/translation/ripper.rb +23 -25
- data/lib/prism/translation/ruby_parser.rb +86 -17
- data/lib/prism/visitor.rb +3 -0
- data/lib/prism.rb +6 -8
- data/prism.gemspec +9 -5
- data/rbi/prism/dsl.rbi +521 -0
- data/rbi/prism/node.rbi +1115 -1120
- data/rbi/prism/parse_result.rbi +29 -0
- data/rbi/prism/string_query.rbi +12 -0
- data/rbi/prism/visitor.rbi +3 -0
- data/rbi/prism.rbi +36 -30
- data/sig/prism/dsl.rbs +190 -303
- data/sig/prism/mutation_compiler.rbs +1 -0
- data/sig/prism/node.rbs +678 -632
- data/sig/prism/parse_result.rbs +22 -0
- data/sig/prism/relocation.rbs +185 -0
- data/sig/prism/string_query.rbs +11 -0
- data/sig/prism/visitor.rbs +1 -0
- data/sig/prism.rbs +103 -64
- data/src/diagnostic.c +64 -28
- data/src/node.c +502 -1739
- data/src/options.c +76 -27
- data/src/prettyprint.c +188 -112
- data/src/prism.c +3376 -2293
- data/src/regexp.c +208 -71
- data/src/serialize.c +182 -50
- data/src/static_literals.c +64 -85
- data/src/token_type.c +4 -4
- data/src/util/pm_char.c +1 -1
- data/src/util/pm_constant_pool.c +0 -8
- data/src/util/pm_integer.c +53 -25
- data/src/util/pm_newline_list.c +29 -0
- data/src/util/pm_string.c +131 -80
- data/src/util/pm_strpbrk.c +32 -6
- metadata +11 -7
- data/include/prism/util/pm_string_list.h +0 -44
- data/lib/prism/debug.rb +0 -249
- data/lib/prism/translation/parser/rubocop.rb +0 -73
- data/src/util/pm_string_list.c +0 -28
@@ -95,9 +95,10 @@ typedef struct {
|
|
95
95
|
* @param start_line The line number that the parser starts on.
|
96
96
|
* @param literals The set of static literals to add the node to.
|
97
97
|
* @param node The node to add to the set.
|
98
|
+
* @param replace Whether to replace the previous node if one already exists.
|
98
99
|
* @return A pointer to the node that is being overwritten, if there is one.
|
99
100
|
*/
|
100
|
-
pm_node_t * pm_static_literals_add(const pm_newline_list_t *newline_list, int32_t start_line, pm_static_literals_t *literals, pm_node_t *node);
|
101
|
+
pm_node_t * pm_static_literals_add(const pm_newline_list_t *newline_list, int32_t start_line, pm_static_literals_t *literals, pm_node_t *node, bool replace);
|
101
102
|
|
102
103
|
/**
|
103
104
|
* Free the internal memory associated with the given static literals set.
|
@@ -115,6 +116,6 @@ void pm_static_literals_free(pm_static_literals_t *literals);
|
|
115
116
|
* @param encoding_name The name of the encoding of the source being parsed.
|
116
117
|
* @param node The node to create a string representation of.
|
117
118
|
*/
|
118
|
-
|
119
|
+
void pm_static_literal_inspect(pm_buffer_t *buffer, const pm_newline_list_t *newline_list, int32_t start_line, const char *encoding_name, const pm_node_t *node);
|
119
120
|
|
120
121
|
#endif
|
@@ -34,8 +34,7 @@ size_t pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length);
|
|
34
34
|
* @return The number of characters at the start of the string that are
|
35
35
|
* whitespace.
|
36
36
|
*/
|
37
|
-
size_t
|
38
|
-
pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list);
|
37
|
+
size_t pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list);
|
39
38
|
|
40
39
|
/**
|
41
40
|
* Returns the number of characters at the start of the string that are inline
|
@@ -87,14 +87,6 @@ void pm_constant_id_list_insert(pm_constant_id_list_t *list, size_t index, pm_co
|
|
87
87
|
*/
|
88
88
|
bool pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id);
|
89
89
|
|
90
|
-
/**
|
91
|
-
* Get the memory size of a list of constant ids.
|
92
|
-
*
|
93
|
-
* @param list The list to get the memory size of.
|
94
|
-
* @return The memory size of the list.
|
95
|
-
*/
|
96
|
-
size_t pm_constant_id_list_memsize(pm_constant_id_list_t *list);
|
97
|
-
|
98
90
|
/**
|
99
91
|
* Free the memory associated with a list of constant ids.
|
100
92
|
*
|
@@ -18,12 +18,6 @@
|
|
18
18
|
* A structure represents an arbitrary-sized integer.
|
19
19
|
*/
|
20
20
|
typedef struct {
|
21
|
-
/**
|
22
|
-
* Embedded value for small integer. This value is set to 0 if the value
|
23
|
-
* does not fit into uint32_t.
|
24
|
-
*/
|
25
|
-
uint32_t value;
|
26
|
-
|
27
21
|
/**
|
28
22
|
* The number of allocated values. length is set to 0 if the integer fits
|
29
23
|
* into uint32_t.
|
@@ -35,6 +29,12 @@ typedef struct {
|
|
35
29
|
*/
|
36
30
|
uint32_t *values;
|
37
31
|
|
32
|
+
/**
|
33
|
+
* Embedded value for small integer. This value is set to 0 if the value
|
34
|
+
* does not fit into uint32_t.
|
35
|
+
*/
|
36
|
+
uint32_t value;
|
37
|
+
|
38
38
|
/**
|
39
39
|
* Whether or not the integer is negative. It is stored this way so that a
|
40
40
|
* zeroed pm_integer_t is always positive zero.
|
@@ -48,6 +48,9 @@ typedef struct {
|
|
48
48
|
* from the string itself.
|
49
49
|
*/
|
50
50
|
typedef enum {
|
51
|
+
/** The default decimal base, with no prefix. Leading 0s will be ignored. */
|
52
|
+
PM_INTEGER_BASE_DEFAULT,
|
53
|
+
|
51
54
|
/** The binary base, indicated by a 0b or 0B prefix. */
|
52
55
|
PM_INTEGER_BASE_BINARY,
|
53
56
|
|
@@ -79,15 +82,7 @@ typedef enum {
|
|
79
82
|
* @param start The start of the string.
|
80
83
|
* @param end The end of the string.
|
81
84
|
*/
|
82
|
-
|
83
|
-
|
84
|
-
/**
|
85
|
-
* Return the memory size of the integer.
|
86
|
-
*
|
87
|
-
* @param integer The integer to get the memory size of.
|
88
|
-
* @return The size of the memory associated with the integer.
|
89
|
-
*/
|
90
|
-
size_t pm_integer_memsize(const pm_integer_t *integer);
|
85
|
+
void pm_integer_parse(pm_integer_t *integer, pm_integer_base_t base, const uint8_t *start, const uint8_t *end);
|
91
86
|
|
92
87
|
/**
|
93
88
|
* Compare two integers. This function returns -1 if the left integer is less
|
@@ -100,6 +95,18 @@ size_t pm_integer_memsize(const pm_integer_t *integer);
|
|
100
95
|
*/
|
101
96
|
int pm_integer_compare(const pm_integer_t *left, const pm_integer_t *right);
|
102
97
|
|
98
|
+
/**
|
99
|
+
* Reduce a ratio of integers to its simplest form.
|
100
|
+
*
|
101
|
+
* If either the numerator or denominator do not fit into a 32-bit integer, then
|
102
|
+
* this function is a no-op. In the future, we may consider reducing even the
|
103
|
+
* larger numbers, but for now we're going to keep it simple.
|
104
|
+
*
|
105
|
+
* @param numerator The numerator of the ratio.
|
106
|
+
* @param denominator The denominator of the ratio.
|
107
|
+
*/
|
108
|
+
void pm_integers_reduce(pm_integer_t *numerator, pm_integer_t *denominator);
|
109
|
+
|
103
110
|
/**
|
104
111
|
* Convert an integer to a decimal string.
|
105
112
|
*
|
@@ -80,6 +80,17 @@ pm_newline_list_clear(pm_newline_list_t *list);
|
|
80
80
|
*/
|
81
81
|
bool pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor);
|
82
82
|
|
83
|
+
/**
|
84
|
+
* Returns the line of the given offset. If the offset is not in the list, the
|
85
|
+
* line of the closest offset less than the given offset is returned.
|
86
|
+
*
|
87
|
+
* @param list The list to search.
|
88
|
+
* @param cursor A pointer to the offset to search for.
|
89
|
+
* @param start_line The line to start counting from.
|
90
|
+
* @return The line of the given offset.
|
91
|
+
*/
|
92
|
+
int32_t pm_newline_list_line(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line);
|
93
|
+
|
83
94
|
/**
|
84
95
|
* Returns the line and column of the given offset. If the offset is not in the
|
85
96
|
* list, the line and column of the closest offset less than the given offset
|
@@ -9,6 +9,7 @@
|
|
9
9
|
#include "prism/defines.h"
|
10
10
|
|
11
11
|
#include <assert.h>
|
12
|
+
#include <errno.h>
|
12
13
|
#include <stdbool.h>
|
13
14
|
#include <stddef.h>
|
14
15
|
#include <stdlib.h>
|
@@ -21,6 +22,9 @@
|
|
21
22
|
#include <fcntl.h>
|
22
23
|
#include <sys/mman.h>
|
23
24
|
#include <sys/stat.h>
|
25
|
+
#elif defined(PRISM_HAS_FILESYSTEM)
|
26
|
+
#include <fcntl.h>
|
27
|
+
#include <sys/stat.h>
|
24
28
|
#endif
|
25
29
|
|
26
30
|
/**
|
@@ -92,6 +96,26 @@ void pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length);
|
|
92
96
|
*/
|
93
97
|
void pm_string_constant_init(pm_string_t *string, const char *source, size_t length);
|
94
98
|
|
99
|
+
/**
|
100
|
+
* Represents the result of calling pm_string_mapped_init or
|
101
|
+
* pm_string_file_init. We need this additional information because there is
|
102
|
+
* not a platform-agnostic way to indicate that the file that was attempted to
|
103
|
+
* be opened was a directory.
|
104
|
+
*/
|
105
|
+
typedef enum {
|
106
|
+
/** Indicates that the string was successfully initialized. */
|
107
|
+
PM_STRING_INIT_SUCCESS = 0,
|
108
|
+
/**
|
109
|
+
* Indicates a generic error from a string_*_init function, where the type
|
110
|
+
* of error should be read from `errno` or `GetLastError()`.
|
111
|
+
*/
|
112
|
+
PM_STRING_INIT_ERROR_GENERIC = 1,
|
113
|
+
/**
|
114
|
+
* Indicates that the file that was attempted to be opened was a directory.
|
115
|
+
*/
|
116
|
+
PM_STRING_INIT_ERROR_DIRECTORY = 2
|
117
|
+
} pm_string_init_result_t;
|
118
|
+
|
95
119
|
/**
|
96
120
|
* Read the file indicated by the filepath parameter into source and load its
|
97
121
|
* contents and size into the given `pm_string_t`. The given `pm_string_t`
|
@@ -105,9 +129,9 @@ void pm_string_constant_init(pm_string_t *string, const char *source, size_t len
|
|
105
129
|
*
|
106
130
|
* @param string The string to initialize.
|
107
131
|
* @param filepath The filepath to read.
|
108
|
-
* @return
|
132
|
+
* @return The success of the read, indicated by the value of the enum.
|
109
133
|
*/
|
110
|
-
PRISM_EXPORTED_FUNCTION
|
134
|
+
PRISM_EXPORTED_FUNCTION pm_string_init_result_t pm_string_mapped_init(pm_string_t *string, const char *filepath);
|
111
135
|
|
112
136
|
/**
|
113
137
|
* Read the file indicated by the filepath parameter into source and load its
|
@@ -116,17 +140,9 @@ PRISM_EXPORTED_FUNCTION bool pm_string_mapped_init(pm_string_t *string, const ch
|
|
116
140
|
*
|
117
141
|
* @param string The string to initialize.
|
118
142
|
* @param filepath The filepath to read.
|
119
|
-
* @return
|
120
|
-
*/
|
121
|
-
PRISM_EXPORTED_FUNCTION bool pm_string_file_init(pm_string_t *string, const char *filepath);
|
122
|
-
|
123
|
-
/**
|
124
|
-
* Returns the memory size associated with the string.
|
125
|
-
*
|
126
|
-
* @param string The string to get the memory size of.
|
127
|
-
* @return The size of the memory associated with the string.
|
143
|
+
* @return The success of the read, indicated by the value of the enum.
|
128
144
|
*/
|
129
|
-
|
145
|
+
PRISM_EXPORTED_FUNCTION pm_string_init_result_t pm_string_file_init(pm_string_t *string, const char *filepath);
|
130
146
|
|
131
147
|
/**
|
132
148
|
* Ensure the string is owned. If it is not, then reinitialize it as owned and
|
data/include/prism/version.h
CHANGED
@@ -9,12 +9,12 @@
|
|
9
9
|
/**
|
10
10
|
* The major version of the Prism library as an int.
|
11
11
|
*/
|
12
|
-
#define PRISM_VERSION_MAJOR
|
12
|
+
#define PRISM_VERSION_MAJOR 1
|
13
13
|
|
14
14
|
/**
|
15
15
|
* The minor version of the Prism library as an int.
|
16
16
|
*/
|
17
|
-
#define PRISM_VERSION_MINOR
|
17
|
+
#define PRISM_VERSION_MINOR 3
|
18
18
|
|
19
19
|
/**
|
20
20
|
* The patch version of the Prism library as an int.
|
@@ -24,6 +24,6 @@
|
|
24
24
|
/**
|
25
25
|
* The version of the Prism library as a constant string.
|
26
26
|
*/
|
27
|
-
#define PRISM_VERSION "
|
27
|
+
#define PRISM_VERSION "1.3.0"
|
28
28
|
|
29
29
|
#endif
|
data/include/prism.h
CHANGED
@@ -219,17 +219,6 @@ PRISM_EXPORTED_FUNCTION const char * pm_token_type_name(pm_token_type_t token_ty
|
|
219
219
|
*/
|
220
220
|
const char * pm_token_type_human(pm_token_type_t token_type);
|
221
221
|
|
222
|
-
/**
|
223
|
-
* Format the errors on the parser into the given buffer.
|
224
|
-
*
|
225
|
-
* @param parser The parser to format the errors for.
|
226
|
-
* @param error_list The list of errors to format.
|
227
|
-
* @param buffer The buffer to format the errors into.
|
228
|
-
* @param colorize Whether or not to colorize the errors with ANSI escape sequences.
|
229
|
-
* @param inline_messages Whether or not to inline the messages with the source.
|
230
|
-
*/
|
231
|
-
PRISM_EXPORTED_FUNCTION void pm_parser_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, pm_buffer_t *buffer, bool colorize, bool inline_messages);
|
232
|
-
|
233
222
|
// We optionally support dumping to JSON. For systems that don't want or need
|
234
223
|
// this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define.
|
235
224
|
#ifndef PRISM_EXCLUDE_JSON
|
@@ -245,6 +234,53 @@ PRISM_EXPORTED_FUNCTION void pm_dump_json(pm_buffer_t *buffer, const pm_parser_t
|
|
245
234
|
|
246
235
|
#endif
|
247
236
|
|
237
|
+
/**
|
238
|
+
* Represents the results of a slice query.
|
239
|
+
*/
|
240
|
+
typedef enum {
|
241
|
+
/** Returned if the encoding given to a slice query was invalid. */
|
242
|
+
PM_STRING_QUERY_ERROR = -1,
|
243
|
+
|
244
|
+
/** Returned if the result of the slice query is false. */
|
245
|
+
PM_STRING_QUERY_FALSE,
|
246
|
+
|
247
|
+
/** Returned if the result of the slice query is true. */
|
248
|
+
PM_STRING_QUERY_TRUE
|
249
|
+
} pm_string_query_t;
|
250
|
+
|
251
|
+
/**
|
252
|
+
* Check that the slice is a valid local variable name.
|
253
|
+
*
|
254
|
+
* @param source The source to check.
|
255
|
+
* @param length The length of the source.
|
256
|
+
* @param encoding_name The name of the encoding of the source.
|
257
|
+
* @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
|
258
|
+
* the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
|
259
|
+
*/
|
260
|
+
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_local(const uint8_t *source, size_t length, const char *encoding_name);
|
261
|
+
|
262
|
+
/**
|
263
|
+
* Check that the slice is a valid constant name.
|
264
|
+
*
|
265
|
+
* @param source The source to check.
|
266
|
+
* @param length The length of the source.
|
267
|
+
* @param encoding_name The name of the encoding of the source.
|
268
|
+
* @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
|
269
|
+
* the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
|
270
|
+
*/
|
271
|
+
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_constant(const uint8_t *source, size_t length, const char *encoding_name);
|
272
|
+
|
273
|
+
/**
|
274
|
+
* Check that the slice is a valid method name.
|
275
|
+
*
|
276
|
+
* @param source The source to check.
|
277
|
+
* @param length The length of the source.
|
278
|
+
* @param encoding_name The name of the encoding of the source.
|
279
|
+
* @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
|
280
|
+
* the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
|
281
|
+
*/
|
282
|
+
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_method_name(const uint8_t *source, size_t length, const char *encoding_name);
|
283
|
+
|
248
284
|
/**
|
249
285
|
* @mainpage
|
250
286
|
*
|
data/lib/prism/compiler.rb
CHANGED
@@ -301,6 +301,9 @@ module Prism
|
|
301
301
|
# Compile a InterpolatedXStringNode node
|
302
302
|
alias visit_interpolated_x_string_node visit_child_nodes
|
303
303
|
|
304
|
+
# Compile a ItLocalVariableReadNode node
|
305
|
+
alias visit_it_local_variable_read_node visit_child_nodes
|
306
|
+
|
304
307
|
# Compile a ItParametersNode node
|
305
308
|
alias visit_it_parameters_node visit_child_nodes
|
306
309
|
|
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
module Prism
|
4
4
|
class DesugarAndWriteNode # :nodoc:
|
5
|
-
|
5
|
+
include DSL
|
6
6
|
|
7
|
-
|
7
|
+
attr_reader :node, :default_source, :read_class, :write_class, :arguments
|
8
|
+
|
9
|
+
def initialize(node, default_source, read_class, write_class, **arguments)
|
8
10
|
@node = node
|
9
|
-
@
|
11
|
+
@default_source = default_source
|
10
12
|
@read_class = read_class
|
11
13
|
@write_class = write_class
|
12
14
|
@arguments = arguments
|
@@ -14,22 +16,30 @@ module Prism
|
|
14
16
|
|
15
17
|
# Desugar `x &&= y` to `x && x = y`
|
16
18
|
def compile
|
17
|
-
|
18
|
-
|
19
|
-
read_class
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
and_node(
|
20
|
+
location: node.location,
|
21
|
+
left: public_send(read_class, location: node.name_loc, **arguments),
|
22
|
+
right: public_send(
|
23
|
+
write_class,
|
24
|
+
location: node.location,
|
25
|
+
**arguments,
|
26
|
+
name_loc: node.name_loc,
|
27
|
+
value: node.value,
|
28
|
+
operator_loc: node.operator_loc
|
29
|
+
),
|
30
|
+
operator_loc: node.operator_loc
|
23
31
|
)
|
24
32
|
end
|
25
33
|
end
|
26
34
|
|
27
35
|
class DesugarOrWriteDefinedNode # :nodoc:
|
28
|
-
|
36
|
+
include DSL
|
37
|
+
|
38
|
+
attr_reader :node, :default_source, :read_class, :write_class, :arguments
|
29
39
|
|
30
|
-
def initialize(node,
|
40
|
+
def initialize(node, default_source, read_class, write_class, **arguments)
|
31
41
|
@node = node
|
32
|
-
@
|
42
|
+
@default_source = default_source
|
33
43
|
@read_class = read_class
|
34
44
|
@write_class = write_class
|
35
45
|
@arguments = arguments
|
@@ -37,35 +47,50 @@ module Prism
|
|
37
47
|
|
38
48
|
# Desugar `x ||= y` to `defined?(x) ? x : x = y`
|
39
49
|
def compile
|
40
|
-
|
41
|
-
|
42
|
-
node.operator_loc,
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
if_node(
|
51
|
+
location: node.location,
|
52
|
+
if_keyword_loc: node.operator_loc,
|
53
|
+
predicate: defined_node(
|
54
|
+
location: node.name_loc,
|
55
|
+
value: public_send(read_class, location: node.name_loc, **arguments),
|
56
|
+
keyword_loc: node.operator_loc
|
57
|
+
),
|
58
|
+
then_keyword_loc: node.operator_loc,
|
59
|
+
statements: statements_node(
|
60
|
+
location: node.location,
|
61
|
+
body: [public_send(read_class, location: node.name_loc, **arguments)]
|
62
|
+
),
|
63
|
+
subsequent: else_node(
|
64
|
+
location: node.location,
|
65
|
+
else_keyword_loc: node.operator_loc,
|
66
|
+
statements: statements_node(
|
67
|
+
location: node.location,
|
68
|
+
body: [
|
69
|
+
public_send(
|
70
|
+
write_class,
|
71
|
+
location: node.location,
|
72
|
+
**arguments,
|
73
|
+
name_loc: node.name_loc,
|
74
|
+
value: node.value,
|
75
|
+
operator_loc: node.operator_loc
|
76
|
+
)
|
77
|
+
]
|
53
78
|
),
|
54
|
-
node.operator_loc
|
55
|
-
node.location
|
79
|
+
end_keyword_loc: node.operator_loc
|
56
80
|
),
|
57
|
-
node.operator_loc
|
58
|
-
node.location
|
81
|
+
end_keyword_loc: node.operator_loc
|
59
82
|
)
|
60
83
|
end
|
61
84
|
end
|
62
85
|
|
63
86
|
class DesugarOperatorWriteNode # :nodoc:
|
64
|
-
|
87
|
+
include DSL
|
65
88
|
|
66
|
-
|
89
|
+
attr_reader :node, :default_source, :read_class, :write_class, :arguments
|
90
|
+
|
91
|
+
def initialize(node, default_source, read_class, write_class, **arguments)
|
67
92
|
@node = node
|
68
|
-
@
|
93
|
+
@default_source = default_source
|
69
94
|
@read_class = read_class
|
70
95
|
@write_class = write_class
|
71
96
|
@arguments = arguments
|
@@ -75,35 +100,41 @@ module Prism
|
|
75
100
|
def compile
|
76
101
|
binary_operator_loc = node.binary_operator_loc.chop
|
77
102
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
103
|
+
public_send(
|
104
|
+
write_class,
|
105
|
+
location: node.location,
|
106
|
+
**arguments,
|
107
|
+
name_loc: node.name_loc,
|
108
|
+
value: call_node(
|
109
|
+
location: node.location,
|
110
|
+
receiver: public_send(
|
111
|
+
read_class,
|
112
|
+
location: node.name_loc,
|
113
|
+
**arguments
|
114
|
+
),
|
115
|
+
name: binary_operator_loc.slice.to_sym,
|
116
|
+
message_loc: binary_operator_loc,
|
117
|
+
arguments: arguments_node(
|
118
|
+
location: node.value.location,
|
119
|
+
arguments: [node.value]
|
120
|
+
)
|
94
121
|
),
|
95
|
-
node.binary_operator_loc.copy(
|
96
|
-
|
122
|
+
operator_loc: node.binary_operator_loc.copy(
|
123
|
+
start_offset: node.binary_operator_loc.end_offset - 1,
|
124
|
+
length: 1
|
125
|
+
)
|
97
126
|
)
|
98
127
|
end
|
99
128
|
end
|
100
129
|
|
101
130
|
class DesugarOrWriteNode # :nodoc:
|
102
|
-
|
131
|
+
include DSL
|
103
132
|
|
104
|
-
|
133
|
+
attr_reader :node, :default_source, :read_class, :write_class, :arguments
|
134
|
+
|
135
|
+
def initialize(node, default_source, read_class, write_class, **arguments)
|
105
136
|
@node = node
|
106
|
-
@
|
137
|
+
@default_source = default_source
|
107
138
|
@read_class = read_class
|
108
139
|
@write_class = write_class
|
109
140
|
@arguments = arguments
|
@@ -111,12 +142,18 @@ module Prism
|
|
111
142
|
|
112
143
|
# Desugar `x ||= y` to `x || x = y`
|
113
144
|
def compile
|
114
|
-
|
115
|
-
|
116
|
-
read_class
|
117
|
-
|
118
|
-
|
119
|
-
|
145
|
+
or_node(
|
146
|
+
location: node.location,
|
147
|
+
left: public_send(read_class, location: node.name_loc, **arguments),
|
148
|
+
right: public_send(
|
149
|
+
write_class,
|
150
|
+
location: node.location,
|
151
|
+
**arguments,
|
152
|
+
name_loc: node.name_loc,
|
153
|
+
value: node.value,
|
154
|
+
operator_loc: node.operator_loc
|
155
|
+
),
|
156
|
+
operator_loc: node.operator_loc
|
120
157
|
)
|
121
158
|
end
|
122
159
|
end
|
@@ -125,91 +162,91 @@ module Prism
|
|
125
162
|
|
126
163
|
class ClassVariableAndWriteNode
|
127
164
|
def desugar # :nodoc:
|
128
|
-
DesugarAndWriteNode.new(self, source,
|
165
|
+
DesugarAndWriteNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile
|
129
166
|
end
|
130
167
|
end
|
131
168
|
|
132
169
|
class ClassVariableOrWriteNode
|
133
170
|
def desugar # :nodoc:
|
134
|
-
DesugarOrWriteDefinedNode.new(self, source,
|
171
|
+
DesugarOrWriteDefinedNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile
|
135
172
|
end
|
136
173
|
end
|
137
174
|
|
138
175
|
class ClassVariableOperatorWriteNode
|
139
176
|
def desugar # :nodoc:
|
140
|
-
DesugarOperatorWriteNode.new(self, source,
|
177
|
+
DesugarOperatorWriteNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile
|
141
178
|
end
|
142
179
|
end
|
143
180
|
|
144
181
|
class ConstantAndWriteNode
|
145
182
|
def desugar # :nodoc:
|
146
|
-
DesugarAndWriteNode.new(self, source,
|
183
|
+
DesugarAndWriteNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile
|
147
184
|
end
|
148
185
|
end
|
149
186
|
|
150
187
|
class ConstantOrWriteNode
|
151
188
|
def desugar # :nodoc:
|
152
|
-
DesugarOrWriteDefinedNode.new(self, source,
|
189
|
+
DesugarOrWriteDefinedNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile
|
153
190
|
end
|
154
191
|
end
|
155
192
|
|
156
193
|
class ConstantOperatorWriteNode
|
157
194
|
def desugar # :nodoc:
|
158
|
-
DesugarOperatorWriteNode.new(self, source,
|
195
|
+
DesugarOperatorWriteNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile
|
159
196
|
end
|
160
197
|
end
|
161
198
|
|
162
199
|
class GlobalVariableAndWriteNode
|
163
200
|
def desugar # :nodoc:
|
164
|
-
DesugarAndWriteNode.new(self, source,
|
201
|
+
DesugarAndWriteNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile
|
165
202
|
end
|
166
203
|
end
|
167
204
|
|
168
205
|
class GlobalVariableOrWriteNode
|
169
206
|
def desugar # :nodoc:
|
170
|
-
DesugarOrWriteDefinedNode.new(self, source,
|
207
|
+
DesugarOrWriteDefinedNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile
|
171
208
|
end
|
172
209
|
end
|
173
210
|
|
174
211
|
class GlobalVariableOperatorWriteNode
|
175
212
|
def desugar # :nodoc:
|
176
|
-
DesugarOperatorWriteNode.new(self, source,
|
213
|
+
DesugarOperatorWriteNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile
|
177
214
|
end
|
178
215
|
end
|
179
216
|
|
180
217
|
class InstanceVariableAndWriteNode
|
181
218
|
def desugar # :nodoc:
|
182
|
-
DesugarAndWriteNode.new(self, source,
|
219
|
+
DesugarAndWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile
|
183
220
|
end
|
184
221
|
end
|
185
222
|
|
186
223
|
class InstanceVariableOrWriteNode
|
187
224
|
def desugar # :nodoc:
|
188
|
-
DesugarOrWriteNode.new(self, source,
|
225
|
+
DesugarOrWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile
|
189
226
|
end
|
190
227
|
end
|
191
228
|
|
192
229
|
class InstanceVariableOperatorWriteNode
|
193
230
|
def desugar # :nodoc:
|
194
|
-
DesugarOperatorWriteNode.new(self, source,
|
231
|
+
DesugarOperatorWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile
|
195
232
|
end
|
196
233
|
end
|
197
234
|
|
198
235
|
class LocalVariableAndWriteNode
|
199
236
|
def desugar # :nodoc:
|
200
|
-
DesugarAndWriteNode.new(self, source,
|
237
|
+
DesugarAndWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile
|
201
238
|
end
|
202
239
|
end
|
203
240
|
|
204
241
|
class LocalVariableOrWriteNode
|
205
242
|
def desugar # :nodoc:
|
206
|
-
DesugarOrWriteNode.new(self, source,
|
243
|
+
DesugarOrWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile
|
207
244
|
end
|
208
245
|
end
|
209
246
|
|
210
247
|
class LocalVariableOperatorWriteNode
|
211
248
|
def desugar # :nodoc:
|
212
|
-
DesugarOperatorWriteNode.new(self, source,
|
249
|
+
DesugarOperatorWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile
|
213
250
|
end
|
214
251
|
end
|
215
252
|
|