prism 0.17.0 → 0.18.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 +37 -1
- data/Makefile +5 -5
- data/README.md +2 -2
- data/config.yml +26 -13
- data/docs/build_system.md +6 -6
- data/docs/building.md +1 -1
- data/docs/configuration.md +1 -0
- data/docs/encoding.md +68 -32
- data/docs/heredocs.md +1 -1
- data/docs/javascript.md +29 -1
- data/docs/releasing.md +4 -1
- data/docs/ruby_api.md +14 -0
- data/ext/prism/api_node.c +74 -45
- data/ext/prism/extconf.rb +91 -127
- data/ext/prism/extension.c +4 -1
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +148 -133
- data/include/prism/diagnostic.h +27 -1
- data/include/prism/enc/pm_encoding.h +42 -1
- data/include/prism/parser.h +6 -0
- data/include/prism/version.h +2 -2
- data/lib/prism/compiler.rb +3 -3
- data/lib/prism/debug.rb +4 -0
- data/lib/prism/desugar_compiler.rb +1 -0
- data/lib/prism/dispatcher.rb +14 -14
- data/lib/prism/dot_visitor.rb +4334 -0
- data/lib/prism/dsl.rb +11 -11
- data/lib/prism/ffi.rb +3 -3
- data/lib/prism/mutation_compiler.rb +6 -6
- data/lib/prism/node.rb +182 -113
- data/lib/prism/node_ext.rb +61 -3
- data/lib/prism/parse_result.rb +46 -12
- data/lib/prism/serialize.rb +124 -130
- data/lib/prism/visitor.rb +3 -3
- data/lib/prism.rb +1 -0
- data/prism.gemspec +5 -1
- data/rbi/prism.rbi +5565 -5540
- data/rbi/prism_static.rbi +138 -142
- data/sig/prism.rbs +47 -32
- data/src/diagnostic.c +61 -3
- data/src/enc/pm_big5.c +63 -0
- data/src/enc/pm_cp51932.c +57 -0
- data/src/enc/pm_euc_jp.c +10 -0
- data/src/enc/pm_gbk.c +5 -2
- data/src/enc/pm_tables.c +1478 -148
- data/src/node.c +33 -21
- data/src/prettyprint.c +1027 -925
- data/src/prism.c +925 -374
- data/src/regexp.c +12 -12
- data/src/serialize.c +36 -9
- metadata +6 -2
data/rbi/prism_static.rbi
CHANGED
@@ -1,196 +1,192 @@
|
|
1
|
-
|
1
|
+
class Prism::ParseResult
|
2
|
+
sig { returns(Prism::ProgramNode) }
|
3
|
+
def value; end
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
sig { returns(ProgramNode) }
|
6
|
-
def value; end
|
5
|
+
sig { returns(T::Array[Prism::Comment]) }
|
6
|
+
def comments; end
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
sig { returns(T::Array[Prism::ParseError]) }
|
9
|
+
def errors; end
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
sig { returns(T::Array[Prism::ParseWarning]) }
|
12
|
+
def warnings; end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
sig { returns(Source) }
|
18
|
-
def source; end
|
19
|
-
end
|
14
|
+
sig { returns(Prism::Source) }
|
15
|
+
def source; end
|
16
|
+
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
class Prism::ParseError
|
19
|
+
sig { returns(String) }
|
20
|
+
def message; end
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
sig { returns(Prism::Location) }
|
23
|
+
def location; end
|
24
|
+
end
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
class Prism::ParseWarning
|
27
|
+
sig { returns(String) }
|
28
|
+
def message; end
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
sig { returns(Prism::Location) }
|
31
|
+
def location; end
|
32
|
+
end
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
class Prism::Node
|
35
|
+
sig { returns(T::Array[T.nilable(Prism::Node)]) }
|
36
|
+
def child_nodes; end
|
40
37
|
|
41
|
-
|
42
|
-
|
38
|
+
sig { returns(Prism::Location) }
|
39
|
+
def location; end
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
sig { returns(String) }
|
42
|
+
def slice; end
|
43
|
+
end
|
47
44
|
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
class Prism::Comment
|
46
|
+
sig { returns(Prism::Location) }
|
47
|
+
def location; end
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
sig { returns(T::Boolean) }
|
50
|
+
def trailing?; end
|
51
|
+
end
|
55
52
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
class Prism::InlineComment < Prism::Comment
|
54
|
+
sig { override.returns(T::Boolean) }
|
55
|
+
def trailing?; end
|
56
|
+
end
|
60
57
|
|
61
|
-
|
62
|
-
|
58
|
+
class Prism::EmbDocComment < Prism::Comment
|
59
|
+
end
|
63
60
|
|
64
|
-
|
65
|
-
|
61
|
+
class Prism::DATAComment < Prism::Comment
|
62
|
+
end
|
66
63
|
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
class Prism::Location
|
65
|
+
sig { params(source: Prism::Source, start_offset: Integer, length: Integer).void }
|
66
|
+
def initialize(source, start_offset, length); end
|
70
67
|
|
71
|
-
|
72
|
-
|
68
|
+
sig { returns(String) }
|
69
|
+
def slice; end
|
73
70
|
|
74
|
-
|
75
|
-
|
71
|
+
sig { returns(T::Array[Prism::Comment]) }
|
72
|
+
def comments; end
|
76
73
|
|
77
|
-
|
78
|
-
|
74
|
+
sig { params(options: T.untyped).returns(Prism::Location) }
|
75
|
+
def copy(**options); end
|
79
76
|
|
80
|
-
|
81
|
-
|
77
|
+
sig { returns(Integer) }
|
78
|
+
def start_offset; end
|
82
79
|
|
83
|
-
|
84
|
-
|
80
|
+
sig { returns(Integer) }
|
81
|
+
def end_offset; end
|
85
82
|
|
86
|
-
|
87
|
-
|
83
|
+
sig { returns(Integer) }
|
84
|
+
def start_line; end
|
88
85
|
|
89
|
-
|
90
|
-
|
86
|
+
sig { returns(Integer) }
|
87
|
+
def end_line; end
|
91
88
|
|
92
|
-
|
93
|
-
|
89
|
+
sig { returns(Integer) }
|
90
|
+
def start_column; end
|
94
91
|
|
95
|
-
|
96
|
-
|
97
|
-
|
92
|
+
sig { returns(Integer) }
|
93
|
+
def end_column; end
|
94
|
+
end
|
98
95
|
|
99
|
-
|
100
|
-
|
101
|
-
|
96
|
+
class Prism::Source
|
97
|
+
sig { params(source: String, start_line: Integer, offsets: T::Array[Integer]).void }
|
98
|
+
def initialize(source, start_line, offsets); end
|
102
99
|
|
103
|
-
|
104
|
-
|
100
|
+
sig { params(offset: Integer, length: Integer).returns(String) }
|
101
|
+
def slice(offset, length); end
|
105
102
|
|
106
|
-
|
107
|
-
|
103
|
+
sig { params(value: Integer).returns(Integer) }
|
104
|
+
def line(value); end
|
108
105
|
|
109
|
-
|
110
|
-
|
106
|
+
sig { params(value: Integer).returns(Integer) }
|
107
|
+
def line_offset(value); end
|
111
108
|
|
112
|
-
|
113
|
-
|
109
|
+
sig { params(value: Integer).returns(Integer) }
|
110
|
+
def column(value); end
|
114
111
|
|
115
|
-
|
116
|
-
|
112
|
+
sig { returns(String) }
|
113
|
+
def source; end
|
117
114
|
|
118
|
-
|
119
|
-
|
120
|
-
|
115
|
+
sig { returns(T::Array[Integer]) }
|
116
|
+
def offsets; end
|
117
|
+
end
|
121
118
|
|
122
|
-
|
123
|
-
|
124
|
-
|
119
|
+
class Prism::Token
|
120
|
+
sig { params(type: T.untyped, value: String, location: Prism::Location).void }
|
121
|
+
def initialize(type, value, location); end
|
125
122
|
|
126
|
-
|
127
|
-
|
123
|
+
sig { params(keys: T.untyped).returns(T.untyped) }
|
124
|
+
def deconstruct_keys(keys); end
|
128
125
|
|
129
|
-
|
130
|
-
|
126
|
+
sig { params(q: T.untyped).returns(T.untyped) }
|
127
|
+
def pretty_print(q); end
|
131
128
|
|
132
|
-
|
133
|
-
|
129
|
+
sig { params(other: T.untyped).returns(T::Boolean) }
|
130
|
+
def ==(other); end
|
134
131
|
|
135
|
-
|
136
|
-
|
132
|
+
sig { returns(T.untyped) }
|
133
|
+
def type; end
|
137
134
|
|
138
|
-
|
139
|
-
|
135
|
+
sig { returns(String) }
|
136
|
+
def value; end
|
140
137
|
|
141
|
-
|
142
|
-
|
143
|
-
|
138
|
+
sig { returns(Prism::Location) }
|
139
|
+
def location; end
|
140
|
+
end
|
144
141
|
|
145
|
-
|
146
|
-
|
147
|
-
|
142
|
+
class Prism::NodeInspector
|
143
|
+
sig { params(prefix: String).void }
|
144
|
+
def initialize(prefix); end
|
148
145
|
|
149
|
-
|
150
|
-
|
146
|
+
sig { returns(String) }
|
147
|
+
def prefix; end
|
151
148
|
|
152
|
-
|
153
|
-
|
149
|
+
sig { returns(String) }
|
150
|
+
def output; end
|
154
151
|
|
155
|
-
|
156
|
-
|
157
|
-
|
152
|
+
# Appends a line to the output with the current prefix.
|
153
|
+
sig { params(line: String).void }
|
154
|
+
def <<(line); end
|
158
155
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
156
|
+
# This generates a string that is used as the header of the inspect output
|
157
|
+
# for any given node.
|
158
|
+
sig { params(node: Prism::Node).returns(String) }
|
159
|
+
def header(node); end
|
163
160
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
161
|
+
# Generates a string that represents a list of nodes. It handles properly
|
162
|
+
# using the box drawing characters to make the output look nice.
|
163
|
+
sig { params(prefix: String, nodes: T::Array[Prism::Node]).returns(String) }
|
164
|
+
def list(prefix, nodes); end
|
168
165
|
|
169
|
-
|
170
|
-
|
171
|
-
|
166
|
+
# Generates a string that represents a location field on a node.
|
167
|
+
sig { params(value: Prism::Location).returns(String) }
|
168
|
+
def location(value); end
|
172
169
|
|
173
|
-
|
174
|
-
|
175
|
-
|
170
|
+
# Generates a string that represents a child node.
|
171
|
+
sig { params(node: Prism::Node, append: String).returns(String) }
|
172
|
+
def child_node(node, append); end
|
176
173
|
|
177
|
-
|
178
|
-
|
179
|
-
|
174
|
+
# Returns a new inspector that can be used to inspect a child node.
|
175
|
+
sig { params(append: String).returns(Prism::NodeInspector) }
|
176
|
+
def child_inspector(append); end
|
180
177
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
178
|
+
# Returns the output as a string.
|
179
|
+
sig { returns(String) }
|
180
|
+
def to_str; end
|
181
|
+
end
|
185
182
|
|
186
|
-
|
187
|
-
|
188
|
-
|
183
|
+
class Prism::BasicVisitor
|
184
|
+
sig { params(node: T.nilable(Prism::Node)).void }
|
185
|
+
def visit(node); end
|
189
186
|
|
190
|
-
|
191
|
-
|
187
|
+
sig { params(nodes: T::Array[T.nilable(Prism::Node)]).void }
|
188
|
+
def visit_all(nodes); end
|
192
189
|
|
193
|
-
|
194
|
-
|
195
|
-
end
|
190
|
+
sig { params(node: Prism::Node).void }
|
191
|
+
def visit_child_nodes(node); end
|
196
192
|
end
|
data/sig/prism.rbs
CHANGED
@@ -605,6 +605,35 @@ module Prism
|
|
605
605
|
|
606
606
|
def inspect: (inspector: NodeInspector) -> String
|
607
607
|
end
|
608
|
+
# Represents the use of a case statement for pattern matching.
|
609
|
+
#
|
610
|
+
# case true
|
611
|
+
# in false
|
612
|
+
# end
|
613
|
+
# ^^^^^^^^^
|
614
|
+
class CaseMatchNode < Node
|
615
|
+
attr_reader predicate: Node?
|
616
|
+
attr_reader conditions: Array[Node]
|
617
|
+
attr_reader consequent: ElseNode?
|
618
|
+
attr_reader case_keyword_loc: Location
|
619
|
+
attr_reader end_keyword_loc: Location
|
620
|
+
|
621
|
+
def initialize: (predicate: Node?, conditions: Array[Node], consequent: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location, location: Location) -> void
|
622
|
+
def accept: (visitor: Visitor) -> void
|
623
|
+
def set_newline_flag: (newline_marked: Array[bool]) -> void
|
624
|
+
def child_nodes: () -> Array[Node?]
|
625
|
+
def deconstruct: () -> Array[Node?]
|
626
|
+
|
627
|
+
def copy: (**untyped) -> CaseMatchNode
|
628
|
+
|
629
|
+
def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, (Node | Array[Node] | String | Token | Array[Token] | Location)?]
|
630
|
+
|
631
|
+
def case_keyword: () -> String
|
632
|
+
|
633
|
+
def end_keyword: () -> String
|
634
|
+
|
635
|
+
def inspect: (inspector: NodeInspector) -> String
|
636
|
+
end
|
608
637
|
# Represents the use of a case statement.
|
609
638
|
#
|
610
639
|
# case true
|
@@ -1632,11 +1661,12 @@ module Prism
|
|
1632
1661
|
class IfNode < Node
|
1633
1662
|
attr_reader if_keyword_loc: Location?
|
1634
1663
|
attr_reader predicate: Node
|
1664
|
+
attr_reader then_keyword_loc: Location?
|
1635
1665
|
attr_reader statements: StatementsNode?
|
1636
1666
|
attr_reader consequent: Node?
|
1637
1667
|
attr_reader end_keyword_loc: Location?
|
1638
1668
|
|
1639
|
-
def initialize: (if_keyword_loc: Location?, predicate: Node, statements: StatementsNode?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> void
|
1669
|
+
def initialize: (if_keyword_loc: Location?, predicate: Node, then_keyword_loc: Location?, statements: StatementsNode?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> void
|
1640
1670
|
def accept: (visitor: Visitor) -> void
|
1641
1671
|
def set_newline_flag: (newline_marked: Array[bool]) -> void
|
1642
1672
|
def child_nodes: () -> Array[Node?]
|
@@ -1648,6 +1678,8 @@ module Prism
|
|
1648
1678
|
|
1649
1679
|
def if_keyword: () -> String?
|
1650
1680
|
|
1681
|
+
def then_keyword: () -> String?
|
1682
|
+
|
1651
1683
|
def end_keyword: () -> String?
|
1652
1684
|
|
1653
1685
|
def inspect: (inspector: NodeInspector) -> String
|
@@ -2471,9 +2503,9 @@ module Prism
|
|
2471
2503
|
# ^^^^^^^^^^^^^^^^^^^^
|
2472
2504
|
class MatchWriteNode < Node
|
2473
2505
|
attr_reader call: CallNode
|
2474
|
-
attr_reader
|
2506
|
+
attr_reader targets: Array[Node]
|
2475
2507
|
|
2476
|
-
def initialize: (call: CallNode,
|
2508
|
+
def initialize: (call: CallNode, targets: Array[Node], location: Location) -> void
|
2477
2509
|
def accept: (visitor: Visitor) -> void
|
2478
2510
|
def set_newline_flag: (newline_marked: Array[bool]) -> void
|
2479
2511
|
def child_nodes: () -> Array[Node?]
|
@@ -3334,26 +3366,6 @@ module Prism
|
|
3334
3366
|
|
3335
3367
|
def inspect: (inspector: NodeInspector) -> String
|
3336
3368
|
end
|
3337
|
-
# Represents the use of compile-time string concatenation.
|
3338
|
-
#
|
3339
|
-
# "foo" "bar"
|
3340
|
-
# ^^^^^^^^^^^
|
3341
|
-
class StringConcatNode < Node
|
3342
|
-
attr_reader left: Node
|
3343
|
-
attr_reader right: Node
|
3344
|
-
|
3345
|
-
def initialize: (left: Node, right: Node, location: Location) -> void
|
3346
|
-
def accept: (visitor: Visitor) -> void
|
3347
|
-
def set_newline_flag: (newline_marked: Array[bool]) -> void
|
3348
|
-
def child_nodes: () -> Array[Node?]
|
3349
|
-
def deconstruct: () -> Array[Node?]
|
3350
|
-
|
3351
|
-
def copy: (**untyped) -> StringConcatNode
|
3352
|
-
|
3353
|
-
def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, (Node | Array[Node] | String | Token | Array[Token] | Location)?]
|
3354
|
-
|
3355
|
-
def inspect: (inspector: NodeInspector) -> String
|
3356
|
-
end
|
3357
3369
|
# Represents a string literal, a string contained within a `%w` list, or
|
3358
3370
|
# plain string content within an interpolated string.
|
3359
3371
|
#
|
@@ -3505,11 +3517,12 @@ module Prism
|
|
3505
3517
|
class UnlessNode < Node
|
3506
3518
|
attr_reader keyword_loc: Location
|
3507
3519
|
attr_reader predicate: Node
|
3520
|
+
attr_reader then_keyword_loc: Location?
|
3508
3521
|
attr_reader statements: StatementsNode?
|
3509
3522
|
attr_reader consequent: ElseNode?
|
3510
3523
|
attr_reader end_keyword_loc: Location?
|
3511
3524
|
|
3512
|
-
def initialize: (keyword_loc: Location, predicate: Node, statements: StatementsNode?, consequent: ElseNode?, end_keyword_loc: Location?, location: Location) -> void
|
3525
|
+
def initialize: (keyword_loc: Location, predicate: Node, then_keyword_loc: Location?, statements: StatementsNode?, consequent: ElseNode?, end_keyword_loc: Location?, location: Location) -> void
|
3513
3526
|
def accept: (visitor: Visitor) -> void
|
3514
3527
|
def set_newline_flag: (newline_marked: Array[bool]) -> void
|
3515
3528
|
def child_nodes: () -> Array[Node?]
|
@@ -3521,6 +3534,8 @@ module Prism
|
|
3521
3534
|
|
3522
3535
|
def keyword: () -> String
|
3523
3536
|
|
3537
|
+
def then_keyword: () -> String?
|
3538
|
+
|
3524
3539
|
def end_keyword: () -> String?
|
3525
3540
|
|
3526
3541
|
def inspect: (inspector: NodeInspector) -> String
|
@@ -3803,6 +3818,9 @@ module Prism
|
|
3803
3818
|
# Visit a CapturePatternNode node
|
3804
3819
|
def visit_capture_pattern_node: (node: CapturePatternNode) -> void
|
3805
3820
|
|
3821
|
+
# Visit a CaseMatchNode node
|
3822
|
+
def visit_case_match_node: (node: CaseMatchNode) -> void
|
3823
|
+
|
3806
3824
|
# Visit a CaseNode node
|
3807
3825
|
def visit_case_node: (node: CaseNode) -> void
|
3808
3826
|
|
@@ -4133,9 +4151,6 @@ module Prism
|
|
4133
4151
|
# Visit a StatementsNode node
|
4134
4152
|
def visit_statements_node: (node: StatementsNode) -> void
|
4135
4153
|
|
4136
|
-
# Visit a StringConcatNode node
|
4137
|
-
def visit_string_concat_node: (node: StringConcatNode) -> void
|
4138
|
-
|
4139
4154
|
# Visit a StringNode node
|
4140
4155
|
def visit_string_node: (node: StringNode) -> void
|
4141
4156
|
|
@@ -4220,6 +4235,8 @@ module Prism
|
|
4220
4235
|
def CallOrWriteNode: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> CallOrWriteNode
|
4221
4236
|
# Create a new CapturePatternNode node
|
4222
4237
|
def CapturePatternNode: (value: Node, target: Node, operator_loc: Location, location: Location) -> CapturePatternNode
|
4238
|
+
# Create a new CaseMatchNode node
|
4239
|
+
def CaseMatchNode: (predicate: Node?, conditions: Array[Node], consequent: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location, location: Location) -> CaseMatchNode
|
4223
4240
|
# Create a new CaseNode node
|
4224
4241
|
def CaseNode: (predicate: Node?, conditions: Array[Node], consequent: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location, location: Location) -> CaseNode
|
4225
4242
|
# Create a new ClassNode node
|
@@ -4305,7 +4322,7 @@ module Prism
|
|
4305
4322
|
# Create a new HashPatternNode node
|
4306
4323
|
def HashPatternNode: (constant: Node?, elements: Array[Node], rest: Node?, opening_loc: Location?, closing_loc: Location?, location: Location) -> HashPatternNode
|
4307
4324
|
# Create a new IfNode node
|
4308
|
-
def IfNode: (if_keyword_loc: Location?, predicate: Node, statements: StatementsNode?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> IfNode
|
4325
|
+
def IfNode: (if_keyword_loc: Location?, predicate: Node, then_keyword_loc: Location?, statements: StatementsNode?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> IfNode
|
4309
4326
|
# Create a new ImaginaryNode node
|
4310
4327
|
def ImaginaryNode: (numeric: Node, location: Location) -> ImaginaryNode
|
4311
4328
|
# Create a new ImplicitNode node
|
@@ -4367,7 +4384,7 @@ module Prism
|
|
4367
4384
|
# Create a new MatchRequiredNode node
|
4368
4385
|
def MatchRequiredNode: (value: Node, pattern: Node, operator_loc: Location, location: Location) -> MatchRequiredNode
|
4369
4386
|
# Create a new MatchWriteNode node
|
4370
|
-
def MatchWriteNode: (call: CallNode,
|
4387
|
+
def MatchWriteNode: (call: CallNode, targets: Array[Node], location: Location) -> MatchWriteNode
|
4371
4388
|
# Create a new MissingNode node
|
4372
4389
|
def MissingNode: (location: Location) -> MissingNode
|
4373
4390
|
# Create a new ModuleNode node
|
@@ -4440,8 +4457,6 @@ module Prism
|
|
4440
4457
|
def SplatNode: (operator_loc: Location, expression: Node?, location: Location) -> SplatNode
|
4441
4458
|
# Create a new StatementsNode node
|
4442
4459
|
def StatementsNode: (body: Array[Node], location: Location) -> StatementsNode
|
4443
|
-
# Create a new StringConcatNode node
|
4444
|
-
def StringConcatNode: (left: Node, right: Node, location: Location) -> StringConcatNode
|
4445
4460
|
# Create a new StringNode node
|
4446
4461
|
def StringNode: (flags: Integer, opening_loc: Location?, content_loc: Location, closing_loc: Location?, unescaped: String, location: Location) -> StringNode
|
4447
4462
|
# Create a new SuperNode node
|
@@ -4453,7 +4468,7 @@ module Prism
|
|
4453
4468
|
# Create a new UndefNode node
|
4454
4469
|
def UndefNode: (names: Array[Node], keyword_loc: Location, location: Location) -> UndefNode
|
4455
4470
|
# Create a new UnlessNode node
|
4456
|
-
def UnlessNode: (keyword_loc: Location, predicate: Node, statements: StatementsNode?, consequent: ElseNode?, end_keyword_loc: Location?, location: Location) -> UnlessNode
|
4471
|
+
def UnlessNode: (keyword_loc: Location, predicate: Node, then_keyword_loc: Location?, statements: StatementsNode?, consequent: ElseNode?, end_keyword_loc: Location?, location: Location) -> UnlessNode
|
4457
4472
|
# Create a new UntilNode node
|
4458
4473
|
def UntilNode: (keyword_loc: Location, closing_loc: Location?, predicate: Node, statements: StatementsNode?, flags: Integer, location: Location) -> UntilNode
|
4459
4474
|
# Create a new WhenNode node
|
data/src/diagnostic.c
CHANGED
@@ -54,12 +54,14 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
|
54
54
|
[PM_ERR_ALIAS_ARGUMENT] = "Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable",
|
55
55
|
[PM_ERR_AMPAMPEQ_MULTI_ASSIGN] = "Unexpected `&&=` in a multiple assignment",
|
56
56
|
[PM_ERR_ARGUMENT_AFTER_BLOCK] = "Unexpected argument after a block argument",
|
57
|
+
[PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES] = "Unexpected argument after `...`",
|
57
58
|
[PM_ERR_ARGUMENT_BARE_HASH] = "Unexpected bare hash argument",
|
58
59
|
[PM_ERR_ARGUMENT_BLOCK_MULTI] = "Multiple block arguments; only one block is allowed",
|
59
60
|
[PM_ERR_ARGUMENT_FORMAL_CLASS] = "Invalid formal argument; formal argument cannot be a class variable",
|
60
61
|
[PM_ERR_ARGUMENT_FORMAL_CONSTANT] = "Invalid formal argument; formal argument cannot be a constant",
|
61
62
|
[PM_ERR_ARGUMENT_FORMAL_GLOBAL] = "Invalid formal argument; formal argument cannot be a global variable",
|
62
63
|
[PM_ERR_ARGUMENT_FORMAL_IVAR] = "Invalid formal argument; formal argument cannot be an instance variable",
|
64
|
+
[PM_ERR_ARGUMENT_FORWARDING_UNBOUND] = "Unexpected `...` in an non-parenthesized call",
|
63
65
|
[PM_ERR_ARGUMENT_NO_FORWARDING_AMP] = "Unexpected `&` when the parent method is not forwarding",
|
64
66
|
[PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = "Unexpected `...` when the parent method is not forwarding",
|
65
67
|
[PM_ERR_ARGUMENT_NO_FORWARDING_STAR] = "Unexpected `*` when the parent method is not forwarding",
|
@@ -85,6 +87,7 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
|
85
87
|
[PM_ERR_CANNOT_PARSE_STRING_PART] = "Cannot parse the string part",
|
86
88
|
[PM_ERR_CASE_EXPRESSION_AFTER_CASE] = "Expected an expression after `case`",
|
87
89
|
[PM_ERR_CASE_EXPRESSION_AFTER_WHEN] = "Expected an expression after `when`",
|
90
|
+
[PM_ERR_CASE_MATCH_MISSING_PREDICATE] = "Expected a predicate for a case matching statement",
|
88
91
|
[PM_ERR_CASE_MISSING_CONDITIONS] = "Expected a `when` or `in` clause after `case`",
|
89
92
|
[PM_ERR_CASE_TERM] = "Expected an `end` to close the `case` statement",
|
90
93
|
[PM_ERR_CLASS_IN_METHOD] = "Unexpected class definition in a method body",
|
@@ -199,7 +202,7 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
|
199
202
|
[PM_ERR_PARAMETER_NAME_REPEAT] = "Repeated parameter name",
|
200
203
|
[PM_ERR_PARAMETER_NO_DEFAULT] = "Expected a default value for the parameter",
|
201
204
|
[PM_ERR_PARAMETER_NO_DEFAULT_KW] = "Expected a default value for the keyword parameter",
|
202
|
-
[PM_ERR_PARAMETER_NUMBERED_RESERVED] = "
|
205
|
+
[PM_ERR_PARAMETER_NUMBERED_RESERVED] = "%.2s is reserved for a numbered parameter",
|
203
206
|
[PM_ERR_PARAMETER_ORDER] = "Unexpected parameter order",
|
204
207
|
[PM_ERR_PARAMETER_SPLAT_MULTI] = "Unexpected multiple `*` splat parameters",
|
205
208
|
[PM_ERR_PARAMETER_STAR] = "Unexpected parameter `*`",
|
@@ -244,6 +247,7 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
|
244
247
|
[PM_ERR_UNARY_RECEIVER_PLUS] = "Expected a receiver for unary `+`",
|
245
248
|
[PM_ERR_UNARY_RECEIVER_TILDE] = "Expected a receiver for unary `~`",
|
246
249
|
[PM_ERR_UNTIL_TERM] = "Expected an `end` to close the `until` statement",
|
250
|
+
[PM_ERR_VOID_EXPRESSION] = "Unexpected void value expression",
|
247
251
|
[PM_ERR_WHILE_TERM] = "Expected an `end` to close the `while` statement",
|
248
252
|
[PM_ERR_WRITE_TARGET_READONLY] = "Immutable variable as a write target",
|
249
253
|
[PM_ERR_WRITE_TARGET_UNEXPECTED] = "Unexpected write target",
|
@@ -252,13 +256,16 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
|
252
256
|
[PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS] = "Ambiguous first argument; put parentheses or a space even after `+` operator",
|
253
257
|
[PM_WARN_AMBIGUOUS_PREFIX_STAR] = "Ambiguous `*` has been interpreted as an argument prefix",
|
254
258
|
[PM_WARN_AMBIGUOUS_SLASH] = "Ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator",
|
259
|
+
[PM_WARN_END_IN_METHOD] = "END in method; use at_exit",
|
255
260
|
};
|
256
261
|
|
257
262
|
static const char*
|
258
263
|
pm_diagnostic_message(pm_diagnostic_id_t diag_id) {
|
259
264
|
assert(diag_id < PM_DIAGNOSTIC_ID_LEN);
|
265
|
+
|
260
266
|
const char *message = diagnostic_messages[diag_id];
|
261
267
|
assert(message);
|
268
|
+
|
262
269
|
return message;
|
263
270
|
}
|
264
271
|
|
@@ -270,7 +277,57 @@ pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *
|
|
270
277
|
pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) calloc(sizeof(pm_diagnostic_t), 1);
|
271
278
|
if (diagnostic == NULL) return false;
|
272
279
|
|
273
|
-
*diagnostic = (pm_diagnostic_t) {
|
280
|
+
*diagnostic = (pm_diagnostic_t) {
|
281
|
+
.start = start,
|
282
|
+
.end = end,
|
283
|
+
.message = pm_diagnostic_message(diag_id),
|
284
|
+
.owned = false
|
285
|
+
};
|
286
|
+
|
287
|
+
pm_list_append(list, (pm_list_node_t *) diagnostic);
|
288
|
+
return true;
|
289
|
+
}
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Append a diagnostic to the given list of diagnostics that is using a format
|
293
|
+
* string for its message.
|
294
|
+
*/
|
295
|
+
bool
|
296
|
+
pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...) {
|
297
|
+
va_list arguments;
|
298
|
+
va_start(arguments, diag_id);
|
299
|
+
|
300
|
+
const char *format = pm_diagnostic_message(diag_id);
|
301
|
+
int result = vsnprintf(NULL, 0, format, arguments);
|
302
|
+
va_end(arguments);
|
303
|
+
|
304
|
+
if (result < 0) {
|
305
|
+
return false;
|
306
|
+
}
|
307
|
+
|
308
|
+
pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) calloc(sizeof(pm_diagnostic_t), 1);
|
309
|
+
if (diagnostic == NULL) {
|
310
|
+
return false;
|
311
|
+
}
|
312
|
+
|
313
|
+
size_t length = (size_t) (result + 1);
|
314
|
+
char *message = (char *) malloc(length);
|
315
|
+
if (message == NULL) {
|
316
|
+
free(diagnostic);
|
317
|
+
return false;
|
318
|
+
}
|
319
|
+
|
320
|
+
va_start(arguments, diag_id);
|
321
|
+
vsnprintf(message, length, format, arguments);
|
322
|
+
va_end(arguments);
|
323
|
+
|
324
|
+
*diagnostic = (pm_diagnostic_t) {
|
325
|
+
.start = start,
|
326
|
+
.end = end,
|
327
|
+
.message = message,
|
328
|
+
.owned = true
|
329
|
+
};
|
330
|
+
|
274
331
|
pm_list_append(list, (pm_list_node_t *) diagnostic);
|
275
332
|
return true;
|
276
333
|
}
|
@@ -284,8 +341,9 @@ pm_diagnostic_list_free(pm_list_t *list) {
|
|
284
341
|
|
285
342
|
for (node = list->head; node != NULL; node = next) {
|
286
343
|
next = node->next;
|
287
|
-
|
288
344
|
pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) node;
|
345
|
+
|
346
|
+
if (diagnostic->owned) free((void *) diagnostic->message);
|
289
347
|
free(diagnostic);
|
290
348
|
}
|
291
349
|
}
|