prism 0.21.0 → 0.22.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 +17 -1
- data/docs/releasing.md +18 -0
- data/ext/prism/extension.c +44 -12
- data/ext/prism/extension.h +1 -1
- data/include/prism/diagnostic.h +8 -2
- data/include/prism/version.h +2 -2
- data/lib/prism/ffi.rb +7 -2
- data/lib/prism/lex_compat.rb +16 -1
- data/lib/prism/node.rb +212 -32
- data/lib/prism/parse_result.rb +2 -1
- data/lib/prism/ripper_compat.rb +98 -20
- data/lib/prism/serialize.rb +3 -1
- data/lib/prism/translation/parser/compiler.rb +16 -6
- data/lib/prism/translation/parser.rb +9 -3
- data/prism.gemspec +2 -2
- data/src/diagnostic.c +10 -4
- data/src/prism.c +21 -26
- data/src/util/pm_string.c +0 -7
- metadata +4 -4
data/lib/prism/parse_result.rb
CHANGED
@@ -91,7 +91,8 @@ module Prism
|
|
91
91
|
class Location
|
92
92
|
# A Source object that is used to determine more information from the given
|
93
93
|
# offset and length.
|
94
|
-
|
94
|
+
attr_reader :source
|
95
|
+
protected :source
|
95
96
|
|
96
97
|
# The byte offset from the beginning of the source where this location
|
97
98
|
# starts.
|
data/lib/prism/ripper_compat.rb
CHANGED
@@ -97,6 +97,8 @@ module Prism
|
|
97
97
|
result.errors.each do |error|
|
98
98
|
on_parse_error(error.message)
|
99
99
|
end
|
100
|
+
|
101
|
+
nil
|
100
102
|
else
|
101
103
|
result.value.accept(self)
|
102
104
|
end
|
@@ -106,41 +108,91 @@ module Prism
|
|
106
108
|
# Visitor methods
|
107
109
|
############################################################################
|
108
110
|
|
111
|
+
# Visit an ArrayNode node.
|
112
|
+
def visit_array_node(node)
|
113
|
+
elements = visit_elements(node.elements) unless node.elements.empty?
|
114
|
+
bounds(node.location)
|
115
|
+
on_array(elements)
|
116
|
+
end
|
117
|
+
|
109
118
|
# Visit a CallNode node.
|
110
119
|
def visit_call_node(node)
|
111
|
-
if
|
112
|
-
|
113
|
-
|
120
|
+
if node.variable_call?
|
121
|
+
if node.message.match?(/^[[:alpha:]_]/)
|
122
|
+
bounds(node.message_loc)
|
123
|
+
return on_vcall(on_ident(node.message))
|
124
|
+
end
|
114
125
|
|
115
|
-
|
116
|
-
|
126
|
+
raise NotImplementedError, "Non-alpha variable call"
|
127
|
+
end
|
128
|
+
|
129
|
+
if node.opening_loc.nil?
|
130
|
+
left = visit(node.receiver)
|
131
|
+
if node.arguments&.arguments&.length == 1
|
132
|
+
right = visit(node.arguments.arguments.first)
|
133
|
+
|
134
|
+
on_binary(left, node.name, right)
|
135
|
+
elsif !node.arguments || node.arguments.empty?
|
136
|
+
on_unary(node.name, left)
|
137
|
+
else
|
138
|
+
raise NotImplementedError, "More than two arguments for operator"
|
139
|
+
end
|
117
140
|
else
|
118
|
-
raise NotImplementedError
|
141
|
+
raise NotImplementedError, "Non-nil opening_loc"
|
119
142
|
end
|
120
143
|
end
|
121
144
|
|
122
145
|
# Visit a FloatNode node.
|
123
146
|
def visit_float_node(node)
|
124
|
-
|
125
|
-
on_float(node.slice)
|
147
|
+
visit_number(node) { |text| on_float(text) }
|
126
148
|
end
|
127
149
|
|
128
150
|
# Visit a ImaginaryNode node.
|
129
151
|
def visit_imaginary_node(node)
|
130
|
-
|
131
|
-
on_imaginary(node.slice)
|
152
|
+
visit_number(node) { |text| on_imaginary(text) }
|
132
153
|
end
|
133
154
|
|
134
155
|
# Visit an IntegerNode node.
|
135
156
|
def visit_integer_node(node)
|
157
|
+
visit_number(node) { |text| on_int(text) }
|
158
|
+
end
|
159
|
+
|
160
|
+
# Visit a ParenthesesNode node.
|
161
|
+
def visit_parentheses_node(node)
|
162
|
+
body =
|
163
|
+
if node.body.nil?
|
164
|
+
on_stmts_add(on_stmts_new, on_void_stmt)
|
165
|
+
else
|
166
|
+
visit(node.body)
|
167
|
+
end
|
168
|
+
|
169
|
+
bounds(node.location)
|
170
|
+
on_paren(body)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Visit a ProgramNode node.
|
174
|
+
def visit_program_node(node)
|
175
|
+
statements = visit(node.statements)
|
176
|
+
bounds(node.location)
|
177
|
+
on_program(statements)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Visit a RangeNode node.
|
181
|
+
def visit_range_node(node)
|
182
|
+
left = visit(node.left)
|
183
|
+
right = visit(node.right)
|
184
|
+
|
136
185
|
bounds(node.location)
|
137
|
-
|
186
|
+
if node.exclude_end?
|
187
|
+
on_dot3(left, right)
|
188
|
+
else
|
189
|
+
on_dot2(left, right)
|
190
|
+
end
|
138
191
|
end
|
139
192
|
|
140
193
|
# Visit a RationalNode node.
|
141
194
|
def visit_rational_node(node)
|
142
|
-
|
143
|
-
on_rational(node.slice)
|
195
|
+
visit_number(node) { |text| on_rational(text) }
|
144
196
|
end
|
145
197
|
|
146
198
|
# Visit a StatementsNode node.
|
@@ -151,13 +203,6 @@ module Prism
|
|
151
203
|
end
|
152
204
|
end
|
153
205
|
|
154
|
-
# Visit a ProgramNode node.
|
155
|
-
def visit_program_node(node)
|
156
|
-
statements = visit(node.statements)
|
157
|
-
bounds(node.location)
|
158
|
-
on_program(statements)
|
159
|
-
end
|
160
|
-
|
161
206
|
############################################################################
|
162
207
|
# Entrypoints for subclasses
|
163
208
|
############################################################################
|
@@ -174,6 +219,32 @@ module Prism
|
|
174
219
|
|
175
220
|
private
|
176
221
|
|
222
|
+
# Visit a list of elements, like the elements of an array or arguments.
|
223
|
+
def visit_elements(elements)
|
224
|
+
bounds(elements.first.location)
|
225
|
+
elements.inject(on_args_new) do |args, element|
|
226
|
+
on_args_add(args, visit(element))
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Visit a node that represents a number. We need to explicitly handle the
|
231
|
+
# unary - operator.
|
232
|
+
def visit_number(node)
|
233
|
+
slice = node.slice
|
234
|
+
location = node.location
|
235
|
+
|
236
|
+
if slice[0] == "-"
|
237
|
+
bounds_values(location.start_line, location.start_column + 1)
|
238
|
+
value = yield slice[1..-1]
|
239
|
+
|
240
|
+
bounds(node.location)
|
241
|
+
on_unary(RUBY_ENGINE == "jruby" ? :- : :-@, value)
|
242
|
+
else
|
243
|
+
bounds(location)
|
244
|
+
yield slice
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
177
248
|
# This method is responsible for updating lineno and column information
|
178
249
|
# to reflect the current node.
|
179
250
|
#
|
@@ -184,6 +255,13 @@ module Prism
|
|
184
255
|
@column = location.start_column
|
185
256
|
end
|
186
257
|
|
258
|
+
# If we need to do something unusual, we can directly update the line number
|
259
|
+
# and column to reflect the current node.
|
260
|
+
def bounds_values(lineno, column)
|
261
|
+
@lineno = lineno
|
262
|
+
@column = column
|
263
|
+
end
|
264
|
+
|
187
265
|
# Lazily initialize the parse result.
|
188
266
|
def result
|
189
267
|
@result ||= Prism.parse(source)
|
data/lib/prism/serialize.rb
CHANGED
@@ -27,7 +27,7 @@ module Prism
|
|
27
27
|
|
28
28
|
# The minor version of prism that we are expecting to find in the serialized
|
29
29
|
# strings.
|
30
|
-
MINOR_VERSION =
|
30
|
+
MINOR_VERSION = 22
|
31
31
|
|
32
32
|
# The patch version of prism that we are expecting to find in the serialized
|
33
33
|
# strings.
|
@@ -244,6 +244,8 @@ module Prism
|
|
244
244
|
case level
|
245
245
|
when 0
|
246
246
|
:fatal
|
247
|
+
when 1
|
248
|
+
:argument
|
247
249
|
else
|
248
250
|
raise "Unknown level: #{level}"
|
249
251
|
end
|
@@ -1062,12 +1062,22 @@ module Prism
|
|
1062
1062
|
|
1063
1063
|
# foo in bar
|
1064
1064
|
# ^^^^^^^^^^
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1065
|
+
if RUBY_VERSION >= "3.0"
|
1066
|
+
def visit_match_predicate_node(node)
|
1067
|
+
builder.match_pattern_p(
|
1068
|
+
visit(node.value),
|
1069
|
+
token(node.operator_loc),
|
1070
|
+
within_pattern { |compiler| node.pattern.accept(compiler) }
|
1071
|
+
)
|
1072
|
+
end
|
1073
|
+
else
|
1074
|
+
def visit_match_predicate_node(node)
|
1075
|
+
builder.match_pattern(
|
1076
|
+
visit(node.value),
|
1077
|
+
token(node.operator_loc),
|
1078
|
+
within_pattern { |compiler| node.pattern.accept(compiler) }
|
1079
|
+
)
|
1080
|
+
end
|
1071
1081
|
end
|
1072
1082
|
|
1073
1083
|
# foo => bar
|
@@ -68,17 +68,23 @@ module Prism
|
|
68
68
|
|
69
69
|
# Parses a source buffer and returns the AST, the source code comments,
|
70
70
|
# and the tokens emitted by the lexer.
|
71
|
-
def tokenize(source_buffer,
|
71
|
+
def tokenize(source_buffer, recover = false)
|
72
72
|
@source_buffer = source_buffer
|
73
73
|
source = source_buffer.source
|
74
74
|
|
75
75
|
offset_cache = build_offset_cache(source)
|
76
|
-
result =
|
76
|
+
result =
|
77
|
+
begin
|
78
|
+
unwrap(Prism.parse_lex(source, filepath: source_buffer.name), offset_cache)
|
79
|
+
rescue ::Parser::SyntaxError
|
80
|
+
raise if !recover
|
81
|
+
end
|
77
82
|
|
78
83
|
program, tokens = result.value
|
84
|
+
ast = build_ast(program, offset_cache) if result.success?
|
79
85
|
|
80
86
|
[
|
81
|
-
|
87
|
+
ast,
|
82
88
|
build_comments(result.comments, offset_cache),
|
83
89
|
build_tokens(tokens, offset_cache)
|
84
90
|
]
|
data/prism.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "prism"
|
5
|
-
spec.version = "0.
|
5
|
+
spec.version = "0.22.0"
|
6
6
|
spec.authors = ["Shopify"]
|
7
7
|
spec.email = ["ruby@shopify.com"]
|
8
8
|
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.homepage = "https://github.com/ruby/prism"
|
11
11
|
spec.license = "MIT"
|
12
12
|
|
13
|
-
spec.required_ruby_version = ">=
|
13
|
+
spec.required_ruby_version = ">= 2.7.0"
|
14
14
|
|
15
15
|
spec.require_paths = ["lib"]
|
16
16
|
spec.files = [
|
data/src/diagnostic.c
CHANGED
@@ -63,7 +63,8 @@ typedef struct {
|
|
63
63
|
*
|
64
64
|
* For errors, they are:
|
65
65
|
*
|
66
|
-
* * `PM_ERROR_LEVEL_FATAL` - The level for
|
66
|
+
* * `PM_ERROR_LEVEL_FATAL` - The default level for errors.
|
67
|
+
* * `PM_ERROR_LEVEL_ARGUMENT` - Errors that should raise ArgumentError.
|
67
68
|
*
|
68
69
|
* For warnings, they are:
|
69
70
|
*
|
@@ -71,9 +72,13 @@ typedef struct {
|
|
71
72
|
* * `PM_WARNING_LEVEL_VERBOSE` - Warnings that appear with `-w`, as in `ruby -w -c -e 'code'`.
|
72
73
|
*/
|
73
74
|
static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
75
|
+
// Special error that can be replaced
|
74
76
|
[PM_ERR_CANNOT_PARSE_EXPRESSION] = { "cannot parse the expression", PM_ERROR_LEVEL_FATAL },
|
75
77
|
|
76
|
-
// Errors
|
78
|
+
// Errors that should raise argument errors
|
79
|
+
[PM_ERR_INVALID_ENCODING_MAGIC_COMMENT] = { "unknown or invalid encoding in the magic comment", PM_ERROR_LEVEL_ARGUMENT },
|
80
|
+
|
81
|
+
// Errors that should raise syntax errors
|
77
82
|
[PM_ERR_ALIAS_ARGUMENT] = { "invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", PM_ERROR_LEVEL_FATAL },
|
78
83
|
[PM_ERR_AMPAMPEQ_MULTI_ASSIGN] = { "unexpected `&&=` in a multiple assignment", PM_ERROR_LEVEL_FATAL },
|
79
84
|
[PM_ERR_ARGUMENT_AFTER_BLOCK] = { "unexpected argument after a block argument", PM_ERROR_LEVEL_FATAL },
|
@@ -187,15 +192,16 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
|
187
192
|
[PM_ERR_INCOMPLETE_QUESTION_MARK] = { "incomplete expression at `?`", PM_ERROR_LEVEL_FATAL },
|
188
193
|
[PM_ERR_INCOMPLETE_VARIABLE_CLASS] = { "incomplete class variable", PM_ERROR_LEVEL_FATAL },
|
189
194
|
[PM_ERR_INCOMPLETE_VARIABLE_INSTANCE] = { "incomplete instance variable", PM_ERROR_LEVEL_FATAL },
|
190
|
-
[PM_ERR_INVALID_ENCODING_MAGIC_COMMENT] = { "unknown or invalid encoding in the magic comment", PM_ERROR_LEVEL_FATAL },
|
191
195
|
[PM_ERR_INVALID_FLOAT_EXPONENT] = { "invalid exponent", PM_ERROR_LEVEL_FATAL },
|
192
196
|
[PM_ERR_INVALID_NUMBER_BINARY] = { "invalid binary number", PM_ERROR_LEVEL_FATAL },
|
193
197
|
[PM_ERR_INVALID_NUMBER_DECIMAL] = { "invalid decimal number", PM_ERROR_LEVEL_FATAL },
|
194
198
|
[PM_ERR_INVALID_NUMBER_HEXADECIMAL] = { "invalid hexadecimal number", PM_ERROR_LEVEL_FATAL },
|
195
199
|
[PM_ERR_INVALID_NUMBER_OCTAL] = { "invalid octal number", PM_ERROR_LEVEL_FATAL },
|
196
200
|
[PM_ERR_INVALID_NUMBER_UNDERSCORE] = { "invalid underscore placement in number", PM_ERROR_LEVEL_FATAL },
|
201
|
+
[PM_ERR_INVALID_CHARACTER] = { "invalid character 0x%X", PM_ERROR_LEVEL_FATAL },
|
202
|
+
[PM_ERR_INVALID_MULTIBYTE_CHARACTER] = { "invalid multibyte character 0x%X", PM_ERROR_LEVEL_FATAL },
|
203
|
+
[PM_ERR_INVALID_PRINTABLE_CHARACTER] = { "invalid character `%c`", PM_ERROR_LEVEL_FATAL },
|
197
204
|
[PM_ERR_INVALID_PERCENT] = { "invalid `%` token", PM_ERROR_LEVEL_FATAL }, // TODO WHAT?
|
198
|
-
[PM_ERR_INVALID_TOKEN] = { "invalid token", PM_ERROR_LEVEL_FATAL }, // TODO WHAT?
|
199
205
|
[PM_ERR_INVALID_VARIABLE_GLOBAL] = { "invalid global variable", PM_ERROR_LEVEL_FATAL },
|
200
206
|
[PM_ERR_IT_NOT_ALLOWED] = { "`it` is not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_FATAL },
|
201
207
|
[PM_ERR_LAMBDA_OPEN] = { "expected a `do` keyword or a `{` to open the lambda block", PM_ERROR_LEVEL_FATAL },
|
data/src/prism.c
CHANGED
@@ -9590,11 +9590,21 @@ parser_lex(pm_parser_t *parser) {
|
|
9590
9590
|
if (*parser->current.start != '_') {
|
9591
9591
|
size_t width = char_is_identifier_start(parser, parser->current.start);
|
9592
9592
|
|
9593
|
-
// If this isn't the beginning of an identifier, then
|
9594
|
-
// token as we've exhausted all of the
|
9595
|
-
// it and return the next
|
9593
|
+
// If this isn't the beginning of an identifier, then
|
9594
|
+
// it's an invalid token as we've exhausted all of the
|
9595
|
+
// other options. We'll skip past it and return the next
|
9596
|
+
// token after adding an appropriate error message.
|
9596
9597
|
if (!width) {
|
9597
|
-
|
9598
|
+
pm_diagnostic_id_t diag_id;
|
9599
|
+
if (*parser->current.start >= 0x80) {
|
9600
|
+
diag_id = PM_ERR_INVALID_MULTIBYTE_CHARACTER;
|
9601
|
+
} else if (char_is_ascii_printable(*parser->current.start) || (*parser->current.start == '\\')) {
|
9602
|
+
diag_id = PM_ERR_INVALID_PRINTABLE_CHARACTER;
|
9603
|
+
} else {
|
9604
|
+
diag_id = PM_ERR_INVALID_CHARACTER;
|
9605
|
+
}
|
9606
|
+
|
9607
|
+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, diag_id, *parser->current.start);
|
9598
9608
|
goto lex_next_token;
|
9599
9609
|
}
|
9600
9610
|
|
@@ -12377,25 +12387,10 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node, bool def_p) {
|
|
12377
12387
|
}
|
12378
12388
|
|
12379
12389
|
static inline pm_begin_node_t *
|
12380
|
-
parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements, bool def_p) {
|
12390
|
+
parse_rescues_as_begin(pm_parser_t *parser, const uint8_t *start, pm_statements_node_t *statements, bool def_p) {
|
12381
12391
|
pm_token_t no_begin_token = not_provided(parser);
|
12382
12392
|
pm_begin_node_t *begin_node = pm_begin_node_create(parser, &no_begin_token, statements);
|
12383
12393
|
parse_rescues(parser, begin_node, def_p);
|
12384
|
-
|
12385
|
-
// All nodes within a begin node are optional, so we look
|
12386
|
-
// for the earliest possible node that we can use to set
|
12387
|
-
// the BeginNode's start location
|
12388
|
-
const uint8_t *start = begin_node->base.location.start;
|
12389
|
-
if (begin_node->statements) {
|
12390
|
-
start = begin_node->statements->base.location.start;
|
12391
|
-
} else if (begin_node->rescue_clause) {
|
12392
|
-
start = begin_node->rescue_clause->base.location.start;
|
12393
|
-
} else if (begin_node->else_clause) {
|
12394
|
-
start = begin_node->else_clause->base.location.start;
|
12395
|
-
} else if (begin_node->ensure_clause) {
|
12396
|
-
start = begin_node->ensure_clause->base.location.start;
|
12397
|
-
}
|
12398
|
-
|
12399
12394
|
begin_node->base.location.start = start;
|
12400
12395
|
return begin_node;
|
12401
12396
|
}
|
@@ -12490,7 +12485,7 @@ parse_block(pm_parser_t *parser) {
|
|
12490
12485
|
|
12491
12486
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
12492
12487
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
12493
|
-
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
12488
|
+
statements = (pm_node_t *) parse_rescues_as_begin(parser, opening.start, (pm_statements_node_t *) statements, false);
|
12494
12489
|
}
|
12495
12490
|
}
|
12496
12491
|
|
@@ -15290,7 +15285,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
15290
15285
|
|
15291
15286
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
15292
15287
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
15293
|
-
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
15288
|
+
statements = (pm_node_t *) parse_rescues_as_begin(parser, class_keyword.start, (pm_statements_node_t *) statements, false);
|
15294
15289
|
}
|
15295
15290
|
|
15296
15291
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
|
@@ -15343,7 +15338,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
15343
15338
|
|
15344
15339
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
15345
15340
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
15346
|
-
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
15341
|
+
statements = (pm_node_t *) parse_rescues_as_begin(parser, class_keyword.start, (pm_statements_node_t *) statements, false);
|
15347
15342
|
}
|
15348
15343
|
|
15349
15344
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
|
@@ -15612,7 +15607,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
15612
15607
|
|
15613
15608
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
15614
15609
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
15615
|
-
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, true);
|
15610
|
+
statements = (pm_node_t *) parse_rescues_as_begin(parser, def_keyword.start, (pm_statements_node_t *) statements, true);
|
15616
15611
|
}
|
15617
15612
|
|
15618
15613
|
pm_accepts_block_stack_pop(parser);
|
@@ -15872,7 +15867,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
15872
15867
|
|
15873
15868
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
15874
15869
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
15875
|
-
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
15870
|
+
statements = (pm_node_t *) parse_rescues_as_begin(parser, module_keyword.start, (pm_statements_node_t *) statements, false);
|
15876
15871
|
}
|
15877
15872
|
|
15878
15873
|
pm_constant_id_list_t locals = parser->current_scope->locals;
|
@@ -16605,7 +16600,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
16605
16600
|
|
16606
16601
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
16607
16602
|
assert(body == NULL || PM_NODE_TYPE_P(body, PM_STATEMENTS_NODE));
|
16608
|
-
body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body, false);
|
16603
|
+
body = (pm_node_t *) parse_rescues_as_begin(parser, opening.start, (pm_statements_node_t *) body, false);
|
16609
16604
|
}
|
16610
16605
|
|
16611
16606
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
|
data/src/util/pm_string.c
CHANGED
@@ -65,7 +65,6 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|
65
65
|
HANDLE file = CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
66
66
|
|
67
67
|
if (file == INVALID_HANDLE_VALUE) {
|
68
|
-
perror("CreateFile failed");
|
69
68
|
return false;
|
70
69
|
}
|
71
70
|
|
@@ -73,7 +72,6 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|
73
72
|
DWORD file_size = GetFileSize(file, NULL);
|
74
73
|
if (file_size == INVALID_FILE_SIZE) {
|
75
74
|
CloseHandle(file);
|
76
|
-
perror("GetFileSize failed");
|
77
75
|
return false;
|
78
76
|
}
|
79
77
|
|
@@ -90,7 +88,6 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|
90
88
|
HANDLE mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
|
91
89
|
if (mapping == NULL) {
|
92
90
|
CloseHandle(file);
|
93
|
-
perror("CreateFileMapping failed");
|
94
91
|
return false;
|
95
92
|
}
|
96
93
|
|
@@ -100,7 +97,6 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|
100
97
|
CloseHandle(file);
|
101
98
|
|
102
99
|
if (source == NULL) {
|
103
|
-
perror("MapViewOfFile failed");
|
104
100
|
return false;
|
105
101
|
}
|
106
102
|
|
@@ -110,7 +106,6 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|
110
106
|
// Open the file for reading
|
111
107
|
int fd = open(filepath, O_RDONLY);
|
112
108
|
if (fd == -1) {
|
113
|
-
perror("open");
|
114
109
|
return false;
|
115
110
|
}
|
116
111
|
|
@@ -118,7 +113,6 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|
118
113
|
struct stat sb;
|
119
114
|
if (fstat(fd, &sb) == -1) {
|
120
115
|
close(fd);
|
121
|
-
perror("fstat");
|
122
116
|
return false;
|
123
117
|
}
|
124
118
|
|
@@ -135,7 +129,6 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|
135
129
|
|
136
130
|
source = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
137
131
|
if (source == MAP_FAILED) {
|
138
|
-
perror("Map failed");
|
139
132
|
return false;
|
140
133
|
}
|
141
134
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prism
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.22.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -137,14 +137,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
137
|
requirements:
|
138
138
|
- - ">="
|
139
139
|
- !ruby/object:Gem::Version
|
140
|
-
version:
|
140
|
+
version: 2.7.0
|
141
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
requirements: []
|
147
|
-
rubygems_version: 3.
|
147
|
+
rubygems_version: 3.6.0.dev
|
148
148
|
signing_key:
|
149
149
|
specification_version: 4
|
150
150
|
summary: Prism Ruby parser
|