rbs 4.1.3-java → 4.2.0.pre.1-java
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/.gitattributes +1 -0
- data/.github/workflows/bundle-update.yml +2 -2
- data/.github/workflows/c-check.yml +2 -2
- data/.github/workflows/changelog.yml +121 -0
- data/.github/workflows/comments.yml +2 -2
- data/.github/workflows/dependabot.yml +1 -1
- data/.github/workflows/jruby.yml +3 -3
- data/.github/workflows/release-gems.yml +6 -7
- data/.github/workflows/ruby.yml +6 -6
- data/.github/workflows/rust.yml +12 -12
- data/.github/workflows/truffleruby.yml +2 -2
- data/.github/workflows/typecheck.yml +2 -2
- data/.github/workflows/wasm.yml +3 -3
- data/.github/workflows/windows.yml +2 -2
- data/CHANGELOG.md +27 -0
- data/Rakefile +50 -21
- data/config.yml +5 -0
- data/docs/CONTRIBUTING.md +1 -1
- data/docs/release.md +57 -1
- data/docs/stdlib.md +8 -0
- data/docs/syntax.md +12 -0
- data/ext/rbs_extension/ast_translation.c +15 -0
- data/ext/rbs_extension/class_constants.c +2 -0
- data/ext/rbs_extension/class_constants.h +1 -0
- data/ext/rbs_extension/main.c +55 -19
- data/include/rbs/ast.h +21 -13
- data/include/rbs/defines.h +2 -2
- data/include/rbs/lexer.h +13 -12
- data/include/rbs/parser.h +37 -3
- data/lib/rbs/ast/declarations.rb +1 -1
- data/lib/rbs/ast/type_param.rb +1 -1
- data/lib/rbs/definition_builder/ancestor_builder.rb +8 -5
- data/lib/rbs/definition_builder/method_builder.rb +4 -4
- data/lib/rbs/definition_builder.rb +5 -2
- data/lib/rbs/environment/class_entry.rb +12 -0
- data/lib/rbs/environment/module_entry.rb +26 -1
- data/lib/rbs/parser_aux.rb +2 -2
- data/lib/rbs/types.rb +44 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/wasm/parser.rb +62 -25
- data/lib/rbs/wasm/rbs_parser.wasm +0 -0
- data/lib/rbs/wasm/runtime.rb +19 -4
- data/lib/rbs/wasm/serialization_schema.rb +3 -2
- data/schema/function.json +12 -1
- data/sig/environment/class_entry.rbs +6 -0
- data/sig/environment/module_entry.rbs +15 -0
- data/sig/parser.rbs +4 -4
- data/sig/types.rbs +11 -1
- data/src/ast.c +17 -1
- data/src/lexer.c +1562 -1560
- data/src/lexer.re +50 -18
- data/src/lexstate.c +2 -1
- data/src/parser.c +130 -70
- data/src/serialize.c +20 -13
- data/src/util/rbs_encoding.c +195 -49
- data/wasm/README.md +20 -4
- data/wasm/rbs_wasm.c +93 -37
- metadata +3 -1
|
@@ -42,10 +42,35 @@ module RBS
|
|
|
42
42
|
|
|
43
43
|
def self_types
|
|
44
44
|
each_decl.flat_map do |decl|
|
|
45
|
-
decl.self_types
|
|
45
|
+
self_types = decl.self_types
|
|
46
|
+
subst = align_params(decl)
|
|
47
|
+
|
|
48
|
+
if self_types.empty? || subst.nil?
|
|
49
|
+
self_types
|
|
50
|
+
else
|
|
51
|
+
self_types.map do |self_type|
|
|
52
|
+
AST::Declarations::Module::Self.new(
|
|
53
|
+
name: self_type.name,
|
|
54
|
+
args: self_type.args.map {|type| type.sub(subst) },
|
|
55
|
+
location: self_type.location
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
46
59
|
end.uniq
|
|
47
60
|
end
|
|
48
61
|
|
|
62
|
+
def align_params(decl)
|
|
63
|
+
entry_params = type_params
|
|
64
|
+
decl_param_names = decl.type_params.map(&:name)
|
|
65
|
+
|
|
66
|
+
return nil if decl_param_names == entry_params.map(&:name)
|
|
67
|
+
|
|
68
|
+
Substitution.build(
|
|
69
|
+
decl_param_names,
|
|
70
|
+
entry_params.map {|param| Types::Variable.new(name: param.name, location: param.location) }
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
|
|
49
74
|
def validate_type_params
|
|
50
75
|
unless context_decls.empty?
|
|
51
76
|
first_decl, *rest_decls = each_decl.to_a
|
data/lib/rbs/parser_aux.rb
CHANGED
|
@@ -14,7 +14,7 @@ module RBS
|
|
|
14
14
|
def self.parse_method_type(source, range: nil, byte_range: 0..., variables: [], require_eof: false)
|
|
15
15
|
buf = buffer(source)
|
|
16
16
|
byte_range = byte_range(range, buf.content) if range
|
|
17
|
-
_parse_method_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof)
|
|
17
|
+
_parse_method_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof, false)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.parse_signature(source)
|
|
@@ -28,7 +28,7 @@ module RBS
|
|
|
28
28
|
0
|
|
29
29
|
end
|
|
30
30
|
content = buf.content
|
|
31
|
-
dirs, decls = _parse_signature(buf, start_pos, content.bytesize)
|
|
31
|
+
dirs, decls = _parse_signature(buf, start_pos, content.bytesize, false)
|
|
32
32
|
|
|
33
33
|
if resolved
|
|
34
34
|
dirs = dirs.dup if dirs.frozen?
|
data/lib/rbs/types.rb
CHANGED
|
@@ -959,6 +959,33 @@ module RBS
|
|
|
959
959
|
end
|
|
960
960
|
end
|
|
961
961
|
|
|
962
|
+
class ForwardingParam
|
|
963
|
+
attr_reader :location
|
|
964
|
+
|
|
965
|
+
def initialize(location:)
|
|
966
|
+
@location = location
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
def ==(other)
|
|
970
|
+
other.is_a?(ForwardingParam)
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
alias eql? ==
|
|
974
|
+
|
|
975
|
+
def hash
|
|
976
|
+
self.class.hash
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
def to_json(state = nil)
|
|
980
|
+
json = {} #: Hash[Symbol, untyped]
|
|
981
|
+
json.to_json(state)
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
def to_s
|
|
985
|
+
"..."
|
|
986
|
+
end
|
|
987
|
+
end
|
|
988
|
+
|
|
962
989
|
attr_reader :required_positionals
|
|
963
990
|
attr_reader :optional_positionals
|
|
964
991
|
attr_reader :rest_positionals
|
|
@@ -966,9 +993,10 @@ module RBS
|
|
|
966
993
|
attr_reader :required_keywords
|
|
967
994
|
attr_reader :optional_keywords
|
|
968
995
|
attr_reader :rest_keywords
|
|
996
|
+
attr_reader :forwarding
|
|
969
997
|
attr_reader :return_type
|
|
970
998
|
|
|
971
|
-
def initialize(required_positionals:, optional_positionals:, rest_positionals:, trailing_positionals:, required_keywords:, optional_keywords:, rest_keywords:, return_type:)
|
|
999
|
+
def initialize(required_positionals:, optional_positionals:, rest_positionals:, trailing_positionals:, required_keywords:, optional_keywords:, rest_keywords:, return_type:, forwarding: nil)
|
|
972
1000
|
@return_type = return_type
|
|
973
1001
|
@required_positionals = required_positionals
|
|
974
1002
|
@optional_positionals = optional_positionals
|
|
@@ -977,6 +1005,7 @@ module RBS
|
|
|
977
1005
|
@required_keywords = required_keywords
|
|
978
1006
|
@optional_keywords = optional_keywords
|
|
979
1007
|
@rest_keywords = rest_keywords
|
|
1008
|
+
@forwarding = forwarding
|
|
980
1009
|
end
|
|
981
1010
|
|
|
982
1011
|
def ==(other)
|
|
@@ -988,6 +1017,7 @@ module RBS
|
|
|
988
1017
|
other.required_keywords == required_keywords &&
|
|
989
1018
|
other.optional_keywords == optional_keywords &&
|
|
990
1019
|
other.rest_keywords == rest_keywords &&
|
|
1020
|
+
other.forwarding == forwarding &&
|
|
991
1021
|
other.return_type == return_type
|
|
992
1022
|
end
|
|
993
1023
|
|
|
@@ -1002,6 +1032,7 @@ module RBS
|
|
|
1002
1032
|
required_keywords.hash ^
|
|
1003
1033
|
optional_keywords.hash ^
|
|
1004
1034
|
rest_keywords.hash ^
|
|
1035
|
+
forwarding.hash ^
|
|
1005
1036
|
return_type.hash
|
|
1006
1037
|
end
|
|
1007
1038
|
|
|
@@ -1043,6 +1074,7 @@ module RBS
|
|
|
1043
1074
|
required_keywords: hmapv(required_keywords) {|param| param.map_type(&block) },
|
|
1044
1075
|
optional_keywords: hmapv(optional_keywords) {|param| param.map_type(&block) },
|
|
1045
1076
|
rest_keywords: rest_keywords&.yield_self {|param| param.map_type(&block) },
|
|
1077
|
+
forwarding: forwarding,
|
|
1046
1078
|
return_type: yield(return_type)
|
|
1047
1079
|
)
|
|
1048
1080
|
else
|
|
@@ -1110,6 +1142,7 @@ module RBS
|
|
|
1110
1142
|
required_keywords: required_keywords,
|
|
1111
1143
|
optional_keywords: optional_keywords,
|
|
1112
1144
|
rest_keywords: rest_keywords,
|
|
1145
|
+
forwarding: forwarding,
|
|
1113
1146
|
return_type: return_type
|
|
1114
1147
|
}.to_json(state)
|
|
1115
1148
|
end
|
|
@@ -1129,6 +1162,7 @@ module RBS
|
|
|
1129
1162
|
required_keywords: {},
|
|
1130
1163
|
optional_keywords: {},
|
|
1131
1164
|
rest_keywords: nil,
|
|
1165
|
+
forwarding: nil,
|
|
1132
1166
|
return_type: return_type
|
|
1133
1167
|
)
|
|
1134
1168
|
end
|
|
@@ -1142,12 +1176,13 @@ module RBS
|
|
|
1142
1176
|
required_keywords: required_keywords,
|
|
1143
1177
|
optional_keywords: optional_keywords,
|
|
1144
1178
|
rest_keywords: rest_keywords,
|
|
1179
|
+
forwarding: forwarding,
|
|
1145
1180
|
return_type: type
|
|
1146
1181
|
)
|
|
1147
1182
|
end
|
|
1148
1183
|
|
|
1149
1184
|
def update(required_positionals: self.required_positionals, optional_positionals: self.optional_positionals, rest_positionals: self.rest_positionals, trailing_positionals: self.trailing_positionals,
|
|
1150
|
-
required_keywords: self.required_keywords, optional_keywords: self.optional_keywords, rest_keywords: self.rest_keywords, return_type: self.return_type)
|
|
1185
|
+
required_keywords: self.required_keywords, optional_keywords: self.optional_keywords, rest_keywords: self.rest_keywords, forwarding: self.forwarding, return_type: self.return_type)
|
|
1151
1186
|
Function.new(
|
|
1152
1187
|
required_positionals: required_positionals,
|
|
1153
1188
|
optional_positionals: optional_positionals,
|
|
@@ -1156,6 +1191,7 @@ module RBS
|
|
|
1156
1191
|
required_keywords: required_keywords,
|
|
1157
1192
|
optional_keywords: optional_keywords,
|
|
1158
1193
|
rest_keywords: rest_keywords,
|
|
1194
|
+
forwarding: forwarding,
|
|
1159
1195
|
return_type: return_type
|
|
1160
1196
|
)
|
|
1161
1197
|
end
|
|
@@ -1167,6 +1203,7 @@ module RBS
|
|
|
1167
1203
|
trailing_positionals.empty? &&
|
|
1168
1204
|
required_keywords.empty? &&
|
|
1169
1205
|
optional_keywords.empty? &&
|
|
1206
|
+
!forwarding? &&
|
|
1170
1207
|
!rest_keywords
|
|
1171
1208
|
end
|
|
1172
1209
|
|
|
@@ -1175,6 +1212,7 @@ module RBS
|
|
|
1175
1212
|
params = []
|
|
1176
1213
|
|
|
1177
1214
|
params.push(*required_positionals.map(&:to_s))
|
|
1215
|
+
params.push(forwarding.to_s) if forwarding
|
|
1178
1216
|
params.push(*optional_positionals.map {|p| "?#{p}"})
|
|
1179
1217
|
params.push("*#{rest_positionals}") if rest_positionals
|
|
1180
1218
|
params.push(*trailing_positionals.map(&:to_s))
|
|
@@ -1185,6 +1223,10 @@ module RBS
|
|
|
1185
1223
|
params.join(", ")
|
|
1186
1224
|
end
|
|
1187
1225
|
|
|
1226
|
+
def forwarding?
|
|
1227
|
+
!forwarding.nil?
|
|
1228
|
+
end
|
|
1229
|
+
|
|
1188
1230
|
def return_to_s
|
|
1189
1231
|
return_type.to_s(1)
|
|
1190
1232
|
end
|
data/lib/rbs/version.rb
CHANGED
data/lib/rbs/wasm/parser.rb
CHANGED
|
@@ -12,83 +12,102 @@ module RBS
|
|
|
12
12
|
# RBS::Parser API on top, exactly as it does for the C extension.
|
|
13
13
|
class Parser
|
|
14
14
|
class << self
|
|
15
|
-
def _parse_signature(buffer, start_pos, end_pos)
|
|
16
|
-
validate_position_range(start_pos, end_pos)
|
|
15
|
+
def _parse_signature(buffer, start_pos, end_pos, enable_forwarding_params)
|
|
16
|
+
validate_position_range(buffer, start_pos, end_pos)
|
|
17
|
+
validate_parser_options(enable_forwarding_params)
|
|
17
18
|
encoding = buffer.content.encoding.name
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
status, bytes = WASM::Runtime.instance.parse_signature(buffer.content, encoding, start_pos, end_pos)
|
|
20
|
+
raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
|
|
20
21
|
|
|
21
22
|
WASM::Deserializer.deserialize(bytes, buffer)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def _parse_type(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
|
|
25
|
-
validate_position_range(start_pos, end_pos)
|
|
26
|
+
validate_position_range(buffer, start_pos, end_pos)
|
|
26
27
|
validate_variables(variables)
|
|
27
28
|
encoding = buffer.content.encoding.name
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
status, bytes = WASM::Runtime.instance.parse_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
|
|
30
|
+
raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
|
|
30
31
|
|
|
31
32
|
deserialize_or_nil(bytes, buffer)
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
def _parse_method_type(buffer, start_pos, end_pos, variables, require_eof)
|
|
35
|
-
validate_position_range(start_pos, end_pos)
|
|
35
|
+
def _parse_method_type(buffer, start_pos, end_pos, variables, require_eof, enable_forwarding_params)
|
|
36
|
+
validate_position_range(buffer, start_pos, end_pos)
|
|
36
37
|
validate_variables(variables)
|
|
38
|
+
validate_parser_options(enable_forwarding_params)
|
|
37
39
|
encoding = buffer.content.encoding.name
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
status, bytes = WASM::Runtime.instance.parse_method_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof)
|
|
41
|
+
raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
|
|
40
42
|
|
|
41
43
|
deserialize_or_nil(bytes, buffer)
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
def _parse_type_params(buffer, start_pos, end_pos, module_type_params)
|
|
45
|
-
validate_position_range(start_pos, end_pos)
|
|
47
|
+
validate_position_range(buffer, start_pos, end_pos)
|
|
46
48
|
encoding = buffer.content.encoding.name
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
status, bytes = WASM::Runtime.instance.parse_type_params(buffer.content, encoding, start_pos, end_pos, module_type_params)
|
|
50
|
+
raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
|
|
49
51
|
|
|
50
52
|
bytes.empty? ? nil : WASM::Deserializer.deserialize_node_list(bytes, buffer)
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
def _lex(buffer, end_pos)
|
|
54
56
|
encoding = buffer.content.encoding.name
|
|
55
|
-
|
|
57
|
+
_status, bytes = WASM::Runtime.instance.lex(buffer.content, encoding, end_pos)
|
|
56
58
|
|
|
57
59
|
WASM::Deserializer.deserialize_tokens(bytes, buffer)
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
def _parse_inline_leading_annotation(buffer, start_pos, end_pos, variables)
|
|
61
|
-
validate_position_range(start_pos, end_pos)
|
|
63
|
+
validate_position_range(buffer, start_pos, end_pos)
|
|
62
64
|
validate_variables(variables)
|
|
63
65
|
encoding = buffer.content.encoding.name
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
status, bytes = WASM::Runtime.instance.parse_inline_leading_annotation(buffer.content, encoding, start_pos, end_pos, variables)
|
|
67
|
+
raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
|
|
66
68
|
|
|
67
69
|
deserialize_or_nil(bytes, buffer)
|
|
68
70
|
end
|
|
69
71
|
|
|
70
72
|
def _parse_inline_trailing_annotation(buffer, start_pos, end_pos, variables)
|
|
71
|
-
validate_position_range(start_pos, end_pos)
|
|
73
|
+
validate_position_range(buffer, start_pos, end_pos)
|
|
72
74
|
validate_variables(variables)
|
|
73
75
|
encoding = buffer.content.encoding.name
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
status, bytes = WASM::Runtime.instance.parse_inline_trailing_annotation(buffer.content, encoding, start_pos, end_pos, variables)
|
|
77
|
+
raise_parse_failure(buffer, status, bytes, start_pos, end_pos) unless status == WASM::Runtime::OK
|
|
76
78
|
|
|
77
79
|
deserialize_or_nil(bytes, buffer)
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
private
|
|
81
83
|
|
|
82
|
-
# Reject
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
|
|
84
|
+
# Reject the position ranges the parser cannot take, matching
|
|
85
|
+
# validate_position_range in the C extension (main.c).
|
|
86
|
+
#
|
|
87
|
+
# `end_pos` past the end of the buffer is fine: clamping with a large
|
|
88
|
+
# number instead of measuring the buffer is ordinary, and the lexer stops
|
|
89
|
+
# at the end of the input on its own.
|
|
90
|
+
def validate_position_range(buffer, start_pos, end_pos)
|
|
86
91
|
if start_pos < 0 || end_pos < 0
|
|
87
92
|
raise ArgumentError, "negative position range: #{start_pos}...#{end_pos}"
|
|
88
93
|
end
|
|
89
94
|
if start_pos > end_pos
|
|
90
95
|
raise ArgumentError, "invalid position range: #{start_pos}...#{end_pos}"
|
|
91
96
|
end
|
|
97
|
+
|
|
98
|
+
size = buffer.content.bytesize
|
|
99
|
+
if start_pos > size
|
|
100
|
+
raise ArgumentError, "position range starts past the end of the buffer: #{start_pos}...#{end_pos}, buffer is #{size} bytes"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# The WebAssembly entry points (rbs_wasm.c) build their parsers with the
|
|
105
|
+
# default options, so the optional syntax the C extension can enable is
|
|
106
|
+
# not reachable here. The public RBS::Parser API never enables it.
|
|
107
|
+
def validate_parser_options(enable_forwarding_params)
|
|
108
|
+
if enable_forwarding_params
|
|
109
|
+
raise NotImplementedError, "forwarding parameter syntax is not supported by the WebAssembly parser"
|
|
110
|
+
end
|
|
92
111
|
end
|
|
93
112
|
|
|
94
113
|
# Reject anything that is not nil or an Array of Symbols, matching
|
|
@@ -112,6 +131,24 @@ module RBS
|
|
|
112
131
|
bytes.empty? ? nil : WASM::Deserializer.deserialize(bytes, buffer)
|
|
113
132
|
end
|
|
114
133
|
|
|
134
|
+
# Raise for a status other than OK (see rbs_wasm.c).
|
|
135
|
+
#
|
|
136
|
+
# A negative status is about the range rather than the source text, so it
|
|
137
|
+
# comes with an empty result and an ArgumentError, as in the C extension
|
|
138
|
+
# (main.c). Starting past the end of the buffer is plain from the
|
|
139
|
+
# buffer's size and rejected above, so a start position that comes back
|
|
140
|
+
# rejected can only be one inside a character.
|
|
141
|
+
def raise_parse_failure(buffer, status, bytes, start_pos, end_pos)
|
|
142
|
+
case status
|
|
143
|
+
when WASM::Runtime::INVALID_START_POS
|
|
144
|
+
raise ArgumentError, "position range starts inside a character: #{start_pos}...#{end_pos}"
|
|
145
|
+
when WASM::Runtime::INVALID_RANGE
|
|
146
|
+
raise ArgumentError, "invalid position range: #{start_pos}...#{end_pos}"
|
|
147
|
+
else
|
|
148
|
+
raise_parsing_error(buffer, bytes)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
115
152
|
# Decodes the error blob written by set_error_result (rbs_wasm.c) and raises
|
|
116
153
|
# the same error the C extension would (see raise_error in main.c).
|
|
117
154
|
def raise_parsing_error(buffer, blob)
|
|
Binary file
|
data/lib/rbs/wasm/runtime.rb
CHANGED
|
@@ -16,6 +16,14 @@ module RBS
|
|
|
16
16
|
class Runtime
|
|
17
17
|
include MonitorMixin
|
|
18
18
|
|
|
19
|
+
# Statuses the parse entry points return (see rbs_wasm.c). A negative one
|
|
20
|
+
# is about the range the caller asked for rather than the source text,
|
|
21
|
+
# and comes with an empty result.
|
|
22
|
+
INVALID_START_POS = -2
|
|
23
|
+
INVALID_RANGE = -1
|
|
24
|
+
PARSE_ERROR = 0
|
|
25
|
+
OK = 1
|
|
26
|
+
|
|
19
27
|
class << self
|
|
20
28
|
def instance
|
|
21
29
|
@instance ||= new
|
|
@@ -48,9 +56,9 @@ module RBS
|
|
|
48
56
|
end
|
|
49
57
|
|
|
50
58
|
# `content` is the whole buffer; `start_pos`/`end_pos` are the character
|
|
51
|
-
# range within it to parse. Each method returns [
|
|
52
|
-
# `bytes` is the serialized AST,
|
|
53
|
-
# set_error_result in rbs_wasm.c).
|
|
59
|
+
# range within it to parse. Each method returns [status, bytes]: with OK
|
|
60
|
+
# `bytes` is the serialized AST, with PARSE_ERROR it is the error blob (see
|
|
61
|
+
# set_error_result in rbs_wasm.c), and with a negative status it is empty.
|
|
54
62
|
|
|
55
63
|
def parse_signature(content, encoding, start_pos, end_pos)
|
|
56
64
|
run(content, encoding) { |ptr, len, enc_ptr, enc_len| @parse_signature.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos)[0] }
|
|
@@ -118,7 +126,7 @@ module RBS
|
|
|
118
126
|
@memory.write(source_ptr, bytes.to_java_bytes)
|
|
119
127
|
@memory.write(name_ptr, name.to_java_bytes) unless name_length.zero?
|
|
120
128
|
status = yield(source_ptr, length, name_ptr, name_length)
|
|
121
|
-
[status
|
|
129
|
+
[i32(status), read_result]
|
|
122
130
|
ensure
|
|
123
131
|
@free.apply(source_ptr)
|
|
124
132
|
@free.apply(name_ptr)
|
|
@@ -156,6 +164,13 @@ module RBS
|
|
|
156
164
|
end
|
|
157
165
|
end
|
|
158
166
|
|
|
167
|
+
# A WebAssembly i32 comes back in a JVM long, so read the low 32 bits as
|
|
168
|
+
# signed: the negative statuses have to stay negative on this side.
|
|
169
|
+
def i32(value)
|
|
170
|
+
value &= 0xFFFF_FFFF
|
|
171
|
+
value >= 0x8000_0000 ? value - 0x1_0000_0000 : value
|
|
172
|
+
end
|
|
173
|
+
|
|
159
174
|
def bool(value)
|
|
160
175
|
value ? 1 : 0
|
|
161
176
|
end
|
|
@@ -23,7 +23,7 @@ module RBS
|
|
|
23
23
|
# :bool, :location_range, :location_range_list, :attr_ivar_name, or
|
|
24
24
|
# [:enum, [value_or_nil, ...]].
|
|
25
25
|
module SerializationSchema
|
|
26
|
-
SYMBOL_TAG =
|
|
26
|
+
SYMBOL_TAG = 79
|
|
27
27
|
|
|
28
28
|
SCHEMA = [
|
|
29
29
|
nil, # tag 0 is reserved for NULL
|
|
@@ -91,7 +91,8 @@ module RBS
|
|
|
91
91
|
[:node, "RBS::Types::Block", true, nil, [[:type, :node], [:required, :bool], [:self_type, :node]], false],
|
|
92
92
|
[:node, "RBS::Types::ClassInstance", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
|
|
93
93
|
[:node, "RBS::Types::ClassSingleton", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
|
|
94
|
-
[:node, "RBS::Types::Function", false, nil, [[:required_positionals, :node_list], [:optional_positionals, :node_list], [:rest_positionals, :node], [:trailing_positionals, :node_list], [:required_keywords, :hash], [:optional_keywords, :hash], [:rest_keywords, :node], [:return_type, :node]], false],
|
|
94
|
+
[:node, "RBS::Types::Function", false, nil, [[:required_positionals, :node_list], [:optional_positionals, :node_list], [:rest_positionals, :node], [:trailing_positionals, :node_list], [:required_keywords, :hash], [:optional_keywords, :hash], [:rest_keywords, :node], [:forwarding, :node], [:return_type, :node]], false],
|
|
95
|
+
[:node, "RBS::Types::Function::ForwardingParam", true, nil, nil, false],
|
|
95
96
|
[:node, "RBS::Types::Function::Param", true, [[:name, false]], [[:type, :node], [:name, :node]], false],
|
|
96
97
|
[:node, "RBS::Types::Interface", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
|
|
97
98
|
[:node, "RBS::Types::Intersection", true, nil, [[:types, :node_list]], false],
|
data/schema/function.json
CHANGED
|
@@ -78,10 +78,21 @@
|
|
|
78
78
|
}
|
|
79
79
|
]
|
|
80
80
|
},
|
|
81
|
+
"forwarding": {
|
|
82
|
+
"title": "Forwarding parameter",
|
|
83
|
+
"oneOf": [
|
|
84
|
+
{
|
|
85
|
+
"type": "object"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"type": "null"
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
},
|
|
81
92
|
"return_type": {
|
|
82
93
|
"title": "Return type of a function",
|
|
83
94
|
"$ref": "types.json"
|
|
84
95
|
}
|
|
85
96
|
},
|
|
86
|
-
"required": ["required_positionals", "optional_positionals", "rest_positionals", "trailing_positionals", "required_keywords", "optional_keywords", "rest_keywords", "return_type"]
|
|
97
|
+
"required": ["required_positionals", "optional_positionals", "rest_positionals", "trailing_positionals", "required_keywords", "optional_keywords", "rest_keywords", "forwarding", "return_type"]
|
|
87
98
|
}
|
|
@@ -45,6 +45,12 @@ module RBS
|
|
|
45
45
|
# * Raises `GenericParameterMismatchError` if incompatible declaration is detected.
|
|
46
46
|
#
|
|
47
47
|
def validate_type_params: () -> void
|
|
48
|
+
|
|
49
|
+
# Returns a substitution that renames the type parameters of the declaration to the entry's type parameters (`#type_params`)
|
|
50
|
+
#
|
|
51
|
+
# Returns `nil` if the declaration uses the same type parameter names as `#type_params`.
|
|
52
|
+
#
|
|
53
|
+
def align_params: (declaration | ModuleEntry::declaration) -> Substitution?
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
56
|
end
|
|
@@ -44,7 +44,22 @@ module RBS
|
|
|
44
44
|
#
|
|
45
45
|
def validate_type_params: () -> void
|
|
46
46
|
|
|
47
|
+
# Returns the self types of the declarations
|
|
48
|
+
#
|
|
49
|
+
# The type variables in the self types are aligned to `#type_params`,
|
|
50
|
+
# so that the self types from declarations with different type parameter
|
|
51
|
+
# names can be compared and used with `#type_params`.
|
|
52
|
+
#
|
|
53
|
+
# Note that the returned objects may be different from the ones in the
|
|
54
|
+
# declarations, but `#location` points to the original declaration.
|
|
55
|
+
#
|
|
47
56
|
def self_types: () -> Array[AST::Declarations::Module::Self]
|
|
57
|
+
|
|
58
|
+
# Returns a substitution that renames the type parameters of the declaration to the entry's type parameters (`#type_params`)
|
|
59
|
+
#
|
|
60
|
+
# Returns `nil` if the declaration uses the same type parameter names as `#type_params`.
|
|
61
|
+
#
|
|
62
|
+
def align_params: (declaration | ClassEntry::declaration) -> Substitution?
|
|
48
63
|
end
|
|
49
64
|
end
|
|
50
65
|
end
|
data/sig/parser.rbs
CHANGED
|
@@ -136,9 +136,9 @@ module RBS
|
|
|
136
136
|
|
|
137
137
|
def self._parse_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof, bool void_allowed, bool self_allowed, bool classish_allowed) -> Types::t?
|
|
138
138
|
|
|
139
|
-
def self._parse_method_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof) -> MethodType?
|
|
139
|
+
def self._parse_method_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof, bool enable_forwarding_params) -> MethodType?
|
|
140
140
|
|
|
141
|
-
def self._parse_signature: (Buffer, Integer start_pos, Integer end_pos) -> [Array[AST::Directives::t], Array[AST::Declarations::t]]
|
|
141
|
+
def self._parse_signature: (Buffer, Integer start_pos, Integer end_pos, bool enable_forwarding_params) -> [Array[AST::Directives::t], Array[AST::Declarations::t]]
|
|
142
142
|
|
|
143
143
|
# Parse and serialize the result to the binary format consumed by
|
|
144
144
|
# RBS::WASM::Deserializer (see ext/rbs_extension/main.c and
|
|
@@ -146,9 +146,9 @@ module RBS
|
|
|
146
146
|
# round-trip can be exercised on CRuby.
|
|
147
147
|
def self._parse_type_to_bytes: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof, bool void_allowed, bool self_allowed, bool classish_allowed) -> String?
|
|
148
148
|
|
|
149
|
-
def self._parse_method_type_to_bytes: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof) -> String?
|
|
149
|
+
def self._parse_method_type_to_bytes: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof, bool enable_forwarding_params) -> String?
|
|
150
150
|
|
|
151
|
-
def self._parse_signature_to_bytes: (Buffer, Integer start_pos, Integer end_pos) -> String
|
|
151
|
+
def self._parse_signature_to_bytes: (Buffer, Integer start_pos, Integer end_pos, bool enable_forwarding_params) -> String
|
|
152
152
|
|
|
153
153
|
def self._parse_type_params: (Buffer, Integer start_pos, Integer end_pos, bool module_type_params) -> Array[AST::TypeParam]
|
|
154
154
|
|
data/sig/types.rbs
CHANGED
|
@@ -385,6 +385,12 @@ module RBS
|
|
|
385
385
|
| -> Enumerator[t, Param]
|
|
386
386
|
end
|
|
387
387
|
|
|
388
|
+
class ForwardingParam
|
|
389
|
+
attr_reader location: Location?
|
|
390
|
+
|
|
391
|
+
def initialize: (location: Location) -> void
|
|
392
|
+
end
|
|
393
|
+
|
|
388
394
|
attr_reader required_positionals: Array[Param]
|
|
389
395
|
attr_reader optional_positionals: Array[Param]
|
|
390
396
|
attr_reader rest_positionals: Param?
|
|
@@ -392,6 +398,7 @@ module RBS
|
|
|
392
398
|
attr_reader required_keywords: Hash[Symbol, Param]
|
|
393
399
|
attr_reader optional_keywords: Hash[Symbol, Param]
|
|
394
400
|
attr_reader rest_keywords: Param?
|
|
401
|
+
attr_reader forwarding: ForwardingParam?
|
|
395
402
|
attr_reader return_type: t
|
|
396
403
|
|
|
397
404
|
def initialize: (required_positionals: Array[Param],
|
|
@@ -401,7 +408,8 @@ module RBS
|
|
|
401
408
|
required_keywords: Hash[Symbol, Param],
|
|
402
409
|
optional_keywords: Hash[Symbol, Param],
|
|
403
410
|
rest_keywords: Param?,
|
|
404
|
-
return_type: t
|
|
411
|
+
return_type: t,
|
|
412
|
+
?forwarding: ForwardingParam?) -> void
|
|
405
413
|
|
|
406
414
|
def free_variables: (?Set[Symbol]) -> Set[Symbol]
|
|
407
415
|
|
|
@@ -431,9 +439,11 @@ module RBS
|
|
|
431
439
|
?required_keywords: Hash[Symbol, Param],
|
|
432
440
|
?optional_keywords: Hash[Symbol, Param],
|
|
433
441
|
?rest_keywords: Param?,
|
|
442
|
+
?forwarding: ForwardingParam?,
|
|
434
443
|
?return_type: t) -> Function
|
|
435
444
|
|
|
436
445
|
def empty?: () -> bool
|
|
446
|
+
def forwarding?: () -> bool
|
|
437
447
|
|
|
438
448
|
def param_to_s: () -> String
|
|
439
449
|
def return_to_s: () -> String
|
data/src/ast.c
CHANGED
|
@@ -143,6 +143,8 @@ const char *RBS_NONNULL rbs_node_type_name(rbs_node_t *RBS_NONNULL node) {
|
|
|
143
143
|
return "RBS::Types::ClassSingleton";
|
|
144
144
|
case RBS_TYPES_FUNCTION:
|
|
145
145
|
return "RBS::Types::Function";
|
|
146
|
+
case RBS_TYPES_FUNCTION_FORWARDING_PARAM:
|
|
147
|
+
return "RBS::Types::Function::ForwardingParam";
|
|
146
148
|
case RBS_TYPES_FUNCTION_PARAM:
|
|
147
149
|
return "RBS::Types::Function::Param";
|
|
148
150
|
case RBS_TYPES_INTERFACE:
|
|
@@ -1430,7 +1432,7 @@ rbs_types_class_singleton_t *RBS_NONNULL rbs_types_class_singleton_new(rbs_alloc
|
|
|
1430
1432
|
return instance;
|
|
1431
1433
|
}
|
|
1432
1434
|
#line 140 "templates/src/ast.c.erb"
|
|
1433
|
-
rbs_types_function_t *RBS_NONNULL rbs_types_function_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_node_list_t *RBS_NONNULL required_positionals, rbs_node_list_t *RBS_NONNULL optional_positionals, rbs_node_t *RBS_NULLABLE rest_positionals, rbs_node_list_t *RBS_NONNULL trailing_positionals, rbs_hash_t *RBS_NONNULL required_keywords, rbs_hash_t *RBS_NONNULL optional_keywords, rbs_node_t *RBS_NULLABLE rest_keywords, rbs_node_t *RBS_NONNULL return_type) {
|
|
1435
|
+
rbs_types_function_t *RBS_NONNULL rbs_types_function_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_node_list_t *RBS_NONNULL required_positionals, rbs_node_list_t *RBS_NONNULL optional_positionals, rbs_node_t *RBS_NULLABLE rest_positionals, rbs_node_list_t *RBS_NONNULL trailing_positionals, rbs_hash_t *RBS_NONNULL required_keywords, rbs_hash_t *RBS_NONNULL optional_keywords, rbs_node_t *RBS_NULLABLE rest_keywords, rbs_node_t *RBS_NULLABLE forwarding, rbs_node_t *RBS_NONNULL return_type) {
|
|
1434
1436
|
rbs_types_function_t *instance = rbs_allocator_alloc(allocator, rbs_types_function_t);
|
|
1435
1437
|
|
|
1436
1438
|
*instance = (rbs_types_function_t) {
|
|
@@ -1445,12 +1447,26 @@ rbs_types_function_t *RBS_NONNULL rbs_types_function_new(rbs_allocator_t *RBS_NO
|
|
|
1445
1447
|
.required_keywords = required_keywords,
|
|
1446
1448
|
.optional_keywords = optional_keywords,
|
|
1447
1449
|
.rest_keywords = rest_keywords,
|
|
1450
|
+
.forwarding = forwarding,
|
|
1448
1451
|
.return_type = return_type,
|
|
1449
1452
|
};
|
|
1450
1453
|
|
|
1451
1454
|
return instance;
|
|
1452
1455
|
}
|
|
1453
1456
|
#line 140 "templates/src/ast.c.erb"
|
|
1457
|
+
rbs_types_function_forwarding_param_t *RBS_NONNULL rbs_types_function_forwarding_param_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location) {
|
|
1458
|
+
rbs_types_function_forwarding_param_t *instance = rbs_allocator_alloc(allocator, rbs_types_function_forwarding_param_t);
|
|
1459
|
+
|
|
1460
|
+
*instance = (rbs_types_function_forwarding_param_t) {
|
|
1461
|
+
.base = (rbs_node_t) {
|
|
1462
|
+
.type = RBS_TYPES_FUNCTION_FORWARDING_PARAM,
|
|
1463
|
+
.location = location,
|
|
1464
|
+
},
|
|
1465
|
+
};
|
|
1466
|
+
|
|
1467
|
+
return instance;
|
|
1468
|
+
}
|
|
1469
|
+
#line 140 "templates/src/ast.c.erb"
|
|
1454
1470
|
rbs_types_function_param_t *RBS_NONNULL rbs_types_function_param_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_node_t *RBS_NONNULL type, rbs_ast_symbol_t *RBS_NULLABLE name) {
|
|
1455
1471
|
rbs_types_function_param_t *instance = rbs_allocator_alloc(allocator, rbs_types_function_param_t);
|
|
1456
1472
|
|