prism 0.17.1 → 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 +30 -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/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 +1 -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 +3 -3
- 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 +125 -131
- data/lib/prism/visitor.rb +3 -3
- data/lib/prism.rb +1 -0
- data/prism.gemspec +5 -1
- data/rbi/prism.rbi +83 -54
- 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.rbi
CHANGED
@@ -1025,6 +1025,56 @@ class Prism::CapturePatternNode < Prism::Node
|
|
1025
1025
|
def inspect(inspector); end
|
1026
1026
|
end
|
1027
1027
|
|
1028
|
+
# Represents the use of a case statement for pattern matching.
|
1029
|
+
#
|
1030
|
+
# case true
|
1031
|
+
# in false
|
1032
|
+
# end
|
1033
|
+
# ^^^^^^^^^
|
1034
|
+
class Prism::CaseMatchNode < Prism::Node
|
1035
|
+
sig { returns(T.nilable(Prism::Node)) }
|
1036
|
+
def predicate; end
|
1037
|
+
|
1038
|
+
sig { returns(T::Array[Prism::Node]) }
|
1039
|
+
def conditions; end
|
1040
|
+
|
1041
|
+
sig { returns(T.nilable(Prism::ElseNode)) }
|
1042
|
+
def consequent; end
|
1043
|
+
|
1044
|
+
sig { returns(Prism::Location) }
|
1045
|
+
def case_keyword_loc; end
|
1046
|
+
|
1047
|
+
sig { returns(Prism::Location) }
|
1048
|
+
def end_keyword_loc; end
|
1049
|
+
|
1050
|
+
sig { params(predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::Node], consequent: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location, location: Prism::Location).void }
|
1051
|
+
def initialize(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location); end
|
1052
|
+
|
1053
|
+
sig { params(visitor: Prism::Visitor).void }
|
1054
|
+
def accept(visitor); end
|
1055
|
+
|
1056
|
+
sig { returns(T::Array[T.nilable(Prism::Node)]) }
|
1057
|
+
def child_nodes; end
|
1058
|
+
|
1059
|
+
sig { returns(T::Array[T.nilable(Prism::Node)]) }
|
1060
|
+
def deconstruct; end
|
1061
|
+
|
1062
|
+
sig { params(params: T.untyped).returns(Prism::CaseMatchNode) }
|
1063
|
+
def copy(**params); end
|
1064
|
+
|
1065
|
+
sig { params(keys: T::Array[Symbol]).returns(T::Hash[Symbol, T.nilable(T.any(Prism::Node, T::Array[Prism::Node], String, Prism::Token, T::Array[Prism::Token], Prism::Location))]) }
|
1066
|
+
def deconstruct_keys(keys); end
|
1067
|
+
|
1068
|
+
sig { returns(String) }
|
1069
|
+
def case_keyword; end
|
1070
|
+
|
1071
|
+
sig { returns(String) }
|
1072
|
+
def end_keyword; end
|
1073
|
+
|
1074
|
+
sig { params(inspector: Prism::NodeInspector).returns(String) }
|
1075
|
+
def inspect(inspector); end
|
1076
|
+
end
|
1077
|
+
|
1028
1078
|
# Represents the use of a case statement.
|
1029
1079
|
#
|
1030
1080
|
# case true
|
@@ -2765,6 +2815,9 @@ class Prism::IfNode < Prism::Node
|
|
2765
2815
|
sig { returns(Prism::Node) }
|
2766
2816
|
def predicate; end
|
2767
2817
|
|
2818
|
+
sig { returns(T.nilable(Prism::Location)) }
|
2819
|
+
def then_keyword_loc; end
|
2820
|
+
|
2768
2821
|
sig { returns(T.nilable(Prism::StatementsNode)) }
|
2769
2822
|
def statements; end
|
2770
2823
|
|
@@ -2774,8 +2827,8 @@ class Prism::IfNode < Prism::Node
|
|
2774
2827
|
sig { returns(T.nilable(Prism::Location)) }
|
2775
2828
|
def end_keyword_loc; end
|
2776
2829
|
|
2777
|
-
sig { params(if_keyword_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::Node), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).void }
|
2778
|
-
def initialize(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location); end
|
2830
|
+
sig { params(if_keyword_loc: T.nilable(Prism::Location), predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::Node), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).void }
|
2831
|
+
def initialize(if_keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location); end
|
2779
2832
|
|
2780
2833
|
sig { params(visitor: Prism::Visitor).void }
|
2781
2834
|
def accept(visitor); end
|
@@ -2797,6 +2850,9 @@ class Prism::IfNode < Prism::Node
|
|
2797
2850
|
sig { returns(T.nilable(String)) }
|
2798
2851
|
def if_keyword; end
|
2799
2852
|
|
2853
|
+
sig { returns(T.nilable(String)) }
|
2854
|
+
def then_keyword; end
|
2855
|
+
|
2800
2856
|
sig { returns(T.nilable(String)) }
|
2801
2857
|
def end_keyword; end
|
2802
2858
|
|
@@ -4211,11 +4267,11 @@ class Prism::MatchWriteNode < Prism::Node
|
|
4211
4267
|
sig { returns(Prism::CallNode) }
|
4212
4268
|
def call; end
|
4213
4269
|
|
4214
|
-
sig { returns(T::Array[
|
4215
|
-
def
|
4270
|
+
sig { returns(T::Array[Prism::Node]) }
|
4271
|
+
def targets; end
|
4216
4272
|
|
4217
|
-
sig { params(call: Prism::CallNode,
|
4218
|
-
def initialize(call,
|
4273
|
+
sig { params(call: Prism::CallNode, targets: T::Array[Prism::Node], location: Prism::Location).void }
|
4274
|
+
def initialize(call, targets, location); end
|
4219
4275
|
|
4220
4276
|
sig { params(visitor: Prism::Visitor).void }
|
4221
4277
|
def accept(visitor); end
|
@@ -5651,39 +5707,6 @@ class Prism::StatementsNode < Prism::Node
|
|
5651
5707
|
def inspect(inspector); end
|
5652
5708
|
end
|
5653
5709
|
|
5654
|
-
# Represents the use of compile-time string concatenation.
|
5655
|
-
#
|
5656
|
-
# "foo" "bar"
|
5657
|
-
# ^^^^^^^^^^^
|
5658
|
-
class Prism::StringConcatNode < Prism::Node
|
5659
|
-
sig { returns(Prism::Node) }
|
5660
|
-
def left; end
|
5661
|
-
|
5662
|
-
sig { returns(Prism::Node) }
|
5663
|
-
def right; end
|
5664
|
-
|
5665
|
-
sig { params(left: Prism::Node, right: Prism::Node, location: Prism::Location).void }
|
5666
|
-
def initialize(left, right, location); end
|
5667
|
-
|
5668
|
-
sig { params(visitor: Prism::Visitor).void }
|
5669
|
-
def accept(visitor); end
|
5670
|
-
|
5671
|
-
sig { returns(T::Array[T.nilable(Prism::Node)]) }
|
5672
|
-
def child_nodes; end
|
5673
|
-
|
5674
|
-
sig { returns(T::Array[T.nilable(Prism::Node)]) }
|
5675
|
-
def deconstruct; end
|
5676
|
-
|
5677
|
-
sig { params(params: T.untyped).returns(Prism::StringConcatNode) }
|
5678
|
-
def copy(**params); end
|
5679
|
-
|
5680
|
-
sig { params(keys: T::Array[Symbol]).returns(T::Hash[Symbol, T.nilable(T.any(Prism::Node, T::Array[Prism::Node], String, Prism::Token, T::Array[Prism::Token], Prism::Location))]) }
|
5681
|
-
def deconstruct_keys(keys); end
|
5682
|
-
|
5683
|
-
sig { params(inspector: Prism::NodeInspector).returns(String) }
|
5684
|
-
def inspect(inspector); end
|
5685
|
-
end
|
5686
|
-
|
5687
5710
|
# Represents a string literal, a string contained within a `%w` list, or
|
5688
5711
|
# plain string content within an interpolated string.
|
5689
5712
|
#
|
@@ -5927,6 +5950,9 @@ class Prism::UnlessNode < Prism::Node
|
|
5927
5950
|
sig { returns(Prism::Node) }
|
5928
5951
|
def predicate; end
|
5929
5952
|
|
5953
|
+
sig { returns(T.nilable(Prism::Location)) }
|
5954
|
+
def then_keyword_loc; end
|
5955
|
+
|
5930
5956
|
sig { returns(T.nilable(Prism::StatementsNode)) }
|
5931
5957
|
def statements; end
|
5932
5958
|
|
@@ -5936,8 +5962,8 @@ class Prism::UnlessNode < Prism::Node
|
|
5936
5962
|
sig { returns(T.nilable(Prism::Location)) }
|
5937
5963
|
def end_keyword_loc; end
|
5938
5964
|
|
5939
|
-
sig { params(keyword_loc: Prism::Location, predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::ElseNode), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).void }
|
5940
|
-
def initialize(keyword_loc, predicate, statements, consequent, end_keyword_loc, location); end
|
5965
|
+
sig { params(keyword_loc: Prism::Location, predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::ElseNode), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).void }
|
5966
|
+
def initialize(keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location); end
|
5941
5967
|
|
5942
5968
|
sig { params(visitor: Prism::Visitor).void }
|
5943
5969
|
def accept(visitor); end
|
@@ -5959,6 +5985,9 @@ class Prism::UnlessNode < Prism::Node
|
|
5959
5985
|
sig { returns(String) }
|
5960
5986
|
def keyword; end
|
5961
5987
|
|
5988
|
+
sig { returns(T.nilable(String)) }
|
5989
|
+
def then_keyword; end
|
5990
|
+
|
5962
5991
|
sig { returns(T.nilable(String)) }
|
5963
5992
|
def end_keyword; end
|
5964
5993
|
|
@@ -6370,6 +6399,10 @@ class Prism::Visitor < Prism::BasicVisitor
|
|
6370
6399
|
sig { params(node: Prism::CapturePatternNode).void }
|
6371
6400
|
def visit_capture_pattern_node(node); end
|
6372
6401
|
|
6402
|
+
# Visit a CaseMatchNode node
|
6403
|
+
sig { params(node: Prism::CaseMatchNode).void }
|
6404
|
+
def visit_case_match_node(node); end
|
6405
|
+
|
6373
6406
|
# Visit a CaseNode node
|
6374
6407
|
sig { params(node: Prism::CaseNode).void }
|
6375
6408
|
def visit_case_node(node); end
|
@@ -6810,10 +6843,6 @@ class Prism::Visitor < Prism::BasicVisitor
|
|
6810
6843
|
sig { params(node: Prism::StatementsNode).void }
|
6811
6844
|
def visit_statements_node(node); end
|
6812
6845
|
|
6813
|
-
# Visit a StringConcatNode node
|
6814
|
-
sig { params(node: Prism::StringConcatNode).void }
|
6815
|
-
def visit_string_concat_node(node); end
|
6816
|
-
|
6817
6846
|
# Visit a StringNode node
|
6818
6847
|
sig { params(node: Prism::StringNode).void }
|
6819
6848
|
def visit_string_node(node); end
|
@@ -6932,6 +6961,9 @@ module Prism::DSL
|
|
6932
6961
|
# Create a new CapturePatternNode node
|
6933
6962
|
sig { params(value: Prism::Node, target: Prism::Node, operator_loc: Prism::Location, location: Prism::Location).returns(Prism::CapturePatternNode) }
|
6934
6963
|
def CapturePatternNode(value, target, operator_loc, location); end
|
6964
|
+
# Create a new CaseMatchNode node
|
6965
|
+
sig { params(predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::Node], consequent: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location, location: Prism::Location).returns(Prism::CaseMatchNode) }
|
6966
|
+
def CaseMatchNode(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location); end
|
6935
6967
|
# Create a new CaseNode node
|
6936
6968
|
sig { params(predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::Node], consequent: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location, location: Prism::Location).returns(Prism::CaseNode) }
|
6937
6969
|
def CaseNode(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location); end
|
@@ -7059,8 +7091,8 @@ module Prism::DSL
|
|
7059
7091
|
sig { params(constant: T.nilable(Prism::Node), elements: T::Array[Prism::Node], rest: T.nilable(Prism::Node), opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), location: Prism::Location).returns(Prism::HashPatternNode) }
|
7060
7092
|
def HashPatternNode(constant, elements, rest, opening_loc, closing_loc, location); end
|
7061
7093
|
# Create a new IfNode node
|
7062
|
-
sig { params(if_keyword_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::Node), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).returns(Prism::IfNode) }
|
7063
|
-
def IfNode(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location); end
|
7094
|
+
sig { params(if_keyword_loc: T.nilable(Prism::Location), predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::Node), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).returns(Prism::IfNode) }
|
7095
|
+
def IfNode(if_keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location); end
|
7064
7096
|
# Create a new ImaginaryNode node
|
7065
7097
|
sig { params(numeric: Prism::Node, location: Prism::Location).returns(Prism::ImaginaryNode) }
|
7066
7098
|
def ImaginaryNode(numeric, location); end
|
@@ -7152,8 +7184,8 @@ module Prism::DSL
|
|
7152
7184
|
sig { params(value: Prism::Node, pattern: Prism::Node, operator_loc: Prism::Location, location: Prism::Location).returns(Prism::MatchRequiredNode) }
|
7153
7185
|
def MatchRequiredNode(value, pattern, operator_loc, location); end
|
7154
7186
|
# Create a new MatchWriteNode node
|
7155
|
-
sig { params(call: Prism::CallNode,
|
7156
|
-
def MatchWriteNode(call,
|
7187
|
+
sig { params(call: Prism::CallNode, targets: T::Array[Prism::Node], location: Prism::Location).returns(Prism::MatchWriteNode) }
|
7188
|
+
def MatchWriteNode(call, targets, location); end
|
7157
7189
|
# Create a new MissingNode node
|
7158
7190
|
sig { params(location: Prism::Location).returns(Prism::MissingNode) }
|
7159
7191
|
def MissingNode(location); end
|
@@ -7262,9 +7294,6 @@ module Prism::DSL
|
|
7262
7294
|
# Create a new StatementsNode node
|
7263
7295
|
sig { params(body: T::Array[Prism::Node], location: Prism::Location).returns(Prism::StatementsNode) }
|
7264
7296
|
def StatementsNode(body, location); end
|
7265
|
-
# Create a new StringConcatNode node
|
7266
|
-
sig { params(left: Prism::Node, right: Prism::Node, location: Prism::Location).returns(Prism::StringConcatNode) }
|
7267
|
-
def StringConcatNode(left, right, location); end
|
7268
7297
|
# Create a new StringNode node
|
7269
7298
|
sig { params(flags: Integer, opening_loc: T.nilable(Prism::Location), content_loc: Prism::Location, closing_loc: T.nilable(Prism::Location), unescaped: String, location: Prism::Location).returns(Prism::StringNode) }
|
7270
7299
|
def StringNode(flags, opening_loc, content_loc, closing_loc, unescaped, location); end
|
@@ -7281,8 +7310,8 @@ module Prism::DSL
|
|
7281
7310
|
sig { params(names: T::Array[Prism::Node], keyword_loc: Prism::Location, location: Prism::Location).returns(Prism::UndefNode) }
|
7282
7311
|
def UndefNode(names, keyword_loc, location); end
|
7283
7312
|
# Create a new UnlessNode node
|
7284
|
-
sig { params(keyword_loc: Prism::Location, predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::ElseNode), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).returns(Prism::UnlessNode) }
|
7285
|
-
def UnlessNode(keyword_loc, predicate, statements, consequent, end_keyword_loc, location); end
|
7313
|
+
sig { params(keyword_loc: Prism::Location, predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), consequent: T.nilable(Prism::ElseNode), end_keyword_loc: T.nilable(Prism::Location), location: Prism::Location).returns(Prism::UnlessNode) }
|
7314
|
+
def UnlessNode(keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location); end
|
7286
7315
|
# Create a new UntilNode node
|
7287
7316
|
sig { params(keyword_loc: Prism::Location, closing_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode), flags: Integer, location: Prism::Location).returns(Prism::UntilNode) }
|
7288
7317
|
def UntilNode(keyword_loc, closing_loc, predicate, statements, flags, location); 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
|
}
|
data/src/enc/pm_big5.c
CHANGED
@@ -15,6 +15,22 @@ pm_encoding_big5_char_width(const uint8_t *b, ptrdiff_t n) {
|
|
15
15
|
return 0;
|
16
16
|
}
|
17
17
|
|
18
|
+
static size_t
|
19
|
+
pm_encoding_big5_star_char_width(const uint8_t *b, ptrdiff_t n) {
|
20
|
+
// These are the single byte characters.
|
21
|
+
if (*b < 0x80) {
|
22
|
+
return 1;
|
23
|
+
}
|
24
|
+
|
25
|
+
// These are the double byte characters.
|
26
|
+
if ((n > 1) && (b[0] >= 0x87 && b[0] <= 0xFE) &&
|
27
|
+
((b[1] >= 0x40 && b[1] <= 0x7E) || (b[1] >= 0xA1 && b[1] <= 0xFE))) {
|
28
|
+
return 2;
|
29
|
+
}
|
30
|
+
|
31
|
+
return 0;
|
32
|
+
}
|
33
|
+
|
18
34
|
static size_t
|
19
35
|
pm_encoding_big5_alpha_char(const uint8_t *b, ptrdiff_t n) {
|
20
36
|
if (pm_encoding_big5_char_width(b, n) == 1) {
|
@@ -24,6 +40,15 @@ pm_encoding_big5_alpha_char(const uint8_t *b, ptrdiff_t n) {
|
|
24
40
|
}
|
25
41
|
}
|
26
42
|
|
43
|
+
static size_t
|
44
|
+
pm_encoding_big5_star_alpha_char(const uint8_t *b, ptrdiff_t n) {
|
45
|
+
if (pm_encoding_big5_star_char_width(b, n) == 1) {
|
46
|
+
return pm_encoding_ascii_alpha_char(b, n);
|
47
|
+
} else {
|
48
|
+
return 0;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
27
52
|
static size_t
|
28
53
|
pm_encoding_big5_alnum_char(const uint8_t *b, ptrdiff_t n) {
|
29
54
|
if (pm_encoding_big5_char_width(b, n) == 1) {
|
@@ -33,6 +58,15 @@ pm_encoding_big5_alnum_char(const uint8_t *b, ptrdiff_t n) {
|
|
33
58
|
}
|
34
59
|
}
|
35
60
|
|
61
|
+
static size_t
|
62
|
+
pm_encoding_big5_star_alnum_char(const uint8_t *b, ptrdiff_t n) {
|
63
|
+
if (pm_encoding_big5_star_char_width(b, n) == 1) {
|
64
|
+
return pm_encoding_ascii_alnum_char(b, n);
|
65
|
+
} else {
|
66
|
+
return 0;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
36
70
|
static bool
|
37
71
|
pm_encoding_big5_isupper_char(const uint8_t *b, ptrdiff_t n) {
|
38
72
|
if (pm_encoding_big5_char_width(b, n) == 1) {
|
@@ -42,6 +76,15 @@ pm_encoding_big5_isupper_char(const uint8_t *b, ptrdiff_t n) {
|
|
42
76
|
}
|
43
77
|
}
|
44
78
|
|
79
|
+
static bool
|
80
|
+
pm_encoding_big5_star_isupper_char(const uint8_t *b, ptrdiff_t n) {
|
81
|
+
if (pm_encoding_big5_star_char_width(b, n) == 1) {
|
82
|
+
return pm_encoding_ascii_isupper_char(b, n);
|
83
|
+
} else {
|
84
|
+
return false;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
45
88
|
/** Big5 encoding */
|
46
89
|
pm_encoding_t pm_encoding_big5 = {
|
47
90
|
.name = "big5",
|
@@ -51,3 +94,23 @@ pm_encoding_t pm_encoding_big5 = {
|
|
51
94
|
.isupper_char = pm_encoding_big5_isupper_char,
|
52
95
|
.multibyte = true
|
53
96
|
};
|
97
|
+
|
98
|
+
/** Big5-HKSCS encoding */
|
99
|
+
pm_encoding_t pm_encoding_big5_hkscs = {
|
100
|
+
.name = "big5-hkscs",
|
101
|
+
.char_width = pm_encoding_big5_star_char_width,
|
102
|
+
.alnum_char = pm_encoding_big5_star_alnum_char,
|
103
|
+
.alpha_char = pm_encoding_big5_star_alpha_char,
|
104
|
+
.isupper_char = pm_encoding_big5_star_isupper_char,
|
105
|
+
.multibyte = true
|
106
|
+
};
|
107
|
+
|
108
|
+
/** Big5-UAO encoding */
|
109
|
+
pm_encoding_t pm_encoding_big5_uao = {
|
110
|
+
.name = "big5-uao",
|
111
|
+
.char_width = pm_encoding_big5_star_char_width,
|
112
|
+
.alnum_char = pm_encoding_big5_star_alnum_char,
|
113
|
+
.alpha_char = pm_encoding_big5_star_alpha_char,
|
114
|
+
.isupper_char = pm_encoding_big5_star_isupper_char,
|
115
|
+
.multibyte = true
|
116
|
+
};
|