prism 0.26.0 → 0.28.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 +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
|