ed-precompiled_prism 1.5.2-arm64-darwin
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 +7 -0
- data/BSDmakefile +58 -0
- data/CHANGELOG.md +723 -0
- data/CODE_OF_CONDUCT.md +76 -0
- data/CONTRIBUTING.md +58 -0
- data/LICENSE.md +7 -0
- data/Makefile +110 -0
- data/README.md +143 -0
- data/config.yml +4714 -0
- data/docs/build_system.md +119 -0
- data/docs/configuration.md +68 -0
- data/docs/cruby_compilation.md +27 -0
- data/docs/design.md +53 -0
- data/docs/encoding.md +121 -0
- data/docs/fuzzing.md +88 -0
- data/docs/heredocs.md +36 -0
- data/docs/javascript.md +118 -0
- data/docs/local_variable_depth.md +229 -0
- data/docs/mapping.md +117 -0
- data/docs/parser_translation.md +24 -0
- data/docs/parsing_rules.md +22 -0
- data/docs/releasing.md +98 -0
- data/docs/relocation.md +34 -0
- data/docs/ripper_translation.md +72 -0
- data/docs/ruby_api.md +44 -0
- data/docs/ruby_parser_translation.md +19 -0
- data/docs/serialization.md +233 -0
- data/docs/testing.md +55 -0
- data/ext/prism/api_node.c +6941 -0
- data/ext/prism/api_pack.c +276 -0
- data/ext/prism/extconf.rb +127 -0
- data/ext/prism/extension.c +1419 -0
- data/ext/prism/extension.h +19 -0
- data/include/prism/ast.h +8220 -0
- data/include/prism/defines.h +260 -0
- data/include/prism/diagnostic.h +456 -0
- data/include/prism/encoding.h +283 -0
- data/include/prism/node.h +129 -0
- data/include/prism/options.h +482 -0
- data/include/prism/pack.h +163 -0
- data/include/prism/parser.h +933 -0
- data/include/prism/prettyprint.h +34 -0
- data/include/prism/regexp.h +43 -0
- data/include/prism/static_literals.h +121 -0
- data/include/prism/util/pm_buffer.h +236 -0
- data/include/prism/util/pm_char.h +204 -0
- data/include/prism/util/pm_constant_pool.h +218 -0
- data/include/prism/util/pm_integer.h +130 -0
- data/include/prism/util/pm_list.h +103 -0
- data/include/prism/util/pm_memchr.h +29 -0
- data/include/prism/util/pm_newline_list.h +113 -0
- data/include/prism/util/pm_string.h +200 -0
- data/include/prism/util/pm_strncasecmp.h +32 -0
- data/include/prism/util/pm_strpbrk.h +46 -0
- data/include/prism/version.h +29 -0
- data/include/prism.h +408 -0
- data/lib/prism/3.0/prism.bundle +0 -0
- data/lib/prism/3.1/prism.bundle +0 -0
- data/lib/prism/3.2/prism.bundle +0 -0
- data/lib/prism/3.3/prism.bundle +0 -0
- data/lib/prism/3.4/prism.bundle +0 -0
- data/lib/prism/compiler.rb +801 -0
- data/lib/prism/desugar_compiler.rb +392 -0
- data/lib/prism/dispatcher.rb +2210 -0
- data/lib/prism/dot_visitor.rb +4762 -0
- data/lib/prism/dsl.rb +1003 -0
- data/lib/prism/ffi.rb +570 -0
- data/lib/prism/inspect_visitor.rb +2392 -0
- data/lib/prism/lex_compat.rb +928 -0
- data/lib/prism/mutation_compiler.rb +772 -0
- data/lib/prism/node.rb +18816 -0
- data/lib/prism/node_ext.rb +511 -0
- data/lib/prism/pack.rb +230 -0
- data/lib/prism/parse_result/comments.rb +188 -0
- data/lib/prism/parse_result/errors.rb +66 -0
- data/lib/prism/parse_result/newlines.rb +155 -0
- data/lib/prism/parse_result.rb +911 -0
- data/lib/prism/pattern.rb +269 -0
- data/lib/prism/polyfill/append_as_bytes.rb +15 -0
- data/lib/prism/polyfill/byteindex.rb +13 -0
- data/lib/prism/polyfill/scan_byte.rb +14 -0
- data/lib/prism/polyfill/unpack1.rb +14 -0
- data/lib/prism/polyfill/warn.rb +36 -0
- data/lib/prism/reflection.rb +416 -0
- data/lib/prism/relocation.rb +505 -0
- data/lib/prism/serialize.rb +2398 -0
- data/lib/prism/string_query.rb +31 -0
- data/lib/prism/translation/parser/builder.rb +62 -0
- data/lib/prism/translation/parser/compiler.rb +2234 -0
- data/lib/prism/translation/parser/lexer.rb +820 -0
- data/lib/prism/translation/parser.rb +374 -0
- data/lib/prism/translation/parser33.rb +13 -0
- data/lib/prism/translation/parser34.rb +13 -0
- data/lib/prism/translation/parser35.rb +13 -0
- data/lib/prism/translation/parser_current.rb +24 -0
- data/lib/prism/translation/ripper/sexp.rb +126 -0
- data/lib/prism/translation/ripper/shim.rb +5 -0
- data/lib/prism/translation/ripper.rb +3474 -0
- data/lib/prism/translation/ruby_parser.rb +1929 -0
- data/lib/prism/translation.rb +16 -0
- data/lib/prism/visitor.rb +813 -0
- data/lib/prism.rb +97 -0
- data/prism.gemspec +174 -0
- data/rbi/prism/compiler.rbi +12 -0
- data/rbi/prism/dsl.rbi +524 -0
- data/rbi/prism/inspect_visitor.rbi +12 -0
- data/rbi/prism/node.rbi +8734 -0
- data/rbi/prism/node_ext.rbi +107 -0
- data/rbi/prism/parse_result.rbi +404 -0
- data/rbi/prism/reflection.rbi +58 -0
- data/rbi/prism/string_query.rbi +12 -0
- data/rbi/prism/translation/parser.rbi +11 -0
- data/rbi/prism/translation/parser33.rbi +6 -0
- data/rbi/prism/translation/parser34.rbi +6 -0
- data/rbi/prism/translation/parser35.rbi +6 -0
- data/rbi/prism/translation/ripper.rbi +15 -0
- data/rbi/prism/visitor.rbi +473 -0
- data/rbi/prism.rbi +66 -0
- data/sig/prism/compiler.rbs +9 -0
- data/sig/prism/dispatcher.rbs +19 -0
- data/sig/prism/dot_visitor.rbs +6 -0
- data/sig/prism/dsl.rbs +351 -0
- data/sig/prism/inspect_visitor.rbs +22 -0
- data/sig/prism/lex_compat.rbs +10 -0
- data/sig/prism/mutation_compiler.rbs +159 -0
- data/sig/prism/node.rbs +4028 -0
- data/sig/prism/node_ext.rbs +149 -0
- data/sig/prism/pack.rbs +43 -0
- data/sig/prism/parse_result/comments.rbs +38 -0
- data/sig/prism/parse_result.rbs +196 -0
- data/sig/prism/pattern.rbs +13 -0
- data/sig/prism/reflection.rbs +50 -0
- data/sig/prism/relocation.rbs +185 -0
- data/sig/prism/serialize.rbs +8 -0
- data/sig/prism/string_query.rbs +11 -0
- data/sig/prism/visitor.rbs +169 -0
- data/sig/prism.rbs +254 -0
- data/src/diagnostic.c +850 -0
- data/src/encoding.c +5235 -0
- data/src/node.c +8676 -0
- data/src/options.c +328 -0
- data/src/pack.c +509 -0
- data/src/prettyprint.c +8941 -0
- data/src/prism.c +23361 -0
- data/src/regexp.c +790 -0
- data/src/serialize.c +2268 -0
- data/src/static_literals.c +617 -0
- data/src/token_type.c +703 -0
- data/src/util/pm_buffer.c +357 -0
- data/src/util/pm_char.c +318 -0
- data/src/util/pm_constant_pool.c +342 -0
- data/src/util/pm_integer.c +670 -0
- data/src/util/pm_list.c +49 -0
- data/src/util/pm_memchr.c +35 -0
- data/src/util/pm_newline_list.c +125 -0
- data/src/util/pm_string.c +381 -0
- data/src/util/pm_strncasecmp.c +36 -0
- data/src/util/pm_strpbrk.c +206 -0
- metadata +202 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
required_version = ">= 3.3.7.2"
|
|
6
|
+
gem "parser", required_version
|
|
7
|
+
require "parser"
|
|
8
|
+
rescue LoadError
|
|
9
|
+
warn(<<~MSG)
|
|
10
|
+
Error: Unable to load parser #{required_version}. \
|
|
11
|
+
Add `gem "parser"` to your Gemfile or run `bundle update parser`.
|
|
12
|
+
MSG
|
|
13
|
+
exit(1)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module Prism
|
|
17
|
+
module Translation
|
|
18
|
+
# This class is the entry-point for converting a prism syntax tree into the
|
|
19
|
+
# whitequark/parser gem's syntax tree. It inherits from the base parser for
|
|
20
|
+
# the parser gem, and overrides the parse* methods to parse with prism and
|
|
21
|
+
# then translate.
|
|
22
|
+
#
|
|
23
|
+
# Note that this version of the parser always parses using the latest
|
|
24
|
+
# version of Ruby syntax supported by Prism. If you want specific version
|
|
25
|
+
# support, use one of the version-specific subclasses, such as
|
|
26
|
+
# `Prism::Translation::Parser34`. If you want to parse using the same
|
|
27
|
+
# version of Ruby syntax as the currently running version of Ruby, use
|
|
28
|
+
# `Prism::Translation::ParserCurrent`.
|
|
29
|
+
class Parser < ::Parser::Base
|
|
30
|
+
Diagnostic = ::Parser::Diagnostic # :nodoc:
|
|
31
|
+
private_constant :Diagnostic
|
|
32
|
+
|
|
33
|
+
# The parser gem has a list of diagnostics with a hard-coded set of error
|
|
34
|
+
# messages. We create our own diagnostic class in order to set our own
|
|
35
|
+
# error messages.
|
|
36
|
+
class PrismDiagnostic < Diagnostic
|
|
37
|
+
# This is the cached message coming from prism.
|
|
38
|
+
attr_reader :message
|
|
39
|
+
|
|
40
|
+
# Initialize a new diagnostic with the given message and location.
|
|
41
|
+
def initialize(message, level, reason, location)
|
|
42
|
+
@message = message
|
|
43
|
+
super(level, reason, {}, location, [])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
Racc_debug_parser = false # :nodoc:
|
|
48
|
+
|
|
49
|
+
# The `builder` argument is used to create the parser using our custom builder class by default.
|
|
50
|
+
#
|
|
51
|
+
# By using the `:parser` keyword argument, you can translate in a way that is compatible with
|
|
52
|
+
# the Parser gem using any parser.
|
|
53
|
+
#
|
|
54
|
+
# For example, in RuboCop for Ruby LSP, the following approach can be used to improve performance
|
|
55
|
+
# by reusing a pre-parsed `Prism::ParseLexResult`:
|
|
56
|
+
#
|
|
57
|
+
# class PrismPreparsed
|
|
58
|
+
# def initialize(prism_result)
|
|
59
|
+
# @prism_result = prism_result
|
|
60
|
+
# end
|
|
61
|
+
#
|
|
62
|
+
# def parse_lex(source, **options)
|
|
63
|
+
# @prism_result
|
|
64
|
+
# end
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
67
|
+
# prism_preparsed = PrismPreparsed.new(prism_result)
|
|
68
|
+
#
|
|
69
|
+
# Prism::Translation::Ruby34.new(builder, parser: prism_preparsed)
|
|
70
|
+
#
|
|
71
|
+
# In an object passed to the `:parser` keyword argument, the `parse` and `parse_lex` methods
|
|
72
|
+
# should be implemented as needed.
|
|
73
|
+
#
|
|
74
|
+
def initialize(builder = Prism::Translation::Parser::Builder.new, parser: Prism)
|
|
75
|
+
if !builder.is_a?(Prism::Translation::Parser::Builder)
|
|
76
|
+
warn(<<~MSG, uplevel: 1, category: :deprecated)
|
|
77
|
+
[deprecation]: The builder passed to `Prism::Translation::Parser.new` is not a \
|
|
78
|
+
`Prism::Translation::Parser::Builder` subclass. This will raise in the next major version.
|
|
79
|
+
MSG
|
|
80
|
+
end
|
|
81
|
+
@parser = parser
|
|
82
|
+
|
|
83
|
+
super(builder)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def version # :nodoc:
|
|
87
|
+
35
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# The default encoding for Ruby files is UTF-8.
|
|
91
|
+
def default_encoding
|
|
92
|
+
Encoding::UTF_8
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def yyerror # :nodoc:
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Parses a source buffer and returns the AST.
|
|
99
|
+
def parse(source_buffer)
|
|
100
|
+
@source_buffer = source_buffer
|
|
101
|
+
source = source_buffer.source
|
|
102
|
+
|
|
103
|
+
offset_cache = build_offset_cache(source)
|
|
104
|
+
result = unwrap(@parser.parse(source, **prism_options), offset_cache)
|
|
105
|
+
|
|
106
|
+
build_ast(result.value, offset_cache)
|
|
107
|
+
ensure
|
|
108
|
+
@source_buffer = nil
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Parses a source buffer and returns the AST and the source code comments.
|
|
112
|
+
def parse_with_comments(source_buffer)
|
|
113
|
+
@source_buffer = source_buffer
|
|
114
|
+
source = source_buffer.source
|
|
115
|
+
|
|
116
|
+
offset_cache = build_offset_cache(source)
|
|
117
|
+
result = unwrap(@parser.parse(source, **prism_options), offset_cache)
|
|
118
|
+
|
|
119
|
+
[
|
|
120
|
+
build_ast(result.value, offset_cache),
|
|
121
|
+
build_comments(result.comments, offset_cache)
|
|
122
|
+
]
|
|
123
|
+
ensure
|
|
124
|
+
@source_buffer = nil
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Parses a source buffer and returns the AST, the source code comments,
|
|
128
|
+
# and the tokens emitted by the lexer.
|
|
129
|
+
def tokenize(source_buffer, recover = false)
|
|
130
|
+
@source_buffer = source_buffer
|
|
131
|
+
source = source_buffer.source
|
|
132
|
+
|
|
133
|
+
offset_cache = build_offset_cache(source)
|
|
134
|
+
result =
|
|
135
|
+
begin
|
|
136
|
+
unwrap(@parser.parse_lex(source, **prism_options), offset_cache)
|
|
137
|
+
rescue ::Parser::SyntaxError
|
|
138
|
+
raise if !recover
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
program, tokens = result.value
|
|
142
|
+
ast = build_ast(program, offset_cache) if result.success?
|
|
143
|
+
|
|
144
|
+
[
|
|
145
|
+
ast,
|
|
146
|
+
build_comments(result.comments, offset_cache),
|
|
147
|
+
build_tokens(tokens, offset_cache)
|
|
148
|
+
]
|
|
149
|
+
ensure
|
|
150
|
+
@source_buffer = nil
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Since prism resolves num params for us, we don't need to support this
|
|
154
|
+
# kind of logic here.
|
|
155
|
+
def try_declare_numparam(node)
|
|
156
|
+
node.children[0].match?(/\A_[1-9]\z/)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
private
|
|
160
|
+
|
|
161
|
+
# This is a hook to allow consumers to disable some errors if they don't
|
|
162
|
+
# want them to block creating the syntax tree.
|
|
163
|
+
def valid_error?(error)
|
|
164
|
+
true
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# This is a hook to allow consumers to disable some warnings if they don't
|
|
168
|
+
# want them to block creating the syntax tree.
|
|
169
|
+
def valid_warning?(warning)
|
|
170
|
+
true
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Build a diagnostic from the given prism parse error.
|
|
174
|
+
def error_diagnostic(error, offset_cache)
|
|
175
|
+
location = error.location
|
|
176
|
+
diagnostic_location = build_range(location, offset_cache)
|
|
177
|
+
|
|
178
|
+
case error.type
|
|
179
|
+
when :argument_block_multi
|
|
180
|
+
Diagnostic.new(:error, :block_and_blockarg, {}, diagnostic_location, [])
|
|
181
|
+
when :argument_formal_constant
|
|
182
|
+
Diagnostic.new(:error, :argument_const, {}, diagnostic_location, [])
|
|
183
|
+
when :argument_formal_class
|
|
184
|
+
Diagnostic.new(:error, :argument_cvar, {}, diagnostic_location, [])
|
|
185
|
+
when :argument_formal_global
|
|
186
|
+
Diagnostic.new(:error, :argument_gvar, {}, diagnostic_location, [])
|
|
187
|
+
when :argument_formal_ivar
|
|
188
|
+
Diagnostic.new(:error, :argument_ivar, {}, diagnostic_location, [])
|
|
189
|
+
when :argument_no_forwarding_amp
|
|
190
|
+
Diagnostic.new(:error, :no_anonymous_blockarg, {}, diagnostic_location, [])
|
|
191
|
+
when :argument_no_forwarding_star
|
|
192
|
+
Diagnostic.new(:error, :no_anonymous_restarg, {}, diagnostic_location, [])
|
|
193
|
+
when :argument_no_forwarding_star_star
|
|
194
|
+
Diagnostic.new(:error, :no_anonymous_kwrestarg, {}, diagnostic_location, [])
|
|
195
|
+
when :begin_lonely_else
|
|
196
|
+
location = location.copy(length: 4)
|
|
197
|
+
diagnostic_location = build_range(location, offset_cache)
|
|
198
|
+
Diagnostic.new(:error, :useless_else, {}, diagnostic_location, [])
|
|
199
|
+
when :class_name, :module_name
|
|
200
|
+
Diagnostic.new(:error, :module_name_const, {}, diagnostic_location, [])
|
|
201
|
+
when :class_in_method
|
|
202
|
+
Diagnostic.new(:error, :class_in_def, {}, diagnostic_location, [])
|
|
203
|
+
when :def_endless_setter
|
|
204
|
+
Diagnostic.new(:error, :endless_setter, {}, diagnostic_location, [])
|
|
205
|
+
when :embdoc_term
|
|
206
|
+
Diagnostic.new(:error, :embedded_document, {}, diagnostic_location, [])
|
|
207
|
+
when :incomplete_variable_class, :incomplete_variable_class_3_3
|
|
208
|
+
location = location.copy(length: location.length + 1)
|
|
209
|
+
diagnostic_location = build_range(location, offset_cache)
|
|
210
|
+
|
|
211
|
+
Diagnostic.new(:error, :cvar_name, { name: location.slice }, diagnostic_location, [])
|
|
212
|
+
when :incomplete_variable_instance, :incomplete_variable_instance_3_3
|
|
213
|
+
location = location.copy(length: location.length + 1)
|
|
214
|
+
diagnostic_location = build_range(location, offset_cache)
|
|
215
|
+
|
|
216
|
+
Diagnostic.new(:error, :ivar_name, { name: location.slice }, diagnostic_location, [])
|
|
217
|
+
when :invalid_variable_global, :invalid_variable_global_3_3
|
|
218
|
+
Diagnostic.new(:error, :gvar_name, { name: location.slice }, diagnostic_location, [])
|
|
219
|
+
when :module_in_method
|
|
220
|
+
Diagnostic.new(:error, :module_in_def, {}, diagnostic_location, [])
|
|
221
|
+
when :numbered_parameter_ordinary
|
|
222
|
+
Diagnostic.new(:error, :ordinary_param_defined, {}, diagnostic_location, [])
|
|
223
|
+
when :numbered_parameter_outer_scope
|
|
224
|
+
Diagnostic.new(:error, :numparam_used_in_outer_scope, {}, diagnostic_location, [])
|
|
225
|
+
when :parameter_circular
|
|
226
|
+
Diagnostic.new(:error, :circular_argument_reference, { var_name: location.slice }, diagnostic_location, [])
|
|
227
|
+
when :parameter_name_repeat
|
|
228
|
+
Diagnostic.new(:error, :duplicate_argument, {}, diagnostic_location, [])
|
|
229
|
+
when :parameter_numbered_reserved
|
|
230
|
+
Diagnostic.new(:error, :reserved_for_numparam, { name: location.slice }, diagnostic_location, [])
|
|
231
|
+
when :regexp_unknown_options
|
|
232
|
+
Diagnostic.new(:error, :regexp_options, { options: location.slice[1..] }, diagnostic_location, [])
|
|
233
|
+
when :singleton_for_literals
|
|
234
|
+
Diagnostic.new(:error, :singleton_literal, {}, diagnostic_location, [])
|
|
235
|
+
when :string_literal_eof
|
|
236
|
+
Diagnostic.new(:error, :string_eof, {}, diagnostic_location, [])
|
|
237
|
+
when :unexpected_token_ignore
|
|
238
|
+
Diagnostic.new(:error, :unexpected_token, { token: location.slice }, diagnostic_location, [])
|
|
239
|
+
when :write_target_in_method
|
|
240
|
+
Diagnostic.new(:error, :dynamic_const, {}, diagnostic_location, [])
|
|
241
|
+
else
|
|
242
|
+
PrismDiagnostic.new(error.message, :error, error.type, diagnostic_location)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Build a diagnostic from the given prism parse warning.
|
|
247
|
+
def warning_diagnostic(warning, offset_cache)
|
|
248
|
+
diagnostic_location = build_range(warning.location, offset_cache)
|
|
249
|
+
|
|
250
|
+
case warning.type
|
|
251
|
+
when :ambiguous_first_argument_plus
|
|
252
|
+
Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "+" }, diagnostic_location, [])
|
|
253
|
+
when :ambiguous_first_argument_minus
|
|
254
|
+
Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "-" }, diagnostic_location, [])
|
|
255
|
+
when :ambiguous_prefix_ampersand
|
|
256
|
+
Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "&" }, diagnostic_location, [])
|
|
257
|
+
when :ambiguous_prefix_star
|
|
258
|
+
Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "*" }, diagnostic_location, [])
|
|
259
|
+
when :ambiguous_prefix_star_star
|
|
260
|
+
Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "**" }, diagnostic_location, [])
|
|
261
|
+
when :ambiguous_slash
|
|
262
|
+
Diagnostic.new(:warning, :ambiguous_regexp, {}, diagnostic_location, [])
|
|
263
|
+
when :dot_dot_dot_eol
|
|
264
|
+
Diagnostic.new(:warning, :triple_dot_at_eol, {}, diagnostic_location, [])
|
|
265
|
+
when :duplicated_hash_key
|
|
266
|
+
# skip, parser does this on its own
|
|
267
|
+
else
|
|
268
|
+
PrismDiagnostic.new(warning.message, :warning, warning.type, diagnostic_location)
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# If there was a error generated during the parse, then raise an
|
|
273
|
+
# appropriate syntax error. Otherwise return the result.
|
|
274
|
+
def unwrap(result, offset_cache)
|
|
275
|
+
result.errors.each do |error|
|
|
276
|
+
next unless valid_error?(error)
|
|
277
|
+
diagnostics.process(error_diagnostic(error, offset_cache))
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
result.warnings.each do |warning|
|
|
281
|
+
next unless valid_warning?(warning)
|
|
282
|
+
diagnostic = warning_diagnostic(warning, offset_cache)
|
|
283
|
+
diagnostics.process(diagnostic) if diagnostic
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
result
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Prism deals with offsets in bytes, while the parser gem deals with
|
|
290
|
+
# offsets in characters. We need to handle this conversion in order to
|
|
291
|
+
# build the parser gem AST.
|
|
292
|
+
#
|
|
293
|
+
# If the bytesize of the source is the same as the length, then we can
|
|
294
|
+
# just use the offset directly. Otherwise, we build an array where the
|
|
295
|
+
# index is the byte offset and the value is the character offset.
|
|
296
|
+
def build_offset_cache(source)
|
|
297
|
+
if source.bytesize == source.length
|
|
298
|
+
-> (offset) { offset }
|
|
299
|
+
else
|
|
300
|
+
offset_cache = []
|
|
301
|
+
offset = 0
|
|
302
|
+
|
|
303
|
+
source.each_char do |char|
|
|
304
|
+
char.bytesize.times { offset_cache << offset }
|
|
305
|
+
offset += 1
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
offset_cache << offset
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Build the parser gem AST from the prism AST.
|
|
313
|
+
def build_ast(program, offset_cache)
|
|
314
|
+
program.accept(Compiler.new(self, offset_cache))
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Build the parser gem comments from the prism comments.
|
|
318
|
+
def build_comments(comments, offset_cache)
|
|
319
|
+
comments.map do |comment|
|
|
320
|
+
::Parser::Source::Comment.new(build_range(comment.location, offset_cache))
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Build the parser gem tokens from the prism tokens.
|
|
325
|
+
def build_tokens(tokens, offset_cache)
|
|
326
|
+
Lexer.new(source_buffer, tokens, offset_cache).to_a
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Build a range from a prism location.
|
|
330
|
+
def build_range(location, offset_cache)
|
|
331
|
+
::Parser::Source::Range.new(
|
|
332
|
+
source_buffer,
|
|
333
|
+
offset_cache[location.start_offset],
|
|
334
|
+
offset_cache[location.end_offset]
|
|
335
|
+
)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# Options for how prism should parse/lex the source.
|
|
339
|
+
def prism_options
|
|
340
|
+
options = {
|
|
341
|
+
filepath: @source_buffer.name,
|
|
342
|
+
version: convert_for_prism(version),
|
|
343
|
+
partial_script: true,
|
|
344
|
+
}
|
|
345
|
+
# The parser gem always encodes to UTF-8, unless it is binary.
|
|
346
|
+
# https://github.com/whitequark/parser/blob/v3.3.6.0/lib/parser/source/buffer.rb#L80-L107
|
|
347
|
+
options[:encoding] = false if @source_buffer.source.encoding != Encoding::BINARY
|
|
348
|
+
|
|
349
|
+
options
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
# Converts the version format handled by Parser to the format handled by Prism.
|
|
353
|
+
def convert_for_prism(version)
|
|
354
|
+
case version
|
|
355
|
+
when 33
|
|
356
|
+
"3.3.1"
|
|
357
|
+
when 34
|
|
358
|
+
"3.4.0"
|
|
359
|
+
when 35
|
|
360
|
+
"3.5.0"
|
|
361
|
+
else
|
|
362
|
+
"latest"
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
require_relative "parser/builder"
|
|
367
|
+
require_relative "parser/compiler"
|
|
368
|
+
require_relative "parser/lexer"
|
|
369
|
+
|
|
370
|
+
private_constant :Compiler
|
|
371
|
+
private_constant :Lexer
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
3
|
+
# typed: ignore
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
module Prism
|
|
7
|
+
module Translation
|
|
8
|
+
case RUBY_VERSION
|
|
9
|
+
when /^3\.3\./
|
|
10
|
+
ParserCurrent = Parser33
|
|
11
|
+
when /^3\.4\./
|
|
12
|
+
ParserCurrent = Parser34
|
|
13
|
+
when /^3\.5\./
|
|
14
|
+
ParserCurrent = Parser35
|
|
15
|
+
else
|
|
16
|
+
# Keep this in sync with released Ruby.
|
|
17
|
+
parser = Parser34
|
|
18
|
+
major, minor, _patch = Gem::Version.new(RUBY_VERSION).segments
|
|
19
|
+
warn "warning: `Prism::Translation::Current` is loading #{parser.name}, " \
|
|
20
|
+
"but you are running #{major}.#{minor}."
|
|
21
|
+
ParserCurrent = parser
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
3
|
+
|
|
4
|
+
require_relative "../ripper"
|
|
5
|
+
|
|
6
|
+
module Prism
|
|
7
|
+
module Translation
|
|
8
|
+
class Ripper
|
|
9
|
+
# This class mirrors the ::Ripper::SexpBuilder subclass of ::Ripper that
|
|
10
|
+
# returns the arrays of [type, *children].
|
|
11
|
+
class SexpBuilder < Ripper
|
|
12
|
+
# :stopdoc:
|
|
13
|
+
|
|
14
|
+
attr_reader :error
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def dedent_element(e, width)
|
|
19
|
+
if (n = dedent_string(e[1], width)) > 0
|
|
20
|
+
e[2][1] += n
|
|
21
|
+
end
|
|
22
|
+
e
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def on_heredoc_dedent(val, width)
|
|
26
|
+
sub = proc do |cont|
|
|
27
|
+
cont.map! do |e|
|
|
28
|
+
if Array === e
|
|
29
|
+
case e[0]
|
|
30
|
+
when :@tstring_content
|
|
31
|
+
e = dedent_element(e, width)
|
|
32
|
+
when /_add\z/
|
|
33
|
+
e[1] = sub[e[1]]
|
|
34
|
+
end
|
|
35
|
+
elsif String === e
|
|
36
|
+
dedent_string(e, width)
|
|
37
|
+
end
|
|
38
|
+
e
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
sub[val]
|
|
42
|
+
val
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
events = private_instance_methods(false).grep(/\Aon_/) {$'.to_sym}
|
|
46
|
+
(PARSER_EVENTS - events).each do |event|
|
|
47
|
+
module_eval(<<-End, __FILE__, __LINE__ + 1)
|
|
48
|
+
def on_#{event}(*args)
|
|
49
|
+
args.unshift :#{event}
|
|
50
|
+
end
|
|
51
|
+
End
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
SCANNER_EVENTS.each do |event|
|
|
55
|
+
module_eval(<<-End, __FILE__, __LINE__ + 1)
|
|
56
|
+
def on_#{event}(tok)
|
|
57
|
+
[:@#{event}, tok, [lineno(), column()]]
|
|
58
|
+
end
|
|
59
|
+
End
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def on_error(mesg)
|
|
63
|
+
@error = mesg
|
|
64
|
+
end
|
|
65
|
+
remove_method :on_parse_error
|
|
66
|
+
alias on_parse_error on_error
|
|
67
|
+
alias compile_error on_error
|
|
68
|
+
|
|
69
|
+
# :startdoc:
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# This class mirrors the ::Ripper::SexpBuilderPP subclass of ::Ripper that
|
|
73
|
+
# returns the same values as ::Ripper::SexpBuilder except with a couple of
|
|
74
|
+
# niceties that flatten linked lists into arrays.
|
|
75
|
+
class SexpBuilderPP < SexpBuilder
|
|
76
|
+
# :stopdoc:
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def on_heredoc_dedent(val, width)
|
|
81
|
+
val.map! do |e|
|
|
82
|
+
next e if Symbol === e and /_content\z/ =~ e
|
|
83
|
+
if Array === e and e[0] == :@tstring_content
|
|
84
|
+
e = dedent_element(e, width)
|
|
85
|
+
elsif String === e
|
|
86
|
+
dedent_string(e, width)
|
|
87
|
+
end
|
|
88
|
+
e
|
|
89
|
+
end
|
|
90
|
+
val
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def _dispatch_event_new
|
|
94
|
+
[]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def _dispatch_event_push(list, item)
|
|
98
|
+
list.push item
|
|
99
|
+
list
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def on_mlhs_paren(list)
|
|
103
|
+
[:mlhs, *list]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def on_mlhs_add_star(list, star)
|
|
107
|
+
list.push([:rest_param, star])
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def on_mlhs_add_post(list, post)
|
|
111
|
+
list.concat(post)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
PARSER_EVENT_TABLE.each do |event, arity|
|
|
115
|
+
if /_new\z/ =~ event and arity == 0
|
|
116
|
+
alias_method "on_#{event}", :_dispatch_event_new
|
|
117
|
+
elsif /_add\z/ =~ event
|
|
118
|
+
alias_method "on_#{event}", :_dispatch_event_push
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# :startdoc:
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|