prism 1.4.0 → 1.8.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 +89 -1
- data/Makefile +14 -6
- data/README.md +3 -1
- data/config.yml +294 -41
- data/docs/build_system.md +2 -2
- data/docs/cruby_compilation.md +1 -1
- data/docs/design.md +2 -2
- data/docs/parser_translation.md +8 -23
- data/docs/releasing.md +4 -25
- data/docs/ripper_translation.md +1 -1
- data/docs/ruby_api.md +1 -0
- data/ext/prism/api_node.c +9 -3
- data/ext/prism/extconf.rb +1 -1
- data/ext/prism/extension.c +24 -3
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +360 -70
- data/include/prism/diagnostic.h +7 -0
- data/include/prism/options.h +49 -3
- data/include/prism/parser.h +3 -0
- data/include/prism/regexp.h +2 -2
- data/include/prism/util/pm_buffer.h +8 -0
- data/include/prism/util/pm_integer.h +4 -0
- data/include/prism/util/pm_list.h +6 -0
- data/include/prism/util/pm_string.h +12 -2
- data/include/prism/version.h +2 -2
- data/include/prism.h +40 -15
- data/lib/prism/compiler.rb +457 -152
- data/lib/prism/desugar_compiler.rb +1 -0
- data/lib/prism/dispatcher.rb +16 -0
- data/lib/prism/dot_visitor.rb +10 -1
- data/lib/prism/dsl.rb +5 -2
- data/lib/prism/ffi.rb +28 -10
- data/lib/prism/inspect_visitor.rb +4 -0
- data/lib/prism/lex_compat.rb +18 -75
- data/lib/prism/lex_ripper.rb +64 -0
- data/lib/prism/mutation_compiler.rb +3 -0
- data/lib/prism/node.rb +1663 -350
- data/lib/prism/node_ext.rb +4 -1
- data/lib/prism/pack.rb +2 -0
- data/lib/prism/parse_result/comments.rb +1 -0
- data/lib/prism/parse_result/errors.rb +1 -0
- data/lib/prism/parse_result/newlines.rb +1 -0
- data/lib/prism/parse_result.rb +3 -15
- data/lib/prism/pattern.rb +1 -0
- data/lib/prism/polyfill/scan_byte.rb +14 -0
- data/lib/prism/polyfill/warn.rb +36 -0
- data/lib/prism/reflection.rb +4 -1
- data/lib/prism/relocation.rb +1 -0
- data/lib/prism/serialize.rb +30 -22
- data/lib/prism/string_query.rb +1 -0
- data/lib/prism/translation/parser/builder.rb +1 -0
- data/lib/prism/translation/parser/compiler.rb +63 -41
- data/lib/prism/translation/parser/lexer.rb +29 -21
- data/lib/prism/translation/parser.rb +25 -4
- data/lib/prism/translation/parser_current.rb +26 -0
- data/lib/prism/translation/parser_versions.rb +36 -0
- data/lib/prism/translation/ripper/lexer.rb +46 -0
- data/lib/prism/translation/ripper/sexp.rb +1 -0
- data/lib/prism/translation/ripper.rb +44 -5
- data/lib/prism/translation/ruby_parser.rb +341 -23
- data/lib/prism/translation.rb +7 -3
- data/lib/prism/visitor.rb +458 -153
- data/lib/prism.rb +23 -1
- data/prism.gemspec +9 -7
- data/rbi/prism/dsl.rbi +6 -6
- data/rbi/prism/node.rbi +42 -17
- data/rbi/prism/translation/parser_versions.rbi +23 -0
- data/sig/prism/dispatcher.rbs +3 -0
- data/sig/prism/dsl.rbs +5 -5
- data/sig/prism/node.rbs +463 -38
- data/sig/prism/node_ext.rbs +84 -17
- data/sig/prism/parse_result/comments.rbs +38 -0
- data/sig/prism/parse_result.rbs +4 -0
- data/sig/prism/reflection.rbs +1 -1
- data/sig/prism.rbs +4 -0
- data/src/diagnostic.c +13 -1
- data/src/encoding.c +172 -67
- data/src/node.c +11 -0
- data/src/options.c +17 -7
- data/src/prettyprint.c +18 -0
- data/src/prism.c +1533 -2038
- data/src/serialize.c +9 -1
- data/src/token_type.c +38 -36
- data/src/util/pm_constant_pool.c +1 -1
- data/src/util/pm_string.c +6 -8
- metadata +11 -9
- data/lib/prism/translation/parser33.rb +0 -12
- data/lib/prism/translation/parser34.rb +0 -12
- data/lib/prism/translation/parser35.rb +0 -12
- data/rbi/prism/translation/parser33.rbi +0 -6
- data/rbi/prism/translation/parser34.rbi +0 -6
- data/rbi/prism/translation/parser35.rbi +0 -6
data/lib/prism/dispatcher.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
2
3
|
|
|
3
4
|
=begin
|
|
5
|
+
--
|
|
4
6
|
This file is generated by the templates/template.rb script and should not be
|
|
5
7
|
modified manually. See templates/lib/prism/dispatcher.rb.erb
|
|
6
8
|
if you are looking to modify the template
|
|
9
|
+
++
|
|
7
10
|
=end
|
|
8
11
|
|
|
9
12
|
module Prism
|
|
@@ -52,6 +55,19 @@ module Prism
|
|
|
52
55
|
#
|
|
53
56
|
# def register: (Listener, *Symbol) -> void
|
|
54
57
|
def register(listener, *events)
|
|
58
|
+
register_events(listener, events)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Register all public methods of a listener that match the pattern
|
|
62
|
+
# `on_<node_name>_(enter|leave)`.
|
|
63
|
+
#
|
|
64
|
+
# def register_public_methods: (Listener) -> void
|
|
65
|
+
def register_public_methods(listener)
|
|
66
|
+
register_events(listener, listener.public_methods(false).grep(/\Aon_.+_(?:enter|leave)\z/))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Register a listener for the given events.
|
|
70
|
+
private def register_events(listener, events)
|
|
55
71
|
events.each { |event| (listeners[event] ||= []) << listener }
|
|
56
72
|
end
|
|
57
73
|
|
data/lib/prism/dot_visitor.rb
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
2
3
|
|
|
3
4
|
=begin
|
|
5
|
+
--
|
|
4
6
|
This file is generated by the templates/template.rb script and should not be
|
|
5
7
|
modified manually. See templates/lib/prism/dot_visitor.rb.erb
|
|
6
8
|
if you are looking to modify the template
|
|
9
|
+
++
|
|
7
10
|
=end
|
|
8
11
|
|
|
9
|
-
require "cgi"
|
|
12
|
+
require "cgi/escape"
|
|
13
|
+
require "cgi/util" unless defined?(CGI::EscapeExt)
|
|
10
14
|
|
|
11
15
|
module Prism
|
|
12
16
|
# This visitor provides the ability to call Node#to_dot, which converts a
|
|
@@ -720,6 +724,11 @@ module Prism
|
|
|
720
724
|
table.field("closing_loc", location_inspect(closing_loc))
|
|
721
725
|
end
|
|
722
726
|
|
|
727
|
+
# equal_loc
|
|
728
|
+
unless (equal_loc = node.equal_loc).nil?
|
|
729
|
+
table.field("equal_loc", location_inspect(equal_loc))
|
|
730
|
+
end
|
|
731
|
+
|
|
723
732
|
# block
|
|
724
733
|
unless (block = node.block).nil?
|
|
725
734
|
table.field("block", port: true)
|
data/lib/prism/dsl.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
2
3
|
|
|
3
4
|
=begin
|
|
5
|
+
--
|
|
4
6
|
This file is generated by the templates/template.rb script and should not be
|
|
5
7
|
modified manually. See templates/lib/prism/dsl.rb.erb
|
|
6
8
|
if you are looking to modify the template
|
|
9
|
+
++
|
|
7
10
|
=end
|
|
8
11
|
|
|
9
12
|
module Prism
|
|
@@ -164,8 +167,8 @@ module Prism
|
|
|
164
167
|
end
|
|
165
168
|
|
|
166
169
|
# Create a new CallNode node.
|
|
167
|
-
def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, block: nil)
|
|
168
|
-
CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block)
|
|
170
|
+
def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, equal_loc: nil, block: nil)
|
|
171
|
+
CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, equal_loc, block)
|
|
169
172
|
end
|
|
170
173
|
|
|
171
174
|
# Create a new CallOperatorWriteNode node.
|
data/lib/prism/ffi.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
2
3
|
# typed: ignore
|
|
3
4
|
|
|
4
5
|
# This file is responsible for mirroring the API provided by the C extension by
|
|
@@ -7,6 +8,10 @@
|
|
|
7
8
|
require "rbconfig"
|
|
8
9
|
require "ffi"
|
|
9
10
|
|
|
11
|
+
# We want to eagerly load this file if there are Ractors so that it does not get
|
|
12
|
+
# autoloaded from within a non-main Ractor.
|
|
13
|
+
require "prism/serialize" if defined?(Ractor)
|
|
14
|
+
|
|
10
15
|
module Prism
|
|
11
16
|
module LibRubyParser # :nodoc:
|
|
12
17
|
extend FFI::Library
|
|
@@ -81,6 +86,7 @@ module Prism
|
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
callback :pm_parse_stream_fgets_t, [:pointer, :int, :pointer], :pointer
|
|
89
|
+
callback :pm_parse_stream_feof_t, [:pointer], :int
|
|
84
90
|
enum :pm_string_init_result_t, %i[PM_STRING_INIT_SUCCESS PM_STRING_INIT_ERROR_GENERIC PM_STRING_INIT_ERROR_DIRECTORY]
|
|
85
91
|
enum :pm_string_query_t, [:PM_STRING_QUERY_ERROR, -1, :PM_STRING_QUERY_FALSE, :PM_STRING_QUERY_TRUE]
|
|
86
92
|
|
|
@@ -96,7 +102,7 @@ module Prism
|
|
|
96
102
|
"pm_string_query_local",
|
|
97
103
|
"pm_string_query_constant",
|
|
98
104
|
"pm_string_query_method_name",
|
|
99
|
-
[:pm_parse_stream_fgets_t]
|
|
105
|
+
[:pm_parse_stream_fgets_t, :pm_parse_stream_feof_t]
|
|
100
106
|
)
|
|
101
107
|
|
|
102
108
|
load_exported_functions_from(
|
|
@@ -159,6 +165,9 @@ module Prism
|
|
|
159
165
|
class PrismString # :nodoc:
|
|
160
166
|
SIZEOF = LibRubyParser.pm_string_sizeof
|
|
161
167
|
|
|
168
|
+
PLATFORM_EXPECTS_UTF8 =
|
|
169
|
+
RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince|darwin/i)
|
|
170
|
+
|
|
162
171
|
attr_reader :pointer, :length
|
|
163
172
|
|
|
164
173
|
def initialize(pointer, length, from_string)
|
|
@@ -193,8 +202,7 @@ module Prism
|
|
|
193
202
|
# On Windows and Mac, it's expected that filepaths will be encoded in
|
|
194
203
|
# UTF-8. If they are not, we need to convert them to UTF-8 before
|
|
195
204
|
# passing them into pm_string_mapped_init.
|
|
196
|
-
if
|
|
197
|
-
(encoding = filepath.encoding) != Encoding::ASCII_8BIT && encoding != Encoding::UTF_8
|
|
205
|
+
if PLATFORM_EXPECTS_UTF8 && (encoding = filepath.encoding) != Encoding::ASCII_8BIT && encoding != Encoding::UTF_8
|
|
198
206
|
filepath = filepath.encode(Encoding::UTF_8)
|
|
199
207
|
end
|
|
200
208
|
|
|
@@ -223,7 +231,7 @@ module Prism
|
|
|
223
231
|
private_constant :LibRubyParser
|
|
224
232
|
|
|
225
233
|
# The version constant is set by reading the result of calling pm_version.
|
|
226
|
-
VERSION = LibRubyParser.pm_version.read_string
|
|
234
|
+
VERSION = LibRubyParser.pm_version.read_string.freeze
|
|
227
235
|
|
|
228
236
|
class << self
|
|
229
237
|
# Mirror the Prism.dump API by using the serialization API.
|
|
@@ -274,12 +282,14 @@ module Prism
|
|
|
274
282
|
end
|
|
275
283
|
}
|
|
276
284
|
|
|
285
|
+
eof_callback = -> (_) { stream.eof? }
|
|
286
|
+
|
|
277
287
|
# In the pm_serialize_parse_stream function it accepts a pointer to the
|
|
278
288
|
# IO object as a void* and then passes it through to the callback as the
|
|
279
289
|
# third argument, but it never touches it itself. As such, since we have
|
|
280
290
|
# access to the IO object already through the closure of the lambda, we
|
|
281
291
|
# can pass a null pointer here and not worry.
|
|
282
|
-
LibRubyParser.pm_serialize_parse_stream(buffer.pointer, nil, callback, dump_options(options))
|
|
292
|
+
LibRubyParser.pm_serialize_parse_stream(buffer.pointer, nil, callback, eof_callback, dump_options(options))
|
|
283
293
|
Prism.load(source, buffer.read, options.fetch(:freeze, false))
|
|
284
294
|
end
|
|
285
295
|
end
|
|
@@ -413,17 +423,25 @@ module Prism
|
|
|
413
423
|
|
|
414
424
|
# Return the value that should be dumped for the version option.
|
|
415
425
|
def dump_options_version(version)
|
|
416
|
-
|
|
426
|
+
current = version == "current"
|
|
427
|
+
|
|
428
|
+
case current ? RUBY_VERSION : version
|
|
417
429
|
when nil, "latest"
|
|
418
|
-
0
|
|
430
|
+
0 # Handled in pm_parser_init
|
|
419
431
|
when /\A3\.3(\.\d+)?\z/
|
|
420
432
|
1
|
|
421
433
|
when /\A3\.4(\.\d+)?\z/
|
|
422
434
|
2
|
|
423
|
-
when /\A3\.5(\.\d+)?\z/
|
|
424
|
-
|
|
435
|
+
when /\A3\.5(\.\d+)?\z/, /\A4\.0(\.\d+)?\z/
|
|
436
|
+
3
|
|
437
|
+
when /\A4\.1(\.\d+)?\z/
|
|
438
|
+
4
|
|
425
439
|
else
|
|
426
|
-
|
|
440
|
+
if current
|
|
441
|
+
raise CurrentVersionError, RUBY_VERSION
|
|
442
|
+
else
|
|
443
|
+
raise ArgumentError, "invalid version: #{version}"
|
|
444
|
+
end
|
|
427
445
|
end
|
|
428
446
|
end
|
|
429
447
|
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
2
3
|
|
|
3
4
|
=begin
|
|
5
|
+
--
|
|
4
6
|
This file is generated by the templates/template.rb script and should not be
|
|
5
7
|
modified manually. See templates/lib/prism/inspect_visitor.rb.erb
|
|
6
8
|
if you are looking to modify the template
|
|
9
|
+
++
|
|
7
10
|
=end
|
|
8
11
|
|
|
9
12
|
module Prism
|
|
@@ -399,6 +402,7 @@ module Prism
|
|
|
399
402
|
commands << [arguments, "#{indent}│ "]
|
|
400
403
|
end
|
|
401
404
|
commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
|
|
405
|
+
commands << ["├── equal_loc: #{inspect_location(node.equal_loc)}\n", indent]
|
|
402
406
|
if (block = node.block).nil?
|
|
403
407
|
commands << ["└── block: ∅\n", indent]
|
|
404
408
|
else
|
data/lib/prism/lex_compat.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
2
3
|
|
|
3
4
|
require "delegate"
|
|
4
|
-
require "ripper"
|
|
5
5
|
|
|
6
6
|
module Prism
|
|
7
7
|
# This class is responsible for lexing the source using prism and then
|
|
@@ -248,8 +248,8 @@ module Prism
|
|
|
248
248
|
class IdentToken < Token
|
|
249
249
|
def ==(other) # :nodoc:
|
|
250
250
|
(self[0...-1] == other[0...-1]) && (
|
|
251
|
-
(other[3] == Ripper::EXPR_LABEL | Ripper::EXPR_END) ||
|
|
252
|
-
(other[3] & Ripper::
|
|
251
|
+
(other[3] == Translation::Ripper::EXPR_LABEL | Translation::Ripper::EXPR_END) ||
|
|
252
|
+
(other[3] & (Translation::Ripper::EXPR_ARG | Translation::Ripper::EXPR_CMDARG) != 0)
|
|
253
253
|
)
|
|
254
254
|
end
|
|
255
255
|
end
|
|
@@ -260,8 +260,8 @@ module Prism
|
|
|
260
260
|
def ==(other) # :nodoc:
|
|
261
261
|
return false unless self[0...-1] == other[0...-1]
|
|
262
262
|
|
|
263
|
-
if self[3] == Ripper::EXPR_ARG | Ripper::EXPR_LABELED
|
|
264
|
-
other[3] & Ripper::EXPR_ARG | Ripper::EXPR_LABELED != 0
|
|
263
|
+
if self[3] == Translation::Ripper::EXPR_ARG | Translation::Ripper::EXPR_LABELED
|
|
264
|
+
other[3] & Translation::Ripper::EXPR_ARG | Translation::Ripper::EXPR_LABELED != 0
|
|
265
265
|
else
|
|
266
266
|
self[3] == other[3]
|
|
267
267
|
end
|
|
@@ -279,8 +279,8 @@ module Prism
|
|
|
279
279
|
class ParamToken < Token
|
|
280
280
|
def ==(other) # :nodoc:
|
|
281
281
|
(self[0...-1] == other[0...-1]) && (
|
|
282
|
-
(other[3] == Ripper::EXPR_END) ||
|
|
283
|
-
(other[3] == Ripper::EXPR_END | Ripper::EXPR_LABEL)
|
|
282
|
+
(other[3] == Translation::Ripper::EXPR_END) ||
|
|
283
|
+
(other[3] == Translation::Ripper::EXPR_END | Translation::Ripper::EXPR_LABEL)
|
|
284
284
|
)
|
|
285
285
|
end
|
|
286
286
|
end
|
|
@@ -614,6 +614,11 @@ module Prism
|
|
|
614
614
|
|
|
615
615
|
private_constant :Heredoc
|
|
616
616
|
|
|
617
|
+
# In previous versions of Ruby, Ripper wouldn't flush the bom before the
|
|
618
|
+
# first token, so we had to have a hack in place to account for that.
|
|
619
|
+
BOM_FLUSHED = RUBY_VERSION >= "3.3.0"
|
|
620
|
+
private_constant :BOM_FLUSHED
|
|
621
|
+
|
|
617
622
|
attr_reader :source, :options
|
|
618
623
|
|
|
619
624
|
def initialize(source, **options)
|
|
@@ -629,13 +634,9 @@ module Prism
|
|
|
629
634
|
|
|
630
635
|
result = Prism.lex(source, **options)
|
|
631
636
|
result_value = result.value
|
|
632
|
-
previous_state = nil #:
|
|
637
|
+
previous_state = nil #: State?
|
|
633
638
|
last_heredoc_end = nil #: Integer?
|
|
634
639
|
|
|
635
|
-
# In previous versions of Ruby, Ripper wouldn't flush the bom before the
|
|
636
|
-
# first token, so we had to have a hack in place to account for that. This
|
|
637
|
-
# checks for that behavior.
|
|
638
|
-
bom_flushed = Ripper.lex("\xEF\xBB\xBF# test")[0][0][1] == 0
|
|
639
640
|
bom = source.byteslice(0..2) == "\xEF\xBB\xBF"
|
|
640
641
|
|
|
641
642
|
result_value.each_with_index do |(token, lex_state), index|
|
|
@@ -650,7 +651,7 @@ module Prism
|
|
|
650
651
|
if bom && lineno == 1
|
|
651
652
|
column -= 3
|
|
652
653
|
|
|
653
|
-
if index == 0 && column == 0 && !
|
|
654
|
+
if index == 0 && column == 0 && !BOM_FLUSHED
|
|
654
655
|
flushed =
|
|
655
656
|
case token.type
|
|
656
657
|
when :BACK_REFERENCE, :INSTANCE_VARIABLE, :CLASS_VARIABLE,
|
|
@@ -674,7 +675,7 @@ module Prism
|
|
|
674
675
|
|
|
675
676
|
event = RIPPER.fetch(token.type)
|
|
676
677
|
value = token.value
|
|
677
|
-
lex_state = Ripper::Lexer::State.new(lex_state)
|
|
678
|
+
lex_state = Translation::Ripper::Lexer::State.new(lex_state)
|
|
678
679
|
|
|
679
680
|
token =
|
|
680
681
|
case event
|
|
@@ -688,7 +689,7 @@ module Prism
|
|
|
688
689
|
last_heredoc_end = token.location.end_offset
|
|
689
690
|
IgnoreStateToken.new([[lineno, column], event, value, lex_state])
|
|
690
691
|
when :on_ident
|
|
691
|
-
if lex_state == Ripper::EXPR_END
|
|
692
|
+
if lex_state == Translation::Ripper::EXPR_END
|
|
692
693
|
# If we have an identifier that follows a method name like:
|
|
693
694
|
#
|
|
694
695
|
# def foo bar
|
|
@@ -698,7 +699,7 @@ module Prism
|
|
|
698
699
|
# yet. We do this more accurately, so we need to allow comparing
|
|
699
700
|
# against both END and END|LABEL.
|
|
700
701
|
ParamToken.new([[lineno, column], event, value, lex_state])
|
|
701
|
-
elsif lex_state == Ripper::EXPR_END | Ripper::EXPR_LABEL
|
|
702
|
+
elsif lex_state == Translation::Ripper::EXPR_END | Translation::Ripper::EXPR_LABEL
|
|
702
703
|
# In the event that we're comparing identifiers, we're going to
|
|
703
704
|
# allow a little divergence. Ripper doesn't account for local
|
|
704
705
|
# variables introduced through named captures in regexes, and we
|
|
@@ -738,7 +739,7 @@ module Prism
|
|
|
738
739
|
counter += { on_embexpr_beg: -1, on_embexpr_end: 1 }[current_event] || 0
|
|
739
740
|
end
|
|
740
741
|
|
|
741
|
-
Ripper::Lexer::State.new(result_value[current_index][1])
|
|
742
|
+
Translation::Ripper::Lexer::State.new(result_value[current_index][1])
|
|
742
743
|
else
|
|
743
744
|
previous_state
|
|
744
745
|
end
|
|
@@ -866,62 +867,4 @@ module Prism
|
|
|
866
867
|
end
|
|
867
868
|
|
|
868
869
|
private_constant :LexCompat
|
|
869
|
-
|
|
870
|
-
# This is a class that wraps the Ripper lexer to produce almost exactly the
|
|
871
|
-
# same tokens.
|
|
872
|
-
class LexRipper # :nodoc:
|
|
873
|
-
attr_reader :source
|
|
874
|
-
|
|
875
|
-
def initialize(source)
|
|
876
|
-
@source = source
|
|
877
|
-
end
|
|
878
|
-
|
|
879
|
-
def result
|
|
880
|
-
previous = [] #: [[Integer, Integer], Symbol, String, untyped] | []
|
|
881
|
-
results = [] #: Array[[[Integer, Integer], Symbol, String, untyped]]
|
|
882
|
-
|
|
883
|
-
lex(source).each do |token|
|
|
884
|
-
case token[1]
|
|
885
|
-
when :on_sp
|
|
886
|
-
# skip
|
|
887
|
-
when :on_tstring_content
|
|
888
|
-
if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
|
|
889
|
-
previous[2] << token[2]
|
|
890
|
-
else
|
|
891
|
-
results << token
|
|
892
|
-
previous = token
|
|
893
|
-
end
|
|
894
|
-
when :on_words_sep
|
|
895
|
-
if previous[1] == :on_words_sep
|
|
896
|
-
previous[2] << token[2]
|
|
897
|
-
else
|
|
898
|
-
results << token
|
|
899
|
-
previous = token
|
|
900
|
-
end
|
|
901
|
-
else
|
|
902
|
-
results << token
|
|
903
|
-
previous = token
|
|
904
|
-
end
|
|
905
|
-
end
|
|
906
|
-
|
|
907
|
-
results
|
|
908
|
-
end
|
|
909
|
-
|
|
910
|
-
private
|
|
911
|
-
|
|
912
|
-
if Ripper.method(:lex).parameters.assoc(:keyrest)
|
|
913
|
-
def lex(source)
|
|
914
|
-
Ripper.lex(source, raise_errors: true)
|
|
915
|
-
end
|
|
916
|
-
else
|
|
917
|
-
def lex(source)
|
|
918
|
-
ripper = Ripper::Lexer.new(source)
|
|
919
|
-
ripper.lex.tap do |result|
|
|
920
|
-
raise SyntaxError, ripper.errors.map(&:message).join(' ;') if ripper.errors.any?
|
|
921
|
-
end
|
|
922
|
-
end
|
|
923
|
-
end
|
|
924
|
-
end
|
|
925
|
-
|
|
926
|
-
private_constant :LexRipper
|
|
927
870
|
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
3
|
+
|
|
4
|
+
require "ripper"
|
|
5
|
+
|
|
6
|
+
module Prism
|
|
7
|
+
# This is a class that wraps the Ripper lexer to produce almost exactly the
|
|
8
|
+
# same tokens.
|
|
9
|
+
class LexRipper # :nodoc:
|
|
10
|
+
attr_reader :source
|
|
11
|
+
|
|
12
|
+
def initialize(source)
|
|
13
|
+
@source = source
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def result
|
|
17
|
+
previous = [] #: [[Integer, Integer], Symbol, String, untyped] | []
|
|
18
|
+
results = [] #: Array[[[Integer, Integer], Symbol, String, untyped]]
|
|
19
|
+
|
|
20
|
+
lex(source).each do |token|
|
|
21
|
+
case token[1]
|
|
22
|
+
when :on_sp
|
|
23
|
+
# skip
|
|
24
|
+
when :on_tstring_content
|
|
25
|
+
if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
|
|
26
|
+
previous[2] << token[2]
|
|
27
|
+
else
|
|
28
|
+
results << token
|
|
29
|
+
previous = token
|
|
30
|
+
end
|
|
31
|
+
when :on_words_sep
|
|
32
|
+
if previous[1] == :on_words_sep
|
|
33
|
+
previous[2] << token[2]
|
|
34
|
+
else
|
|
35
|
+
results << token
|
|
36
|
+
previous = token
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
results << token
|
|
40
|
+
previous = token
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
results
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
if Ripper.method(:lex).parameters.assoc(:keyrest)
|
|
50
|
+
def lex(source)
|
|
51
|
+
Ripper.lex(source, raise_errors: true)
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
def lex(source)
|
|
55
|
+
ripper = Ripper::Lexer.new(source)
|
|
56
|
+
ripper.lex.tap do |result|
|
|
57
|
+
raise SyntaxError, ripper.errors.map(&:message).join(' ;') if ripper.errors.any?
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private_constant :LexRipper
|
|
64
|
+
end
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
2
3
|
|
|
3
4
|
=begin
|
|
5
|
+
--
|
|
4
6
|
This file is generated by the templates/template.rb script and should not be
|
|
5
7
|
modified manually. See templates/lib/prism/mutation_compiler.rb.erb
|
|
6
8
|
if you are looking to modify the template
|
|
9
|
+
++
|
|
7
10
|
=end
|
|
8
11
|
|
|
9
12
|
module Prism
|