prism 1.3.0 → 1.5.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 +46 -1
- data/Makefile +2 -1
- data/README.md +1 -0
- data/config.yml +273 -37
- data/docs/parser_translation.md +8 -23
- data/docs/releasing.md +1 -1
- data/docs/ripper_translation.md +1 -1
- data/docs/ruby_api.md +1 -1
- data/ext/prism/api_node.c +1816 -1303
- data/ext/prism/extension.c +244 -110
- data/ext/prism/extension.h +4 -4
- data/include/prism/ast.h +291 -49
- data/include/prism/defines.h +4 -1
- data/include/prism/diagnostic.h +4 -0
- data/include/prism/options.h +89 -3
- data/include/prism/regexp.h +2 -2
- data/include/prism/util/pm_buffer.h +18 -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 +41 -16
- data/lib/prism/compiler.rb +456 -151
- data/lib/prism/desugar_compiler.rb +1 -0
- data/lib/prism/dispatcher.rb +16 -0
- data/lib/prism/dot_visitor.rb +21 -1
- data/lib/prism/dsl.rb +13 -2
- data/lib/prism/ffi.rb +62 -34
- data/lib/prism/inspect_visitor.rb +5 -1
- data/lib/prism/lex_compat.rb +1 -0
- data/lib/prism/mutation_compiler.rb +3 -0
- data/lib/prism/node.rb +554 -345
- 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 +2 -1
- data/lib/prism/parse_result.rb +53 -0
- data/lib/prism/pattern.rb +1 -0
- data/lib/prism/polyfill/append_as_bytes.rb +15 -0
- data/lib/prism/polyfill/scan_byte.rb +14 -0
- data/lib/prism/polyfill/warn.rb +42 -0
- data/lib/prism/reflection.rb +5 -2
- data/lib/prism/relocation.rb +1 -0
- data/lib/prism/serialize.rb +1275 -783
- data/lib/prism/string_query.rb +1 -0
- data/lib/prism/translation/parser/builder.rb +62 -0
- data/lib/prism/translation/parser/compiler.rb +230 -152
- data/lib/prism/translation/parser/lexer.rb +446 -64
- data/lib/prism/translation/parser.rb +64 -4
- data/lib/prism/translation/parser33.rb +1 -0
- data/lib/prism/translation/parser34.rb +1 -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 +1 -0
- data/lib/prism/translation/ripper.rb +30 -4
- data/lib/prism/translation/ruby_parser.rb +291 -7
- data/lib/prism/translation.rb +3 -0
- data/lib/prism/visitor.rb +457 -152
- data/lib/prism.rb +5 -3
- data/prism.gemspec +9 -1
- data/rbi/prism/dsl.rbi +9 -6
- data/rbi/prism/node.rbi +43 -16
- data/rbi/prism/parse_result.rbi +17 -0
- data/rbi/prism/translation/parser35.rbi +6 -0
- data/rbi/prism.rbi +39 -36
- data/sig/prism/dispatcher.rbs +3 -0
- data/sig/prism/dsl.rbs +7 -5
- data/sig/prism/node.rbs +461 -37
- data/sig/prism/node_ext.rbs +84 -17
- data/sig/prism/parse_result/comments.rbs +38 -0
- data/sig/prism/parse_result.rbs +14 -0
- data/sig/prism/reflection.rbs +1 -1
- data/sig/prism/serialize.rbs +4 -2
- data/sig/prism.rbs +22 -1
- data/src/diagnostic.c +9 -3
- data/src/node.c +23 -0
- data/src/options.c +33 -2
- data/src/prettyprint.c +32 -0
- data/src/prism.c +620 -242
- data/src/serialize.c +8 -0
- data/src/token_type.c +36 -34
- data/src/util/pm_buffer.c +40 -0
- data/src/util/pm_constant_pool.c +6 -2
- data/src/util/pm_strncasecmp.c +13 -1
- metadata +11 -7
@@ -1,9 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# :markup: markdown
|
2
3
|
|
3
4
|
begin
|
5
|
+
required_version = ">= 3.3.7.2"
|
6
|
+
gem "parser", required_version
|
4
7
|
require "parser"
|
5
8
|
rescue LoadError
|
6
|
-
warn(
|
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
|
7
13
|
exit(1)
|
8
14
|
end
|
9
15
|
|
@@ -33,6 +39,43 @@ module Prism
|
|
33
39
|
|
34
40
|
Racc_debug_parser = false # :nodoc:
|
35
41
|
|
42
|
+
# The `builder` argument is used to create the parser using our custom builder class by default.
|
43
|
+
#
|
44
|
+
# By using the `:parser` keyword argument, you can translate in a way that is compatible with
|
45
|
+
# the Parser gem using any parser.
|
46
|
+
#
|
47
|
+
# For example, in RuboCop for Ruby LSP, the following approach can be used to improve performance
|
48
|
+
# by reusing a pre-parsed `Prism::ParseLexResult`:
|
49
|
+
#
|
50
|
+
# class PrismPreparsed
|
51
|
+
# def initialize(prism_result)
|
52
|
+
# @prism_result = prism_result
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# def parse_lex(source, **options)
|
56
|
+
# @prism_result
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# prism_preparsed = PrismPreparsed.new(prism_result)
|
61
|
+
#
|
62
|
+
# Prism::Translation::Ruby34.new(builder, parser: prism_preparsed)
|
63
|
+
#
|
64
|
+
# In an object passed to the `:parser` keyword argument, the `parse` and `parse_lex` methods
|
65
|
+
# should be implemented as needed.
|
66
|
+
#
|
67
|
+
def initialize(builder = Prism::Translation::Parser::Builder.new, parser: Prism)
|
68
|
+
if !builder.is_a?(Prism::Translation::Parser::Builder)
|
69
|
+
warn(<<~MSG, uplevel: 1, category: :deprecated)
|
70
|
+
[deprecation]: The builder passed to `Prism::Translation::Parser.new` is not a \
|
71
|
+
`Prism::Translation::Parser::Builder` subclass. This will raise in the next major version.
|
72
|
+
MSG
|
73
|
+
end
|
74
|
+
@parser = parser
|
75
|
+
|
76
|
+
super(builder)
|
77
|
+
end
|
78
|
+
|
36
79
|
def version # :nodoc:
|
37
80
|
34
|
38
81
|
end
|
@@ -51,7 +94,7 @@ module Prism
|
|
51
94
|
source = source_buffer.source
|
52
95
|
|
53
96
|
offset_cache = build_offset_cache(source)
|
54
|
-
result = unwrap(
|
97
|
+
result = unwrap(@parser.parse(source, **prism_options), offset_cache)
|
55
98
|
|
56
99
|
build_ast(result.value, offset_cache)
|
57
100
|
ensure
|
@@ -64,7 +107,7 @@ module Prism
|
|
64
107
|
source = source_buffer.source
|
65
108
|
|
66
109
|
offset_cache = build_offset_cache(source)
|
67
|
-
result = unwrap(
|
110
|
+
result = unwrap(@parser.parse(source, **prism_options), offset_cache)
|
68
111
|
|
69
112
|
[
|
70
113
|
build_ast(result.value, offset_cache),
|
@@ -83,7 +126,7 @@ module Prism
|
|
83
126
|
offset_cache = build_offset_cache(source)
|
84
127
|
result =
|
85
128
|
begin
|
86
|
-
unwrap(
|
129
|
+
unwrap(@parser.parse_lex(source, **prism_options), offset_cache)
|
87
130
|
rescue ::Parser::SyntaxError
|
88
131
|
raise if !recover
|
89
132
|
end
|
@@ -285,6 +328,20 @@ module Prism
|
|
285
328
|
)
|
286
329
|
end
|
287
330
|
|
331
|
+
# Options for how prism should parse/lex the source.
|
332
|
+
def prism_options
|
333
|
+
options = {
|
334
|
+
filepath: @source_buffer.name,
|
335
|
+
version: convert_for_prism(version),
|
336
|
+
partial_script: true,
|
337
|
+
}
|
338
|
+
# The parser gem always encodes to UTF-8, unless it is binary.
|
339
|
+
# https://github.com/whitequark/parser/blob/v3.3.6.0/lib/parser/source/buffer.rb#L80-L107
|
340
|
+
options[:encoding] = false if @source_buffer.source.encoding != Encoding::BINARY
|
341
|
+
|
342
|
+
options
|
343
|
+
end
|
344
|
+
|
288
345
|
# Converts the version format handled by Parser to the format handled by Prism.
|
289
346
|
def convert_for_prism(version)
|
290
347
|
case version
|
@@ -292,11 +349,14 @@ module Prism
|
|
292
349
|
"3.3.1"
|
293
350
|
when 34
|
294
351
|
"3.4.0"
|
352
|
+
when 35
|
353
|
+
"3.5.0"
|
295
354
|
else
|
296
355
|
"latest"
|
297
356
|
end
|
298
357
|
end
|
299
358
|
|
359
|
+
require_relative "parser/builder"
|
300
360
|
require_relative "parser/compiler"
|
301
361
|
require_relative "parser/lexer"
|
302
362
|
|
@@ -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
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# :markup: markdown
|
2
3
|
|
3
4
|
require "ripper"
|
4
5
|
|
@@ -1045,10 +1046,20 @@ module Prism
|
|
1045
1046
|
bounds(node.location)
|
1046
1047
|
on_unary(node.name, receiver)
|
1047
1048
|
when :!
|
1048
|
-
|
1049
|
+
if node.message == "not"
|
1050
|
+
receiver =
|
1051
|
+
if !node.receiver.is_a?(ParenthesesNode) || !node.receiver.body.nil?
|
1052
|
+
visit(node.receiver)
|
1053
|
+
end
|
1049
1054
|
|
1050
|
-
|
1051
|
-
|
1055
|
+
bounds(node.location)
|
1056
|
+
on_unary(:not, receiver)
|
1057
|
+
else
|
1058
|
+
receiver = visit(node.receiver)
|
1059
|
+
|
1060
|
+
bounds(node.location)
|
1061
|
+
on_unary(:!, receiver)
|
1062
|
+
end
|
1052
1063
|
when *BINARY_OPERATORS
|
1053
1064
|
receiver = visit(node.receiver)
|
1054
1065
|
value = visit(node.arguments.arguments.first)
|
@@ -1605,8 +1616,23 @@ module Prism
|
|
1605
1616
|
# defined?(a)
|
1606
1617
|
# ^^^^^^^^^^^
|
1607
1618
|
def visit_defined_node(node)
|
1619
|
+
expression = visit(node.value)
|
1620
|
+
|
1621
|
+
# Very weird circumstances here where something like:
|
1622
|
+
#
|
1623
|
+
# defined?
|
1624
|
+
# (1)
|
1625
|
+
#
|
1626
|
+
# gets parsed in Ruby as having only the `1` expression but in Ripper it
|
1627
|
+
# gets parsed as having a parentheses node. In this case we need to
|
1628
|
+
# synthesize that node to match Ripper's behavior.
|
1629
|
+
if node.lparen_loc && node.keyword_loc.join(node.lparen_loc).slice.include?("\n")
|
1630
|
+
bounds(node.lparen_loc.join(node.rparen_loc))
|
1631
|
+
expression = on_paren(on_stmts_add(on_stmts_new, expression))
|
1632
|
+
end
|
1633
|
+
|
1608
1634
|
bounds(node.location)
|
1609
|
-
on_defined(
|
1635
|
+
on_defined(expression)
|
1610
1636
|
end
|
1611
1637
|
|
1612
1638
|
# if foo then bar else baz end
|