prism 0.22.0 → 0.24.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 +39 -1
- data/README.md +2 -1
- data/docs/releasing.md +67 -17
- data/docs/ruby_parser_translation.md +19 -0
- data/docs/serialization.md +2 -0
- data/ext/prism/api_node.c +1982 -1538
- data/ext/prism/extension.c +12 -7
- data/ext/prism/extension.h +2 -2
- data/include/prism/diagnostic.h +3 -4
- data/include/prism/encoding.h +7 -0
- data/include/prism/util/pm_constant_pool.h +1 -1
- data/include/prism/util/pm_newline_list.h +4 -3
- data/include/prism/util/pm_strpbrk.h +4 -1
- data/include/prism/version.h +2 -2
- data/lib/prism/desugar_compiler.rb +225 -80
- data/lib/prism/dsl.rb +302 -299
- data/lib/prism/ffi.rb +103 -77
- data/lib/prism/lex_compat.rb +1 -0
- data/lib/prism/node.rb +3624 -2114
- data/lib/prism/node_ext.rb +25 -2
- data/lib/prism/parse_result.rb +56 -19
- data/lib/prism/serialize.rb +605 -303
- data/lib/prism/translation/parser/compiler.rb +1 -1
- data/lib/prism/translation/parser/rubocop.rb +11 -3
- data/lib/prism/translation/parser.rb +25 -12
- data/lib/prism/translation/parser33.rb +12 -0
- data/lib/prism/translation/parser34.rb +12 -0
- data/lib/prism/translation/ripper.rb +696 -0
- data/lib/prism/translation/ruby_parser.rb +1521 -0
- data/lib/prism/translation.rb +3 -3
- data/lib/prism.rb +0 -1
- data/prism.gemspec +6 -2
- data/src/diagnostic.c +10 -11
- data/src/encoding.c +16 -17
- data/src/options.c +7 -2
- data/src/prettyprint.c +3 -3
- data/src/prism.c +172 -97
- data/src/serialize.c +24 -13
- data/src/token_type.c +3 -3
- data/src/util/pm_constant_pool.c +1 -1
- data/src/util/pm_newline_list.c +6 -3
- data/src/util/pm_strpbrk.c +122 -14
- metadata +8 -4
- data/lib/prism/ripper_compat.rb +0 -285
data/ext/prism/extension.c
CHANGED
@@ -542,8 +542,9 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
|
|
542
542
|
pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
|
543
543
|
pm_parser_register_encoding_changed_callback(&parser, parse_lex_encoding_changed_callback);
|
544
544
|
|
545
|
+
VALUE source_string = rb_str_new((const char *) pm_string_source(input), pm_string_length(input));
|
545
546
|
VALUE offsets = rb_ary_new();
|
546
|
-
VALUE source_argv[] = {
|
547
|
+
VALUE source_argv[] = { source_string, LONG2NUM(parser.start_line), offsets };
|
547
548
|
VALUE source = rb_class_new_instance(3, source_argv, rb_cPrismSource);
|
548
549
|
|
549
550
|
parse_lex_data_t parse_lex_data = {
|
@@ -561,17 +562,21 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
|
|
561
562
|
parser.lex_callback = &lex_callback;
|
562
563
|
pm_node_t *node = pm_parse(&parser);
|
563
564
|
|
564
|
-
// Here we need to update the
|
565
|
-
//
|
566
|
-
// it
|
565
|
+
// Here we need to update the Source object to have the correct
|
566
|
+
// encoding for the source string and the correct newline offsets.
|
567
|
+
// We do it here because we've already created the Source object and given
|
568
|
+
// it over to all of the tokens, and both of these are only set after pm_parse().
|
569
|
+
rb_encoding *encoding = rb_enc_find(parser.encoding->name);
|
570
|
+
rb_enc_associate(source_string, encoding);
|
571
|
+
|
567
572
|
for (size_t index = 0; index < parser.newline_list.size; index++) {
|
568
|
-
rb_ary_push(offsets,
|
573
|
+
rb_ary_push(offsets, ULONG2NUM(parser.newline_list.offsets[index]));
|
569
574
|
}
|
570
575
|
|
571
576
|
VALUE value;
|
572
577
|
if (return_nodes) {
|
573
578
|
value = rb_ary_new_capa(2);
|
574
|
-
rb_ary_push(value, pm_ast_new(&parser, node, parse_lex_data.encoding));
|
579
|
+
rb_ary_push(value, pm_ast_new(&parser, node, parse_lex_data.encoding, source));
|
575
580
|
rb_ary_push(value, parse_lex_data.tokens);
|
576
581
|
} else {
|
577
582
|
value = parse_lex_data.tokens;
|
@@ -650,7 +655,7 @@ parse_input(pm_string_t *input, const pm_options_t *options) {
|
|
650
655
|
|
651
656
|
VALUE source = pm_source_new(&parser, encoding);
|
652
657
|
VALUE result_argv[] = {
|
653
|
-
pm_ast_new(&parser, node, encoding),
|
658
|
+
pm_ast_new(&parser, node, encoding, source),
|
654
659
|
parser_comments(&parser, source),
|
655
660
|
parser_magic_comments(&parser, source),
|
656
661
|
parser_data_loc(&parser, source),
|
data/ext/prism/extension.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#ifndef PRISM_EXT_NODE_H
|
2
2
|
#define PRISM_EXT_NODE_H
|
3
3
|
|
4
|
-
#define EXPECTED_PRISM_VERSION "0.
|
4
|
+
#define EXPECTED_PRISM_VERSION "0.24.0"
|
5
5
|
|
6
6
|
#include <ruby.h>
|
7
7
|
#include <ruby/encoding.h>
|
@@ -9,7 +9,7 @@
|
|
9
9
|
|
10
10
|
VALUE pm_source_new(pm_parser_t *parser, rb_encoding *encoding);
|
11
11
|
VALUE pm_token_new(pm_parser_t *parser, pm_token_t *token, rb_encoding *encoding, VALUE source);
|
12
|
-
VALUE pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding);
|
12
|
+
VALUE pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding, VALUE source);
|
13
13
|
|
14
14
|
void Init_prism_api_node(void);
|
15
15
|
void Init_prism_pack(void);
|
data/include/prism/diagnostic.h
CHANGED
@@ -219,6 +219,7 @@ typedef enum {
|
|
219
219
|
PM_ERR_MODULE_NAME,
|
220
220
|
PM_ERR_MODULE_TERM,
|
221
221
|
PM_ERR_MULTI_ASSIGN_MULTI_SPLATS,
|
222
|
+
PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST,
|
222
223
|
PM_ERR_NOT_EXPRESSION,
|
223
224
|
PM_ERR_NO_LOCAL_VARIABLE,
|
224
225
|
PM_ERR_NUMBER_LITERAL_UNDERSCORE,
|
@@ -272,6 +273,7 @@ typedef enum {
|
|
272
273
|
PM_ERR_STATEMENT_UNDEF,
|
273
274
|
PM_ERR_STRING_CONCATENATION,
|
274
275
|
PM_ERR_STRING_INTERPOLATED_TERM,
|
276
|
+
PM_ERR_STRING_LITERAL_EOF,
|
275
277
|
PM_ERR_STRING_LITERAL_TERM,
|
276
278
|
PM_ERR_SYMBOL_INVALID,
|
277
279
|
PM_ERR_SYMBOL_TERM_DYNAMIC,
|
@@ -279,10 +281,7 @@ typedef enum {
|
|
279
281
|
PM_ERR_TERNARY_COLON,
|
280
282
|
PM_ERR_TERNARY_EXPRESSION_FALSE,
|
281
283
|
PM_ERR_TERNARY_EXPRESSION_TRUE,
|
282
|
-
|
283
|
-
PM_ERR_UNARY_RECEIVER_MINUS,
|
284
|
-
PM_ERR_UNARY_RECEIVER_PLUS,
|
285
|
-
PM_ERR_UNARY_RECEIVER_TILDE,
|
284
|
+
PM_ERR_UNARY_RECEIVER,
|
286
285
|
PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT,
|
287
286
|
PM_ERR_UNEXPECTED_TOKEN_IGNORE,
|
288
287
|
PM_ERR_UNDEF_ARGUMENT,
|
data/include/prism/encoding.h
CHANGED
@@ -245,6 +245,13 @@ extern const pm_encoding_t pm_encodings[PM_ENCODING_MAXIMUM];
|
|
245
245
|
*/
|
246
246
|
#define PM_ENCODING_US_ASCII_ENTRY (&pm_encodings[PM_ENCODING_US_ASCII])
|
247
247
|
|
248
|
+
/**
|
249
|
+
* This is the ASCII-8BIT encoding. We need a reference to it so that pm_strpbrk
|
250
|
+
* can compare against it because invalid multibyte characters are not a thing
|
251
|
+
* in this encoding.
|
252
|
+
*/
|
253
|
+
#define PM_ENCODING_ASCII_8BIT_ENTRY (&pm_encodings[PM_ENCODING_ASCII_8BIT])
|
254
|
+
|
248
255
|
/**
|
249
256
|
* Parse the given name of an encoding and return a pointer to the corresponding
|
250
257
|
* encoding struct if one can be found, otherwise return NULL.
|
@@ -163,7 +163,7 @@ pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool,
|
|
163
163
|
* @param length The length of the constant.
|
164
164
|
* @return The id of the constant.
|
165
165
|
*/
|
166
|
-
pm_constant_id_t pm_constant_pool_find(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
|
166
|
+
pm_constant_id_t pm_constant_pool_find(const pm_constant_pool_t *pool, const uint8_t *start, size_t length);
|
167
167
|
|
168
168
|
/**
|
169
169
|
* Insert a constant into a constant pool that is a slice of a source string.
|
@@ -44,10 +44,10 @@ typedef struct {
|
|
44
44
|
*/
|
45
45
|
typedef struct {
|
46
46
|
/** The line number. */
|
47
|
-
|
47
|
+
int32_t line;
|
48
48
|
|
49
49
|
/** The column number. */
|
50
|
-
|
50
|
+
uint32_t column;
|
51
51
|
} pm_line_column_t;
|
52
52
|
|
53
53
|
/**
|
@@ -79,9 +79,10 @@ bool pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor);
|
|
79
79
|
*
|
80
80
|
* @param list The list to search.
|
81
81
|
* @param cursor A pointer to the offset to search for.
|
82
|
+
* @param start_line The line to start counting from.
|
82
83
|
* @return The line and column of the given offset.
|
83
84
|
*/
|
84
|
-
pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor);
|
85
|
+
pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line);
|
85
86
|
|
86
87
|
/**
|
87
88
|
* Free the internal memory allocated for the newline list.
|
@@ -7,6 +7,7 @@
|
|
7
7
|
#define PRISM_STRPBRK_H
|
8
8
|
|
9
9
|
#include "prism/defines.h"
|
10
|
+
#include "prism/diagnostic.h"
|
10
11
|
#include "prism/parser.h"
|
11
12
|
|
12
13
|
#include <stddef.h>
|
@@ -35,9 +36,11 @@
|
|
35
36
|
* @param source The source to search.
|
36
37
|
* @param charset The charset to search for.
|
37
38
|
* @param length The maximum number of bytes to search.
|
39
|
+
* @param validate Whether to validate that the source string is valid in the
|
40
|
+
* current encoding of the parser.
|
38
41
|
* @return A pointer to the first character in the source string that is in the
|
39
42
|
* charset, or NULL if no such character exists.
|
40
43
|
*/
|
41
|
-
const uint8_t * pm_strpbrk(
|
44
|
+
const uint8_t * pm_strpbrk(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length, bool validate);
|
42
45
|
|
43
46
|
#endif
|
data/include/prism/version.h
CHANGED
@@ -14,7 +14,7 @@
|
|
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 24
|
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 "0.
|
27
|
+
#define PRISM_VERSION "0.24.0"
|
28
28
|
|
29
29
|
#endif
|
@@ -1,6 +1,216 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Prism
|
4
|
+
class DesugarAndWriteNode # :nodoc:
|
5
|
+
attr_reader :node, :source, :read_class, :write_class, :arguments
|
6
|
+
|
7
|
+
def initialize(node, source, read_class, write_class, *arguments)
|
8
|
+
@node = node
|
9
|
+
@source = source
|
10
|
+
@read_class = read_class
|
11
|
+
@write_class = write_class
|
12
|
+
@arguments = arguments
|
13
|
+
end
|
14
|
+
|
15
|
+
# Desugar `x &&= y` to `x && x = y`
|
16
|
+
def compile
|
17
|
+
AndNode.new(
|
18
|
+
source,
|
19
|
+
read_class.new(source, *arguments, node.name_loc),
|
20
|
+
write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location),
|
21
|
+
node.operator_loc,
|
22
|
+
node.location
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class DesugarOrWriteDefinedNode # :nodoc:
|
28
|
+
attr_reader :node, :source, :read_class, :write_class, :arguments
|
29
|
+
|
30
|
+
def initialize(node, source, read_class, write_class, *arguments)
|
31
|
+
@node = node
|
32
|
+
@source = source
|
33
|
+
@read_class = read_class
|
34
|
+
@write_class = write_class
|
35
|
+
@arguments = arguments
|
36
|
+
end
|
37
|
+
|
38
|
+
# Desugar `x ||= y` to `defined?(x) ? x : x = y`
|
39
|
+
def compile
|
40
|
+
IfNode.new(
|
41
|
+
source,
|
42
|
+
node.operator_loc,
|
43
|
+
DefinedNode.new(source, nil, read_class.new(source, *arguments, node.name_loc), nil, node.operator_loc, node.name_loc),
|
44
|
+
node.operator_loc,
|
45
|
+
StatementsNode.new(source, [read_class.new(source, *arguments, node.name_loc)], node.location),
|
46
|
+
ElseNode.new(
|
47
|
+
source,
|
48
|
+
node.operator_loc,
|
49
|
+
StatementsNode.new(
|
50
|
+
source,
|
51
|
+
[write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location)],
|
52
|
+
node.location
|
53
|
+
),
|
54
|
+
node.operator_loc,
|
55
|
+
node.location
|
56
|
+
),
|
57
|
+
node.operator_loc,
|
58
|
+
node.location
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class DesugarOperatorWriteNode # :nodoc:
|
64
|
+
attr_reader :node, :source, :read_class, :write_class, :arguments
|
65
|
+
|
66
|
+
def initialize(node, source, read_class, write_class, *arguments)
|
67
|
+
@node = node
|
68
|
+
@source = source
|
69
|
+
@read_class = read_class
|
70
|
+
@write_class = write_class
|
71
|
+
@arguments = arguments
|
72
|
+
end
|
73
|
+
|
74
|
+
# Desugar `x += y` to `x = x + y`
|
75
|
+
def compile
|
76
|
+
write_class.new(
|
77
|
+
source,
|
78
|
+
*arguments,
|
79
|
+
node.name_loc,
|
80
|
+
CallNode.new(
|
81
|
+
source,
|
82
|
+
0,
|
83
|
+
read_class.new(source, *arguments, node.name_loc),
|
84
|
+
nil,
|
85
|
+
node.operator_loc.slice.chomp("="),
|
86
|
+
node.operator_loc.copy(length: node.operator_loc.length - 1),
|
87
|
+
nil,
|
88
|
+
ArgumentsNode.new(source, 0, [node.value], node.value.location),
|
89
|
+
nil,
|
90
|
+
nil,
|
91
|
+
node.location
|
92
|
+
),
|
93
|
+
node.operator_loc.copy(start_offset: node.operator_loc.end_offset - 1, length: 1),
|
94
|
+
node.location
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class DesugarOrWriteNode # :nodoc:
|
100
|
+
attr_reader :node, :source, :read_class, :write_class, :arguments
|
101
|
+
|
102
|
+
def initialize(node, source, read_class, write_class, *arguments)
|
103
|
+
@node = node
|
104
|
+
@source = source
|
105
|
+
@read_class = read_class
|
106
|
+
@write_class = write_class
|
107
|
+
@arguments = arguments
|
108
|
+
end
|
109
|
+
|
110
|
+
# Desugar `x ||= y` to `x || x = y`
|
111
|
+
def compile
|
112
|
+
OrNode.new(
|
113
|
+
source,
|
114
|
+
read_class.new(source, *arguments, node.name_loc),
|
115
|
+
write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location),
|
116
|
+
node.operator_loc,
|
117
|
+
node.location
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private_constant :DesugarAndWriteNode, :DesugarOrWriteNode, :DesugarOrWriteDefinedNode, :DesugarOperatorWriteNode
|
123
|
+
|
124
|
+
class ClassVariableAndWriteNode
|
125
|
+
def desugar # :nodoc:
|
126
|
+
DesugarAndWriteNode.new(self, source, ClassVariableReadNode, ClassVariableWriteNode, name).compile
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class ClassVariableOrWriteNode
|
131
|
+
def desugar # :nodoc:
|
132
|
+
DesugarOrWriteDefinedNode.new(self, source, ClassVariableReadNode, ClassVariableWriteNode, name).compile
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class ClassVariableOperatorWriteNode
|
137
|
+
def desugar # :nodoc:
|
138
|
+
DesugarOperatorWriteNode.new(self, source, ClassVariableReadNode, ClassVariableWriteNode, name).compile
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class ConstantAndWriteNode
|
143
|
+
def desugar # :nodoc:
|
144
|
+
DesugarAndWriteNode.new(self, source, ConstantReadNode, ConstantWriteNode, name).compile
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class ConstantOrWriteNode
|
149
|
+
def desugar # :nodoc:
|
150
|
+
DesugarOrWriteDefinedNode.new(self, source, ConstantReadNode, ConstantWriteNode, name).compile
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class ConstantOperatorWriteNode
|
155
|
+
def desugar # :nodoc:
|
156
|
+
DesugarOperatorWriteNode.new(self, source, ConstantReadNode, ConstantWriteNode, name).compile
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class GlobalVariableAndWriteNode
|
161
|
+
def desugar # :nodoc:
|
162
|
+
DesugarAndWriteNode.new(self, source, GlobalVariableReadNode, GlobalVariableWriteNode, name).compile
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class GlobalVariableOrWriteNode
|
167
|
+
def desugar # :nodoc:
|
168
|
+
DesugarOrWriteDefinedNode.new(self, source, GlobalVariableReadNode, GlobalVariableWriteNode, name).compile
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class GlobalVariableOperatorWriteNode
|
173
|
+
def desugar # :nodoc:
|
174
|
+
DesugarOperatorWriteNode.new(self, source, GlobalVariableReadNode, GlobalVariableWriteNode, name).compile
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class InstanceVariableAndWriteNode
|
179
|
+
def desugar # :nodoc:
|
180
|
+
DesugarAndWriteNode.new(self, source, InstanceVariableReadNode, InstanceVariableWriteNode, name).compile
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class InstanceVariableOrWriteNode
|
185
|
+
def desugar # :nodoc:
|
186
|
+
DesugarOrWriteNode.new(self, source, InstanceVariableReadNode, InstanceVariableWriteNode, name).compile
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class InstanceVariableOperatorWriteNode
|
191
|
+
def desugar # :nodoc:
|
192
|
+
DesugarOperatorWriteNode.new(self, source, InstanceVariableReadNode, InstanceVariableWriteNode, name).compile
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class LocalVariableAndWriteNode
|
197
|
+
def desugar # :nodoc:
|
198
|
+
DesugarAndWriteNode.new(self, source, LocalVariableReadNode, LocalVariableWriteNode, name, depth).compile
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class LocalVariableOrWriteNode
|
203
|
+
def desugar # :nodoc:
|
204
|
+
DesugarOrWriteNode.new(self, source, LocalVariableReadNode, LocalVariableWriteNode, name, depth).compile
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
class LocalVariableOperatorWriteNode
|
209
|
+
def desugar # :nodoc:
|
210
|
+
DesugarOperatorWriteNode.new(self, source, LocalVariableReadNode, LocalVariableWriteNode, name, depth).compile
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
4
214
|
# DesugarCompiler is a compiler that desugars Ruby code into a more primitive
|
5
215
|
# form. This is useful for consumers that want to deal with fewer node types.
|
6
216
|
class DesugarCompiler < MutationCompiler
|
@@ -10,7 +220,7 @@ module Prism
|
|
10
220
|
#
|
11
221
|
# @@foo && @@foo = bar
|
12
222
|
def visit_class_variable_and_write_node(node)
|
13
|
-
|
223
|
+
node.desugar
|
14
224
|
end
|
15
225
|
|
16
226
|
# @@foo ||= bar
|
@@ -19,7 +229,7 @@ module Prism
|
|
19
229
|
#
|
20
230
|
# defined?(@@foo) ? @@foo : @@foo = bar
|
21
231
|
def visit_class_variable_or_write_node(node)
|
22
|
-
|
232
|
+
node.desugar
|
23
233
|
end
|
24
234
|
|
25
235
|
# @@foo += bar
|
@@ -28,7 +238,7 @@ module Prism
|
|
28
238
|
#
|
29
239
|
# @@foo = @@foo + bar
|
30
240
|
def visit_class_variable_operator_write_node(node)
|
31
|
-
|
241
|
+
node.desugar
|
32
242
|
end
|
33
243
|
|
34
244
|
# Foo &&= bar
|
@@ -37,7 +247,7 @@ module Prism
|
|
37
247
|
#
|
38
248
|
# Foo && Foo = bar
|
39
249
|
def visit_constant_and_write_node(node)
|
40
|
-
|
250
|
+
node.desugar
|
41
251
|
end
|
42
252
|
|
43
253
|
# Foo ||= bar
|
@@ -46,7 +256,7 @@ module Prism
|
|
46
256
|
#
|
47
257
|
# defined?(Foo) ? Foo : Foo = bar
|
48
258
|
def visit_constant_or_write_node(node)
|
49
|
-
|
259
|
+
node.desugar
|
50
260
|
end
|
51
261
|
|
52
262
|
# Foo += bar
|
@@ -55,7 +265,7 @@ module Prism
|
|
55
265
|
#
|
56
266
|
# Foo = Foo + bar
|
57
267
|
def visit_constant_operator_write_node(node)
|
58
|
-
|
268
|
+
node.desugar
|
59
269
|
end
|
60
270
|
|
61
271
|
# $foo &&= bar
|
@@ -64,7 +274,7 @@ module Prism
|
|
64
274
|
#
|
65
275
|
# $foo && $foo = bar
|
66
276
|
def visit_global_variable_and_write_node(node)
|
67
|
-
|
277
|
+
node.desugar
|
68
278
|
end
|
69
279
|
|
70
280
|
# $foo ||= bar
|
@@ -73,7 +283,7 @@ module Prism
|
|
73
283
|
#
|
74
284
|
# defined?($foo) ? $foo : $foo = bar
|
75
285
|
def visit_global_variable_or_write_node(node)
|
76
|
-
|
286
|
+
node.desugar
|
77
287
|
end
|
78
288
|
|
79
289
|
# $foo += bar
|
@@ -82,7 +292,7 @@ module Prism
|
|
82
292
|
#
|
83
293
|
# $foo = $foo + bar
|
84
294
|
def visit_global_variable_operator_write_node(node)
|
85
|
-
|
295
|
+
node.desugar
|
86
296
|
end
|
87
297
|
|
88
298
|
# @foo &&= bar
|
@@ -91,7 +301,7 @@ module Prism
|
|
91
301
|
#
|
92
302
|
# @foo && @foo = bar
|
93
303
|
def visit_instance_variable_and_write_node(node)
|
94
|
-
|
304
|
+
node.desugar
|
95
305
|
end
|
96
306
|
|
97
307
|
# @foo ||= bar
|
@@ -100,7 +310,7 @@ module Prism
|
|
100
310
|
#
|
101
311
|
# @foo || @foo = bar
|
102
312
|
def visit_instance_variable_or_write_node(node)
|
103
|
-
|
313
|
+
node.desugar
|
104
314
|
end
|
105
315
|
|
106
316
|
# @foo += bar
|
@@ -109,7 +319,7 @@ module Prism
|
|
109
319
|
#
|
110
320
|
# @foo = @foo + bar
|
111
321
|
def visit_instance_variable_operator_write_node(node)
|
112
|
-
|
322
|
+
node.desugar
|
113
323
|
end
|
114
324
|
|
115
325
|
# foo &&= bar
|
@@ -118,7 +328,7 @@ module Prism
|
|
118
328
|
#
|
119
329
|
# foo && foo = bar
|
120
330
|
def visit_local_variable_and_write_node(node)
|
121
|
-
|
331
|
+
node.desugar
|
122
332
|
end
|
123
333
|
|
124
334
|
# foo ||= bar
|
@@ -127,7 +337,7 @@ module Prism
|
|
127
337
|
#
|
128
338
|
# foo || foo = bar
|
129
339
|
def visit_local_variable_or_write_node(node)
|
130
|
-
|
340
|
+
node.desugar
|
131
341
|
end
|
132
342
|
|
133
343
|
# foo += bar
|
@@ -136,72 +346,7 @@ module Prism
|
|
136
346
|
#
|
137
347
|
# foo = foo + bar
|
138
348
|
def visit_local_variable_operator_write_node(node)
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
private
|
143
|
-
|
144
|
-
# Desugar `x &&= y` to `x && x = y`
|
145
|
-
def desugar_and_write_node(node, read_class, write_class, *arguments)
|
146
|
-
AndNode.new(
|
147
|
-
read_class.new(*arguments, node.name_loc),
|
148
|
-
write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location),
|
149
|
-
node.operator_loc,
|
150
|
-
node.location
|
151
|
-
)
|
152
|
-
end
|
153
|
-
|
154
|
-
# Desugar `x += y` to `x = x + y`
|
155
|
-
def desugar_operator_write_node(node, read_class, write_class, *arguments)
|
156
|
-
write_class.new(
|
157
|
-
*arguments,
|
158
|
-
node.name_loc,
|
159
|
-
CallNode.new(
|
160
|
-
0,
|
161
|
-
read_class.new(*arguments, node.name_loc),
|
162
|
-
nil,
|
163
|
-
node.operator_loc.slice.chomp("="),
|
164
|
-
node.operator_loc.copy(length: node.operator_loc.length - 1),
|
165
|
-
nil,
|
166
|
-
ArgumentsNode.new(0, [node.value], node.value.location),
|
167
|
-
nil,
|
168
|
-
nil,
|
169
|
-
node.location
|
170
|
-
),
|
171
|
-
node.operator_loc.copy(start_offset: node.operator_loc.end_offset - 1, length: 1),
|
172
|
-
node.location
|
173
|
-
)
|
174
|
-
end
|
175
|
-
|
176
|
-
# Desugar `x ||= y` to `x || x = y`
|
177
|
-
def desugar_or_write_node(node, read_class, write_class, *arguments)
|
178
|
-
OrNode.new(
|
179
|
-
read_class.new(*arguments, node.name_loc),
|
180
|
-
write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location),
|
181
|
-
node.operator_loc,
|
182
|
-
node.location
|
183
|
-
)
|
184
|
-
end
|
185
|
-
|
186
|
-
# Desugar `x ||= y` to `defined?(x) ? x : x = y`
|
187
|
-
def desugar_or_write_defined_node(node, read_class, write_class, *arguments)
|
188
|
-
IfNode.new(
|
189
|
-
node.operator_loc,
|
190
|
-
DefinedNode.new(nil, read_class.new(*arguments, node.name_loc), nil, node.operator_loc, node.name_loc),
|
191
|
-
node.operator_loc,
|
192
|
-
StatementsNode.new([read_class.new(*arguments, node.name_loc)], node.location),
|
193
|
-
ElseNode.new(
|
194
|
-
node.operator_loc,
|
195
|
-
StatementsNode.new(
|
196
|
-
[write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location)],
|
197
|
-
node.location
|
198
|
-
),
|
199
|
-
node.operator_loc,
|
200
|
-
node.location
|
201
|
-
),
|
202
|
-
node.operator_loc,
|
203
|
-
node.location
|
204
|
-
)
|
349
|
+
node.desugar
|
205
350
|
end
|
206
351
|
end
|
207
352
|
end
|