prism 0.17.0 → 0.18.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 +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
|
}
|