prism 0.21.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|