prism 0.26.0 → 0.28.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 +45 -1
- data/Makefile +3 -2
- data/config.yml +305 -20
- data/docs/configuration.md +1 -0
- data/ext/prism/api_node.c +884 -879
- data/ext/prism/extconf.rb +23 -4
- data/ext/prism/extension.c +16 -9
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +298 -9
- data/include/prism/diagnostic.h +15 -5
- data/include/prism/options.h +2 -2
- data/include/prism/parser.h +10 -0
- data/include/prism/static_literals.h +8 -6
- data/include/prism/version.h +2 -2
- data/lib/prism/dot_visitor.rb +22 -6
- data/lib/prism/dsl.rb +8 -8
- data/lib/prism/ffi.rb +4 -4
- data/lib/prism/inspect_visitor.rb +2156 -0
- data/lib/prism/lex_compat.rb +18 -1
- data/lib/prism/mutation_compiler.rb +2 -2
- data/lib/prism/node.rb +2345 -1964
- data/lib/prism/node_ext.rb +34 -5
- data/lib/prism/parse_result/newlines.rb +0 -2
- data/lib/prism/parse_result.rb +137 -13
- data/lib/prism/pattern.rb +12 -6
- data/lib/prism/polyfill/byteindex.rb +13 -0
- data/lib/prism/polyfill/unpack1.rb +14 -0
- data/lib/prism/reflection.rb +21 -31
- data/lib/prism/serialize.rb +27 -17
- data/lib/prism/translation/parser/compiler.rb +34 -15
- data/lib/prism/translation/parser.rb +6 -6
- data/lib/prism/translation/ripper.rb +72 -68
- data/lib/prism/translation/ruby_parser.rb +69 -31
- data/lib/prism.rb +3 -2
- data/prism.gemspec +36 -38
- data/rbi/prism/compiler.rbi +3 -5
- data/rbi/prism/inspect_visitor.rbi +12 -0
- data/rbi/prism/node.rbi +359 -321
- data/rbi/prism/parse_result.rbi +85 -34
- data/rbi/prism/reflection.rbi +7 -13
- data/rbi/prism/translation/ripper.rbi +1 -11
- data/rbi/prism.rbi +9 -9
- data/sig/prism/dsl.rbs +3 -3
- data/sig/prism/inspect_visitor.rbs +22 -0
- data/sig/prism/node.rbs +68 -48
- data/sig/prism/parse_result.rbs +42 -10
- data/sig/prism/reflection.rbs +2 -8
- data/sig/prism/serialize.rbs +2 -3
- data/sig/prism.rbs +9 -9
- data/src/diagnostic.c +44 -24
- data/src/node.c +41 -16
- data/src/options.c +2 -2
- data/src/prettyprint.c +61 -18
- data/src/prism.c +623 -188
- data/src/serialize.c +5 -2
- data/src/static_literals.c +120 -34
- data/src/token_type.c +4 -4
- data/src/util/pm_integer.c +9 -2
- metadata +7 -9
- data/lib/prism/node_inspector.rb +0 -68
- data/lib/prism/polyfill/string.rb +0 -12
- data/rbi/prism/desugar_compiler.rbi +0 -5
- data/rbi/prism/mutation_compiler.rbi +0 -5
- data/rbi/prism/translation/parser/compiler.rbi +0 -13
- data/rbi/prism/translation/ripper/ripper_compiler.rbi +0 -5
- data/rbi/prism/translation/ruby_parser.rbi +0 -11
data/lib/prism/node_ext.rb
CHANGED
@@ -143,11 +143,12 @@ module Prism
|
|
143
143
|
current = self #: node?
|
144
144
|
|
145
145
|
while current.is_a?(ConstantPathNode)
|
146
|
-
|
147
|
-
if
|
146
|
+
name = current.name
|
147
|
+
if name.nil?
|
148
148
|
raise MissingNodesInConstantPathError, "Constant path contains missing nodes. Cannot compute full name"
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
|
+
parts.unshift(name)
|
151
152
|
current = current.parent
|
152
153
|
end
|
153
154
|
|
@@ -162,6 +163,20 @@ module Prism
|
|
162
163
|
def full_name
|
163
164
|
full_name_parts.join("::")
|
164
165
|
end
|
166
|
+
|
167
|
+
# Previously, we had a child node on this class that contained either a
|
168
|
+
# constant read or a missing node. To not cause a breaking change, we
|
169
|
+
# continue to supply that API.
|
170
|
+
def child
|
171
|
+
warn(<<~MSG, category: :deprecated)
|
172
|
+
DEPRECATED: ConstantPathNode#child is deprecated and will be removed \
|
173
|
+
in the next major version. Use \
|
174
|
+
ConstantPathNode#name/ConstantPathNode#name_loc instead. Called from \
|
175
|
+
#{caller(1, 1)&.first}.
|
176
|
+
MSG
|
177
|
+
|
178
|
+
name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
|
179
|
+
end
|
165
180
|
end
|
166
181
|
|
167
182
|
class ConstantPathTargetNode < Node
|
@@ -179,17 +194,31 @@ module Prism
|
|
179
194
|
raise ConstantPathNode::DynamicPartsInConstantPathError, "Constant target path contains dynamic parts. Cannot compute full name"
|
180
195
|
end
|
181
196
|
|
182
|
-
if
|
197
|
+
if name.nil?
|
183
198
|
raise ConstantPathNode::MissingNodesInConstantPathError, "Constant target path contains missing nodes. Cannot compute full name"
|
184
199
|
end
|
185
200
|
|
186
|
-
parts.push(
|
201
|
+
parts.push(name)
|
187
202
|
end
|
188
203
|
|
189
204
|
# Returns the full name of this constant path. For example: "Foo::Bar"
|
190
205
|
def full_name
|
191
206
|
full_name_parts.join("::")
|
192
207
|
end
|
208
|
+
|
209
|
+
# Previously, we had a child node on this class that contained either a
|
210
|
+
# constant read or a missing node. To not cause a breaking change, we
|
211
|
+
# continue to supply that API.
|
212
|
+
def child
|
213
|
+
warn(<<~MSG, category: :deprecated)
|
214
|
+
DEPRECATED: ConstantPathTargetNode#child is deprecated and will be \
|
215
|
+
removed in the next major version. Use \
|
216
|
+
ConstantPathTargetNode#name/ConstantPathTargetNode#name_loc instead. \
|
217
|
+
Called from #{caller(1, 1)&.first}.
|
218
|
+
MSG
|
219
|
+
|
220
|
+
name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
|
221
|
+
end
|
193
222
|
end
|
194
223
|
|
195
224
|
class ConstantTargetNode < Node
|
@@ -58,8 +58,6 @@ module Prism
|
|
58
58
|
|
59
59
|
# Walk the tree and mark nodes that are on a new line.
|
60
60
|
def mark_newlines!
|
61
|
-
value = self.value
|
62
|
-
raise "This method should only be called on a parse result that contains a node" unless Node === value
|
63
61
|
value.accept(Newlines.new(Array.new(1 + source.offsets.size, false))) # steep:ignore
|
64
62
|
end
|
65
63
|
end
|
data/lib/prism/parse_result.rb
CHANGED
@@ -5,6 +5,14 @@ module Prism
|
|
5
5
|
# conjunction with locations to allow them to resolve line numbers and source
|
6
6
|
# ranges.
|
7
7
|
class Source
|
8
|
+
# Create a new source object with the given source code. This method should
|
9
|
+
# be used instead of `new` and it will return either a `Source` or a
|
10
|
+
# specialized and more performant `ASCIISource` if no multibyte characters
|
11
|
+
# are present in the source code.
|
12
|
+
def self.for(source, start_line = 1, offsets = [])
|
13
|
+
source.ascii_only? ? ASCIISource.new(source, start_line, offsets): new(source, start_line, offsets)
|
14
|
+
end
|
15
|
+
|
8
16
|
# The source code that this source object represents.
|
9
17
|
attr_reader :source
|
10
18
|
|
@@ -27,6 +35,11 @@ module Prism
|
|
27
35
|
source.encoding
|
28
36
|
end
|
29
37
|
|
38
|
+
# Returns the lines of the source code as an array of strings.
|
39
|
+
def lines
|
40
|
+
source.lines
|
41
|
+
end
|
42
|
+
|
30
43
|
# Perform a byteslice on the source code using the given byte offset and
|
31
44
|
# byte length.
|
32
45
|
def slice(byte_offset, length)
|
@@ -45,6 +58,12 @@ module Prism
|
|
45
58
|
offsets[find_line(byte_offset)]
|
46
59
|
end
|
47
60
|
|
61
|
+
# Returns the byte offset of the end of the line corresponding to the given
|
62
|
+
# byte offset.
|
63
|
+
def line_end(byte_offset)
|
64
|
+
offsets[find_line(byte_offset) + 1] || source.bytesize
|
65
|
+
end
|
66
|
+
|
48
67
|
# Return the column number for the given byte offset.
|
49
68
|
def column(byte_offset)
|
50
69
|
byte_offset - line_start(byte_offset)
|
@@ -100,6 +119,39 @@ module Prism
|
|
100
119
|
end
|
101
120
|
end
|
102
121
|
|
122
|
+
# Specialized version of Prism::Source for source code that includes ASCII
|
123
|
+
# characters only. This class is used to apply performance optimizations that
|
124
|
+
# cannot be applied to sources that include multibyte characters. Sources that
|
125
|
+
# include multibyte characters are represented by the Prism::Source class.
|
126
|
+
class ASCIISource < Source
|
127
|
+
# Return the character offset for the given byte offset.
|
128
|
+
def character_offset(byte_offset)
|
129
|
+
byte_offset
|
130
|
+
end
|
131
|
+
|
132
|
+
# Return the column number in characters for the given byte offset.
|
133
|
+
def character_column(byte_offset)
|
134
|
+
byte_offset - line_start(byte_offset)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Returns the offset from the start of the file for the given byte offset
|
138
|
+
# counting in code units for the given encoding.
|
139
|
+
#
|
140
|
+
# This method is tested with UTF-8, UTF-16, and UTF-32. If there is the
|
141
|
+
# concept of code units that differs from the number of characters in other
|
142
|
+
# encodings, it is not captured here.
|
143
|
+
def code_units_offset(byte_offset, encoding)
|
144
|
+
byte_offset
|
145
|
+
end
|
146
|
+
|
147
|
+
# Specialized version of `code_units_column` that does not depend on
|
148
|
+
# `code_units_offset`, which is a more expensive operation. This is
|
149
|
+
# essentialy the same as `Prism::Source#column`.
|
150
|
+
def code_units_column(byte_offset, encoding)
|
151
|
+
byte_offset - line_start(byte_offset)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
103
155
|
# This represents a location in the source.
|
104
156
|
class Location
|
105
157
|
# A Source object that is used to determine more information from the given
|
@@ -171,11 +223,25 @@ module Prism
|
|
171
223
|
"#<Prism::Location @start_offset=#{@start_offset} @length=#{@length} start_line=#{start_line}>"
|
172
224
|
end
|
173
225
|
|
226
|
+
# Returns all of the lines of the source code associated with this location.
|
227
|
+
def source_lines
|
228
|
+
source.lines
|
229
|
+
end
|
230
|
+
|
174
231
|
# The source code that this location represents.
|
175
232
|
def slice
|
176
233
|
source.slice(start_offset, length)
|
177
234
|
end
|
178
235
|
|
236
|
+
# The source code that this location represents starting from the beginning
|
237
|
+
# of the line that this location starts on to the end of the line that this
|
238
|
+
# location ends on.
|
239
|
+
def slice_lines
|
240
|
+
line_start = source.line_start(start_offset)
|
241
|
+
line_end = source.line_end(end_offset)
|
242
|
+
source.slice(line_start, line_end - line_start)
|
243
|
+
end
|
244
|
+
|
179
245
|
# The character offset from the beginning of the source where this location
|
180
246
|
# starts.
|
181
247
|
def start_character_offset
|
@@ -281,6 +347,18 @@ module Prism
|
|
281
347
|
|
282
348
|
Location.new(source, start_offset, other.end_offset - start_offset)
|
283
349
|
end
|
350
|
+
|
351
|
+
# Join this location with the first occurrence of the string in the source
|
352
|
+
# that occurs after this location on the same line, and return the new
|
353
|
+
# location. This will raise an error if the string does not exist.
|
354
|
+
def adjoin(string)
|
355
|
+
line_suffix = source.slice(end_offset, source.line_end(end_offset) - end_offset)
|
356
|
+
|
357
|
+
line_suffix_index = line_suffix.byteindex(string)
|
358
|
+
raise "Could not find #{string}" if line_suffix_index.nil?
|
359
|
+
|
360
|
+
Location.new(source, start_offset, length + line_suffix_index + string.bytesize)
|
361
|
+
end
|
284
362
|
end
|
285
363
|
|
286
364
|
# This represents a comment that was encountered during parsing. It is the
|
@@ -438,14 +516,9 @@ module Prism
|
|
438
516
|
end
|
439
517
|
|
440
518
|
# This represents the result of a call to ::parse or ::parse_file. It contains
|
441
|
-
# the
|
442
|
-
# encountered.
|
443
|
-
class
|
444
|
-
# The value that was generated by parsing. Normally this holds the AST, but
|
445
|
-
# it can sometimes how a list of tokens or other results passed back from
|
446
|
-
# the parser.
|
447
|
-
attr_reader :value
|
448
|
-
|
519
|
+
# the requested structure, any comments that were encounters, and any errors
|
520
|
+
# that were encountered.
|
521
|
+
class Result
|
449
522
|
# The list of comments that were encountered during parsing.
|
450
523
|
attr_reader :comments
|
451
524
|
|
@@ -466,9 +539,8 @@ module Prism
|
|
466
539
|
# A Source instance that represents the source code that was parsed.
|
467
540
|
attr_reader :source
|
468
541
|
|
469
|
-
# Create a new
|
470
|
-
def initialize(
|
471
|
-
@value = value
|
542
|
+
# Create a new result object with the given values.
|
543
|
+
def initialize(comments, magic_comments, data_loc, errors, warnings, source)
|
472
544
|
@comments = comments
|
473
545
|
@magic_comments = magic_comments
|
474
546
|
@data_loc = data_loc
|
@@ -477,9 +549,9 @@ module Prism
|
|
477
549
|
@source = source
|
478
550
|
end
|
479
551
|
|
480
|
-
# Implement the hash pattern matching interface for
|
552
|
+
# Implement the hash pattern matching interface for Result.
|
481
553
|
def deconstruct_keys(keys)
|
482
|
-
{
|
554
|
+
{ comments: comments, magic_comments: magic_comments, data_loc: data_loc, errors: errors, warnings: warnings }
|
483
555
|
end
|
484
556
|
|
485
557
|
# Returns the encoding of the source code that was parsed.
|
@@ -500,6 +572,58 @@ module Prism
|
|
500
572
|
end
|
501
573
|
end
|
502
574
|
|
575
|
+
# This is a result specific to the `parse` and `parse_file` methods.
|
576
|
+
class ParseResult < Result
|
577
|
+
# The syntax tree that was parsed from the source code.
|
578
|
+
attr_reader :value
|
579
|
+
|
580
|
+
# Create a new parse result object with the given values.
|
581
|
+
def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
|
582
|
+
@value = value
|
583
|
+
super(comments, magic_comments, data_loc, errors, warnings, source)
|
584
|
+
end
|
585
|
+
|
586
|
+
# Implement the hash pattern matching interface for ParseResult.
|
587
|
+
def deconstruct_keys(keys)
|
588
|
+
super.merge!(value: value)
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
# This is a result specific to the `lex` and `lex_file` methods.
|
593
|
+
class LexResult < Result
|
594
|
+
# The list of tokens that were parsed from the source code.
|
595
|
+
attr_reader :value
|
596
|
+
|
597
|
+
# Create a new lex result object with the given values.
|
598
|
+
def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
|
599
|
+
@value = value
|
600
|
+
super(comments, magic_comments, data_loc, errors, warnings, source)
|
601
|
+
end
|
602
|
+
|
603
|
+
# Implement the hash pattern matching interface for LexResult.
|
604
|
+
def deconstruct_keys(keys)
|
605
|
+
super.merge!(value: value)
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
# This is a result specific to the `parse_lex` and `parse_lex_file` methods.
|
610
|
+
class ParseLexResult < Result
|
611
|
+
# A tuple of the syntax tree and the list of tokens that were parsed from
|
612
|
+
# the source code.
|
613
|
+
attr_reader :value
|
614
|
+
|
615
|
+
# Create a new parse lex result object with the given values.
|
616
|
+
def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
|
617
|
+
@value = value
|
618
|
+
super(comments, magic_comments, data_loc, errors, warnings, source)
|
619
|
+
end
|
620
|
+
|
621
|
+
# Implement the hash pattern matching interface for ParseLexResult.
|
622
|
+
def deconstruct_keys(keys)
|
623
|
+
super.merge!(value: value)
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
503
627
|
# This represents a token from the Ruby source.
|
504
628
|
class Token
|
505
629
|
# The Source object that represents the source this token came from.
|
data/lib/prism/pattern.rb
CHANGED
@@ -149,7 +149,10 @@ module Prism
|
|
149
149
|
parent = node.parent
|
150
150
|
|
151
151
|
if parent.is_a?(ConstantReadNode) && parent.slice == "Prism"
|
152
|
-
|
152
|
+
name = node.name
|
153
|
+
raise CompilationError, node.inspect if name.nil?
|
154
|
+
|
155
|
+
compile_constant_name(node, name)
|
153
156
|
else
|
154
157
|
compile_error(node)
|
155
158
|
end
|
@@ -158,14 +161,17 @@ module Prism
|
|
158
161
|
# in ConstantReadNode
|
159
162
|
# in String
|
160
163
|
def compile_constant_read_node(node)
|
161
|
-
|
164
|
+
compile_constant_name(node, node.name)
|
165
|
+
end
|
162
166
|
|
163
|
-
|
164
|
-
|
167
|
+
# Compile a name associated with a constant.
|
168
|
+
def compile_constant_name(node, name)
|
169
|
+
if Prism.const_defined?(name, false)
|
170
|
+
clazz = Prism.const_get(name)
|
165
171
|
|
166
172
|
->(other) { clazz === other }
|
167
|
-
elsif Object.const_defined?(
|
168
|
-
clazz = Object.const_get(
|
173
|
+
elsif Object.const_defined?(name, false)
|
174
|
+
clazz = Object.const_get(name)
|
169
175
|
|
170
176
|
->(other) { clazz === other }
|
171
177
|
else
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Polyfill for String#byteindex, which didn't exist until Ruby 3.2.
|
4
|
+
if !("".respond_to?(:byteindex))
|
5
|
+
String.include(
|
6
|
+
Module.new {
|
7
|
+
def byteindex(needle, offset = 0)
|
8
|
+
charindex = index(needle, offset)
|
9
|
+
slice(0...charindex).bytesize if charindex
|
10
|
+
end
|
11
|
+
}
|
12
|
+
)
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Polyfill for String#unpack1 with the offset parameter. Not all Ruby engines
|
4
|
+
# have Method#parameters implemented, so we check the arity instead if
|
5
|
+
# necessary.
|
6
|
+
if (unpack1 = String.instance_method(:unpack1)).respond_to?(:parameters) ? unpack1.parameters.none? { |_, name| name == :offset } : (unpack1.arity == 1)
|
7
|
+
String.prepend(
|
8
|
+
Module.new {
|
9
|
+
def unpack1(format, offset: 0) # :nodoc:
|
10
|
+
offset == 0 ? super(format) : self[offset..].unpack1(format) # steep:ignore
|
11
|
+
end
|
12
|
+
}
|
13
|
+
)
|
14
|
+
end
|
data/lib/prism/reflection.rb
CHANGED
@@ -73,14 +73,16 @@ module Prism
|
|
73
73
|
class OptionalLocationField < Field
|
74
74
|
end
|
75
75
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
76
|
+
# An integer field represents an integer value. It is used to represent the
|
77
|
+
# value of an integer literal, the depth of local variables, and the number
|
78
|
+
# of a numbered reference. It resolves to an Integer in Ruby.
|
79
|
+
class IntegerField < Field
|
79
80
|
end
|
80
81
|
|
81
|
-
# A
|
82
|
-
#
|
83
|
-
|
82
|
+
# A float field represents a double-precision floating point value. It is
|
83
|
+
# used exclusively to represent the value of a floating point literal. It
|
84
|
+
# resolves to a Float in Ruby.
|
85
|
+
class FloatField < Field
|
84
86
|
end
|
85
87
|
|
86
88
|
# A flags field represents a bitset of flags on a node. It resolves to an
|
@@ -98,18 +100,6 @@ module Prism
|
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
101
|
-
# An integer field represents an arbitrarily-sized integer value. It is used
|
102
|
-
# exclusively to represent the value of an integer literal. It resolves to
|
103
|
-
# an Integer in Ruby.
|
104
|
-
class IntegerField < Field
|
105
|
-
end
|
106
|
-
|
107
|
-
# A double field represents a double-precision floating point value. It is
|
108
|
-
# used exclusively to represent the value of a floating point literal. It
|
109
|
-
# resolves to a Float in Ruby.
|
110
|
-
class DoubleField < Field
|
111
|
-
end
|
112
|
-
|
113
103
|
# Returns the fields for the given node.
|
114
104
|
def self.fields_for(node)
|
115
105
|
case node.type
|
@@ -122,7 +112,7 @@ module Prism
|
|
122
112
|
when :and_node
|
123
113
|
[NodeField.new(:left), NodeField.new(:right), LocationField.new(:operator_loc)]
|
124
114
|
when :arguments_node
|
125
|
-
[FlagsField.new(:flags, [:contains_keyword_splat?]), NodeListField.new(:arguments)]
|
115
|
+
[FlagsField.new(:flags, [:contains_keywords?, :contains_keyword_splat?]), NodeListField.new(:arguments)]
|
126
116
|
when :array_node
|
127
117
|
[FlagsField.new(:flags, [:contains_splat?]), NodeListField.new(:elements), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)]
|
128
118
|
when :array_pattern_node
|
@@ -186,13 +176,13 @@ module Prism
|
|
186
176
|
when :constant_path_and_write_node
|
187
177
|
[NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)]
|
188
178
|
when :constant_path_node
|
189
|
-
[OptionalNodeField.new(:parent),
|
179
|
+
[OptionalNodeField.new(:parent), OptionalConstantField.new(:name), LocationField.new(:delimiter_loc), LocationField.new(:name_loc)]
|
190
180
|
when :constant_path_operator_write_node
|
191
181
|
[NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:operator)]
|
192
182
|
when :constant_path_or_write_node
|
193
183
|
[NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)]
|
194
184
|
when :constant_path_target_node
|
195
|
-
[OptionalNodeField.new(:parent),
|
185
|
+
[OptionalNodeField.new(:parent), OptionalConstantField.new(:name), LocationField.new(:delimiter_loc), LocationField.new(:name_loc)]
|
196
186
|
when :constant_path_write_node
|
197
187
|
[NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)]
|
198
188
|
when :constant_read_node
|
@@ -220,7 +210,7 @@ module Prism
|
|
220
210
|
when :flip_flop_node
|
221
211
|
[FlagsField.new(:flags, [:exclude_end?]), OptionalNodeField.new(:left), OptionalNodeField.new(:right), LocationField.new(:operator_loc)]
|
222
212
|
when :float_node
|
223
|
-
[
|
213
|
+
[FloatField.new(:value)]
|
224
214
|
when :for_node
|
225
215
|
[NodeField.new(:index), NodeField.new(:collection), OptionalNodeField.new(:statements), LocationField.new(:for_keyword_loc), LocationField.new(:in_keyword_loc), OptionalLocationField.new(:do_keyword_loc), LocationField.new(:end_keyword_loc)]
|
226
216
|
when :forwarding_arguments_node
|
@@ -296,17 +286,17 @@ module Prism
|
|
296
286
|
when :lambda_node
|
297
287
|
[ConstantListField.new(:locals), LocationField.new(:operator_loc), LocationField.new(:opening_loc), LocationField.new(:closing_loc), OptionalNodeField.new(:parameters), OptionalNodeField.new(:body)]
|
298
288
|
when :local_variable_and_write_node
|
299
|
-
[LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name),
|
289
|
+
[LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), IntegerField.new(:depth)]
|
300
290
|
when :local_variable_operator_write_node
|
301
|
-
[LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), ConstantField.new(:operator),
|
291
|
+
[LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), ConstantField.new(:operator), IntegerField.new(:depth)]
|
302
292
|
when :local_variable_or_write_node
|
303
|
-
[LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name),
|
293
|
+
[LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), IntegerField.new(:depth)]
|
304
294
|
when :local_variable_read_node
|
305
|
-
[ConstantField.new(:name),
|
295
|
+
[ConstantField.new(:name), IntegerField.new(:depth)]
|
306
296
|
when :local_variable_target_node
|
307
|
-
[ConstantField.new(:name),
|
297
|
+
[ConstantField.new(:name), IntegerField.new(:depth)]
|
308
298
|
when :local_variable_write_node
|
309
|
-
[ConstantField.new(:name),
|
299
|
+
[ConstantField.new(:name), IntegerField.new(:depth), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)]
|
310
300
|
when :match_last_line_node
|
311
301
|
[FlagsField.new(:flags, [:ignore_case?, :extended?, :multi_line?, :once?, :euc_jp?, :ascii_8bit?, :windows_31j?, :utf_8?, :forced_utf8_encoding?, :forced_binary_encoding?, :forced_us_ascii_encoding?]), LocationField.new(:opening_loc), LocationField.new(:content_loc), LocationField.new(:closing_loc), StringField.new(:unescaped)]
|
312
302
|
when :match_predicate_node
|
@@ -330,9 +320,9 @@ module Prism
|
|
330
320
|
when :no_keywords_parameter_node
|
331
321
|
[LocationField.new(:operator_loc), LocationField.new(:keyword_loc)]
|
332
322
|
when :numbered_parameters_node
|
333
|
-
[
|
323
|
+
[IntegerField.new(:maximum)]
|
334
324
|
when :numbered_reference_read_node
|
335
|
-
[
|
325
|
+
[IntegerField.new(:number)]
|
336
326
|
when :optional_keyword_parameter_node
|
337
327
|
[FlagsField.new(:flags, [:repeated_parameter?]), ConstantField.new(:name), LocationField.new(:name_loc), NodeField.new(:value)]
|
338
328
|
when :optional_parameter_node
|
@@ -374,7 +364,7 @@ module Prism
|
|
374
364
|
when :retry_node
|
375
365
|
[]
|
376
366
|
when :return_node
|
377
|
-
[LocationField.new(:keyword_loc), OptionalNodeField.new(:arguments)]
|
367
|
+
[FlagsField.new(:flags, [:redundant?]), LocationField.new(:keyword_loc), OptionalNodeField.new(:arguments)]
|
378
368
|
when :self_node
|
379
369
|
[]
|
380
370
|
when :shareable_constant_node
|
data/lib/prism/serialize.rb
CHANGED
@@ -7,7 +7,7 @@ if you are looking to modify the template
|
|
7
7
|
=end
|
8
8
|
|
9
9
|
require "stringio"
|
10
|
-
require_relative "polyfill/
|
10
|
+
require_relative "polyfill/unpack1"
|
11
11
|
|
12
12
|
module Prism
|
13
13
|
# A module responsible for deserializing parse results.
|
@@ -18,7 +18,7 @@ module Prism
|
|
18
18
|
|
19
19
|
# The minor version of prism that we are expecting to find in the serialized
|
20
20
|
# strings.
|
21
|
-
MINOR_VERSION =
|
21
|
+
MINOR_VERSION = 28
|
22
22
|
|
23
23
|
# The patch version of prism that we are expecting to find in the serialized
|
24
24
|
# strings.
|
@@ -27,7 +27,7 @@ module Prism
|
|
27
27
|
# Deserialize the AST represented by the given string into a parse result.
|
28
28
|
def self.load(input, serialized)
|
29
29
|
input = input.dup
|
30
|
-
source = Source.
|
30
|
+
source = Source.for(input)
|
31
31
|
loader = Loader.new(source, serialized)
|
32
32
|
result = loader.load_result
|
33
33
|
|
@@ -249,17 +249,20 @@ module Prism
|
|
249
249
|
:hash_rocket,
|
250
250
|
:hash_term,
|
251
251
|
:hash_value,
|
252
|
+
:heredoc_identifier,
|
252
253
|
:heredoc_term,
|
253
254
|
:incomplete_question_mark,
|
254
255
|
:incomplete_variable_class,
|
255
|
-
:
|
256
|
+
:incomplete_variable_class_3_3,
|
256
257
|
:incomplete_variable_instance,
|
257
|
-
:
|
258
|
+
:incomplete_variable_instance_3_3,
|
258
259
|
:instance_variable_bare,
|
259
260
|
:invalid_block_exit,
|
260
261
|
:invalid_character,
|
261
262
|
:invalid_encoding_magic_comment,
|
262
263
|
:invalid_float_exponent,
|
264
|
+
:invalid_local_variable_read,
|
265
|
+
:invalid_local_variable_write,
|
263
266
|
:invalid_multibyte_char,
|
264
267
|
:invalid_multibyte_character,
|
265
268
|
:invalid_multibyte_escape,
|
@@ -267,14 +270,16 @@ module Prism
|
|
267
270
|
:invalid_number_decimal,
|
268
271
|
:invalid_number_hexadecimal,
|
269
272
|
:invalid_number_octal,
|
270
|
-
:
|
273
|
+
:invalid_number_underscore_inner,
|
274
|
+
:invalid_number_underscore_trailing,
|
271
275
|
:invalid_percent,
|
272
276
|
:invalid_printable_character,
|
273
277
|
:invalid_retry_after_else,
|
274
278
|
:invalid_retry_after_ensure,
|
275
279
|
:invalid_retry_without_rescue,
|
280
|
+
:invalid_symbol,
|
276
281
|
:invalid_variable_global,
|
277
|
-
:
|
282
|
+
:invalid_variable_global_3_3,
|
278
283
|
:invalid_yield,
|
279
284
|
:it_not_allowed_numbered,
|
280
285
|
:it_not_allowed_ordinary,
|
@@ -318,6 +323,7 @@ module Prism
|
|
318
323
|
:parameter_star,
|
319
324
|
:parameter_unexpected_fwd,
|
320
325
|
:parameter_wild_loose_comma,
|
326
|
+
:parameter_unexpected_no_kw,
|
321
327
|
:pattern_capture_duplicate,
|
322
328
|
:pattern_expression_after_bracket,
|
323
329
|
:pattern_expression_after_comma,
|
@@ -332,6 +338,7 @@ module Prism
|
|
332
338
|
:pattern_hash_key,
|
333
339
|
:pattern_hash_key_duplicate,
|
334
340
|
:pattern_hash_key_label,
|
341
|
+
:pattern_hash_key_locals,
|
335
342
|
:pattern_ident_after_hrocket,
|
336
343
|
:pattern_label_after_comma,
|
337
344
|
:pattern_rest,
|
@@ -370,6 +377,9 @@ module Prism
|
|
370
377
|
:unary_receiver,
|
371
378
|
:undef_argument,
|
372
379
|
:unexpected_block_argument,
|
380
|
+
:unexpected_index_block,
|
381
|
+
:unexpected_index_keywords,
|
382
|
+
:unexpected_safe_navigation,
|
373
383
|
:unexpected_token_close_context,
|
374
384
|
:unexpected_token_ignore,
|
375
385
|
:until_term,
|
@@ -388,7 +398,7 @@ module Prism
|
|
388
398
|
:comparison_after_comparison,
|
389
399
|
:dot_dot_dot_eol,
|
390
400
|
:equal_in_conditional,
|
391
|
-
:
|
401
|
+
:equal_in_conditional_3_3,
|
392
402
|
:end_in_method,
|
393
403
|
:duplicated_hash_key,
|
394
404
|
:duplicated_when_clause,
|
@@ -426,7 +436,7 @@ module Prism
|
|
426
436
|
length = load_varuint
|
427
437
|
lex_state = load_varuint
|
428
438
|
location = Location.new(@source, start, length)
|
429
|
-
tokens << [
|
439
|
+
tokens << [Token.new(source, type, location.slice, location), lex_state]
|
430
440
|
end
|
431
441
|
|
432
442
|
tokens
|
@@ -441,7 +451,7 @@ module Prism
|
|
441
451
|
tokens.each { |token,| token.value.force_encoding(encoding) }
|
442
452
|
|
443
453
|
raise "Expected to consume all bytes while deserializing" unless @io.eof?
|
444
|
-
|
454
|
+
LexResult.new(tokens, comments, magic_comments, data_loc, errors, warnings, @source)
|
445
455
|
end
|
446
456
|
|
447
457
|
def load_nodes
|
@@ -460,7 +470,7 @@ module Prism
|
|
460
470
|
|
461
471
|
def load_result
|
462
472
|
node, comments, magic_comments, data_loc, errors, warnings = load_nodes
|
463
|
-
|
473
|
+
ParseResult.new(node, comments, magic_comments, data_loc, errors, warnings, @source)
|
464
474
|
end
|
465
475
|
|
466
476
|
private
|
@@ -718,7 +728,7 @@ module Prism
|
|
718
728
|
source, load_node, load_location, load_node, location)
|
719
729
|
when 37 then
|
720
730
|
ConstantPathNode.new(
|
721
|
-
source, load_optional_node,
|
731
|
+
source, load_optional_node, load_optional_constant, load_location, load_location, location)
|
722
732
|
when 38 then
|
723
733
|
ConstantPathOperatorWriteNode.new(
|
724
734
|
source, load_node, load_location, load_node, load_required_constant, location)
|
@@ -727,7 +737,7 @@ module Prism
|
|
727
737
|
source, load_node, load_location, load_node, location)
|
728
738
|
when 40 then
|
729
739
|
ConstantPathTargetNode.new(
|
730
|
-
source, load_optional_node,
|
740
|
+
source, load_optional_node, load_optional_constant, load_location, load_location, location)
|
731
741
|
when 41 then
|
732
742
|
ConstantPathWriteNode.new(
|
733
743
|
source, load_node, load_location, load_node, location)
|
@@ -1001,7 +1011,7 @@ module Prism
|
|
1001
1011
|
source, location)
|
1002
1012
|
when 131 then
|
1003
1013
|
ReturnNode.new(
|
1004
|
-
source, load_location, load_optional_node, location)
|
1014
|
+
source, load_varuint, load_location, load_optional_node, location)
|
1005
1015
|
when 132 then
|
1006
1016
|
SelfNode.new(
|
1007
1017
|
source, location)
|
@@ -1253,7 +1263,7 @@ module Prism
|
|
1253
1263
|
-> {
|
1254
1264
|
location = load_location
|
1255
1265
|
ConstantPathNode.new(
|
1256
|
-
source, load_optional_node,
|
1266
|
+
source, load_optional_node, load_optional_constant, load_location, load_location, location)
|
1257
1267
|
},
|
1258
1268
|
-> {
|
1259
1269
|
location = load_location
|
@@ -1268,7 +1278,7 @@ module Prism
|
|
1268
1278
|
-> {
|
1269
1279
|
location = load_location
|
1270
1280
|
ConstantPathTargetNode.new(
|
1271
|
-
source, load_optional_node,
|
1281
|
+
source, load_optional_node, load_optional_constant, load_location, load_location, location)
|
1272
1282
|
},
|
1273
1283
|
-> {
|
1274
1284
|
location = load_location
|
@@ -1724,7 +1734,7 @@ module Prism
|
|
1724
1734
|
-> {
|
1725
1735
|
location = load_location
|
1726
1736
|
ReturnNode.new(
|
1727
|
-
source, load_location, load_optional_node, location)
|
1737
|
+
source, load_varuint, load_location, load_optional_node, location)
|
1728
1738
|
},
|
1729
1739
|
-> {
|
1730
1740
|
location = load_location
|