rbs 0.2.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 +7 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +12 -0
- data/.rubocop.yml +15 -0
- data/BSDL +22 -0
- data/CHANGELOG.md +9 -0
- data/COPYING +56 -0
- data/Gemfile +6 -0
- data/README.md +93 -0
- data/Rakefile +142 -0
- data/bin/annotate-with-rdoc +157 -0
- data/bin/console +14 -0
- data/bin/query-rdoc +103 -0
- data/bin/setup +10 -0
- data/bin/sort +89 -0
- data/bin/test_runner.rb +16 -0
- data/docs/CONTRIBUTING.md +97 -0
- data/docs/sigs.md +148 -0
- data/docs/stdlib.md +152 -0
- data/docs/syntax.md +528 -0
- data/exe/rbs +7 -0
- data/lib/rbs.rb +64 -0
- data/lib/rbs/ast/annotation.rb +27 -0
- data/lib/rbs/ast/comment.rb +27 -0
- data/lib/rbs/ast/declarations.rb +395 -0
- data/lib/rbs/ast/members.rb +362 -0
- data/lib/rbs/buffer.rb +50 -0
- data/lib/rbs/builtin_names.rb +55 -0
- data/lib/rbs/cli.rb +558 -0
- data/lib/rbs/constant.rb +26 -0
- data/lib/rbs/constant_table.rb +150 -0
- data/lib/rbs/definition.rb +170 -0
- data/lib/rbs/definition_builder.rb +919 -0
- data/lib/rbs/environment.rb +281 -0
- data/lib/rbs/environment_loader.rb +136 -0
- data/lib/rbs/environment_walker.rb +124 -0
- data/lib/rbs/errors.rb +187 -0
- data/lib/rbs/location.rb +102 -0
- data/lib/rbs/method_type.rb +123 -0
- data/lib/rbs/namespace.rb +91 -0
- data/lib/rbs/parser.y +1344 -0
- data/lib/rbs/prototype/rb.rb +553 -0
- data/lib/rbs/prototype/rbi.rb +587 -0
- data/lib/rbs/prototype/runtime.rb +381 -0
- data/lib/rbs/substitution.rb +46 -0
- data/lib/rbs/test.rb +26 -0
- data/lib/rbs/test/errors.rb +61 -0
- data/lib/rbs/test/hook.rb +294 -0
- data/lib/rbs/test/setup.rb +58 -0
- data/lib/rbs/test/spy.rb +325 -0
- data/lib/rbs/test/test_helper.rb +183 -0
- data/lib/rbs/test/type_check.rb +254 -0
- data/lib/rbs/type_name.rb +70 -0
- data/lib/rbs/types.rb +936 -0
- data/lib/rbs/variance_calculator.rb +138 -0
- data/lib/rbs/vendorer.rb +47 -0
- data/lib/rbs/version.rb +3 -0
- data/lib/rbs/writer.rb +269 -0
- data/lib/ruby/signature.rb +7 -0
- data/rbs.gemspec +46 -0
- data/stdlib/abbrev/abbrev.rbs +60 -0
- data/stdlib/base64/base64.rbs +71 -0
- data/stdlib/benchmark/benchmark.rbs +372 -0
- data/stdlib/builtin/array.rbs +1997 -0
- data/stdlib/builtin/basic_object.rbs +280 -0
- data/stdlib/builtin/binding.rbs +177 -0
- data/stdlib/builtin/builtin.rbs +45 -0
- data/stdlib/builtin/class.rbs +145 -0
- data/stdlib/builtin/comparable.rbs +116 -0
- data/stdlib/builtin/complex.rbs +400 -0
- data/stdlib/builtin/constants.rbs +37 -0
- data/stdlib/builtin/data.rbs +5 -0
- data/stdlib/builtin/deprecated.rbs +2 -0
- data/stdlib/builtin/dir.rbs +413 -0
- data/stdlib/builtin/encoding.rbs +607 -0
- data/stdlib/builtin/enumerable.rbs +404 -0
- data/stdlib/builtin/enumerator.rbs +260 -0
- data/stdlib/builtin/errno.rbs +781 -0
- data/stdlib/builtin/errors.rbs +582 -0
- data/stdlib/builtin/exception.rbs +194 -0
- data/stdlib/builtin/false_class.rbs +40 -0
- data/stdlib/builtin/fiber.rbs +68 -0
- data/stdlib/builtin/fiber_error.rbs +12 -0
- data/stdlib/builtin/file.rbs +1076 -0
- data/stdlib/builtin/file_test.rbs +59 -0
- data/stdlib/builtin/float.rbs +696 -0
- data/stdlib/builtin/gc.rbs +243 -0
- data/stdlib/builtin/hash.rbs +1029 -0
- data/stdlib/builtin/integer.rbs +707 -0
- data/stdlib/builtin/io.rbs +683 -0
- data/stdlib/builtin/kernel.rbs +576 -0
- data/stdlib/builtin/marshal.rbs +161 -0
- data/stdlib/builtin/match_data.rbs +271 -0
- data/stdlib/builtin/math.rbs +369 -0
- data/stdlib/builtin/method.rbs +185 -0
- data/stdlib/builtin/module.rbs +1104 -0
- data/stdlib/builtin/nil_class.rbs +82 -0
- data/stdlib/builtin/numeric.rbs +409 -0
- data/stdlib/builtin/object.rbs +824 -0
- data/stdlib/builtin/proc.rbs +429 -0
- data/stdlib/builtin/process.rbs +1227 -0
- data/stdlib/builtin/random.rbs +267 -0
- data/stdlib/builtin/range.rbs +226 -0
- data/stdlib/builtin/rational.rbs +424 -0
- data/stdlib/builtin/rb_config.rbs +57 -0
- data/stdlib/builtin/regexp.rbs +1083 -0
- data/stdlib/builtin/ruby_vm.rbs +14 -0
- data/stdlib/builtin/signal.rbs +55 -0
- data/stdlib/builtin/string.rbs +1901 -0
- data/stdlib/builtin/string_io.rbs +284 -0
- data/stdlib/builtin/struct.rbs +40 -0
- data/stdlib/builtin/symbol.rbs +228 -0
- data/stdlib/builtin/thread.rbs +1108 -0
- data/stdlib/builtin/thread_group.rbs +23 -0
- data/stdlib/builtin/time.rbs +1047 -0
- data/stdlib/builtin/trace_point.rbs +290 -0
- data/stdlib/builtin/true_class.rbs +46 -0
- data/stdlib/builtin/unbound_method.rbs +153 -0
- data/stdlib/builtin/warning.rbs +17 -0
- data/stdlib/coverage/coverage.rbs +62 -0
- data/stdlib/csv/csv.rbs +773 -0
- data/stdlib/erb/erb.rbs +392 -0
- data/stdlib/find/find.rbs +40 -0
- data/stdlib/ipaddr/ipaddr.rbs +247 -0
- data/stdlib/json/json.rbs +335 -0
- data/stdlib/pathname/pathname.rbs +1093 -0
- data/stdlib/prime/integer-extension.rbs +23 -0
- data/stdlib/prime/prime.rbs +188 -0
- data/stdlib/securerandom/securerandom.rbs +9 -0
- data/stdlib/set/set.rbs +301 -0
- data/stdlib/tmpdir/tmpdir.rbs +53 -0
- metadata +292 -0
data/lib/rbs/parser.y
ADDED
|
@@ -0,0 +1,1344 @@
|
|
|
1
|
+
class RBS::Parser
|
|
2
|
+
token tUIDENT tLIDENT tNAMESPACE tINTERFACEIDENT tLKEYWORD tUKEYWORD tGLOBALIDENT
|
|
3
|
+
tIVAR tCLASSVAR
|
|
4
|
+
tANNOTATION
|
|
5
|
+
tSTRING tSYMBOL tINTEGER tWRITE_ATTR
|
|
6
|
+
kLPAREN kRPAREN kLBRACKET kRBRACKET kLBRACE kRBRACE
|
|
7
|
+
kVOID kNIL kTRUE kFALSE kANY kUNTYPED kTOP kBOT kSELF kSELFQ kINSTANCE kCLASS kBOOL kSINGLETON kTYPE kDEF kMODULE kSUPER
|
|
8
|
+
kPRIVATE kPUBLIC kALIAS
|
|
9
|
+
kCOLON kCOLON2 kCOMMA kBAR kAMP kHAT kARROW kQUESTION kEXCLAMATION kSTAR kSTAR2 kFATARROW kEQ kDOT kLT
|
|
10
|
+
kINTERFACE kEND kINCLUDE kEXTEND kATTRREADER kATTRWRITER kATTRACCESSOR tOPERATOR tQUOTEDMETHOD tQUOTEDIDENT
|
|
11
|
+
kPREPEND kEXTENSION kINCOMPATIBLE
|
|
12
|
+
type_TYPE type_SIGNATURE type_METHODTYPE tEOF
|
|
13
|
+
kOUT kIN kUNCHECKED
|
|
14
|
+
|
|
15
|
+
prechigh
|
|
16
|
+
nonassoc kQUESTION
|
|
17
|
+
left kAMP
|
|
18
|
+
left kBAR
|
|
19
|
+
nonassoc kARROW
|
|
20
|
+
preclow
|
|
21
|
+
|
|
22
|
+
expect 2
|
|
23
|
+
|
|
24
|
+
rule
|
|
25
|
+
|
|
26
|
+
target:
|
|
27
|
+
type_TYPE type eof {
|
|
28
|
+
result = val[1]
|
|
29
|
+
}
|
|
30
|
+
| type_SIGNATURE signatures eof {
|
|
31
|
+
result = val[1]
|
|
32
|
+
}
|
|
33
|
+
| type_METHODTYPE method_type eof {
|
|
34
|
+
result = val[1]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
eof: | tEOF
|
|
38
|
+
|
|
39
|
+
signatures:
|
|
40
|
+
{ result = [] }
|
|
41
|
+
| signatures signature {
|
|
42
|
+
result = val[0].push(val[1])
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
signature:
|
|
46
|
+
type_decl
|
|
47
|
+
| const_decl
|
|
48
|
+
| global_decl
|
|
49
|
+
| interface_decl
|
|
50
|
+
| module_decl
|
|
51
|
+
| class_decl
|
|
52
|
+
| extension_decl
|
|
53
|
+
|
|
54
|
+
start_new_scope: { start_new_variables_scope }
|
|
55
|
+
start_merged_scope: { start_merged_variables_scope }
|
|
56
|
+
|
|
57
|
+
annotations:
|
|
58
|
+
{ result = [] }
|
|
59
|
+
| tANNOTATION annotations {
|
|
60
|
+
result = val[1].unshift(Annotation.new(string: val[0].value, location: val[0].location))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
extension_decl:
|
|
64
|
+
annotations kEXTENSION start_new_scope class_name type_params kLPAREN extension_name kRPAREN class_members kEND {
|
|
65
|
+
reset_variable_scope
|
|
66
|
+
|
|
67
|
+
location = val[1].location + val[9].location
|
|
68
|
+
result = Declarations::Extension.new(
|
|
69
|
+
name: val[3].value,
|
|
70
|
+
type_params: val[4]&.value || [],
|
|
71
|
+
extension_name: val[6].value.to_sym,
|
|
72
|
+
members: val[8],
|
|
73
|
+
annotations: val[0],
|
|
74
|
+
location: location,
|
|
75
|
+
comment: leading_comment(val[0].first&.location || location)
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
extension_name: tUIDENT | tLIDENT
|
|
80
|
+
|
|
81
|
+
class_decl:
|
|
82
|
+
annotations kCLASS start_new_scope class_name module_type_params super_class class_members kEND {
|
|
83
|
+
reset_variable_scope
|
|
84
|
+
|
|
85
|
+
location = val[1].location + val[7].location
|
|
86
|
+
result = Declarations::Class.new(
|
|
87
|
+
name: val[3].value,
|
|
88
|
+
type_params: val[4]&.value || Declarations::ModuleTypeParams.empty,
|
|
89
|
+
super_class: val[5],
|
|
90
|
+
members: val[6],
|
|
91
|
+
annotations: val[0],
|
|
92
|
+
location: location,
|
|
93
|
+
comment: leading_comment(val[0].first&.location || location)
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
super_class:
|
|
98
|
+
{ result = nil }
|
|
99
|
+
| kLT class_name {
|
|
100
|
+
result = Declarations::Class::Super.new(name: val[1].value,
|
|
101
|
+
args: [])
|
|
102
|
+
}
|
|
103
|
+
| kLT class_name kLBRACKET type_list kRBRACKET {
|
|
104
|
+
result = Declarations::Class::Super.new(name: val[1].value,
|
|
105
|
+
args: val[3])
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module_decl:
|
|
109
|
+
annotations kMODULE start_new_scope class_name module_type_params module_self_type class_members kEND {
|
|
110
|
+
reset_variable_scope
|
|
111
|
+
|
|
112
|
+
location = val[1].location + val[7].location
|
|
113
|
+
result = Declarations::Module.new(
|
|
114
|
+
name: val[3].value,
|
|
115
|
+
type_params: val[4]&.value || Declarations::ModuleTypeParams.empty,
|
|
116
|
+
self_type: val[5],
|
|
117
|
+
members: val[6],
|
|
118
|
+
annotations: val[0],
|
|
119
|
+
location: location,
|
|
120
|
+
comment: leading_comment(val[0].first&.location || location)
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
| annotations kMODULE start_new_scope tUKEYWORD type class_members kEND {
|
|
124
|
+
reset_variable_scope
|
|
125
|
+
|
|
126
|
+
location = val[1].location + val[6].location
|
|
127
|
+
result = Declarations::Module.new(
|
|
128
|
+
name: val[3].value,
|
|
129
|
+
type_params: Declarations::ModuleTypeParams.empty,
|
|
130
|
+
self_type: val[4],
|
|
131
|
+
members: val[5],
|
|
132
|
+
annotations: val[0],
|
|
133
|
+
location: location,
|
|
134
|
+
comment: leading_comment(val[0].first&.location || location)
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module_self_type:
|
|
139
|
+
{ result = nil }
|
|
140
|
+
| kCOLON type {
|
|
141
|
+
result = val[1]
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
class_members:
|
|
145
|
+
{ result = [] }
|
|
146
|
+
| class_members class_member {
|
|
147
|
+
result = val[0].push(val[1])
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
class_member:
|
|
151
|
+
method_member
|
|
152
|
+
| include_member
|
|
153
|
+
| extend_member
|
|
154
|
+
| prepend_member
|
|
155
|
+
| var_type_member
|
|
156
|
+
| attribute_member
|
|
157
|
+
| kPUBLIC {
|
|
158
|
+
result = Members::Public.new(location: val[0].location)
|
|
159
|
+
}
|
|
160
|
+
| kPRIVATE {
|
|
161
|
+
result = Members::Private.new(location: val[0].location)
|
|
162
|
+
}
|
|
163
|
+
| alias_member
|
|
164
|
+
|
|
165
|
+
attribute_member:
|
|
166
|
+
annotations kATTRREADER keyword type {
|
|
167
|
+
location = val[1].location + val[3].location
|
|
168
|
+
result = Members::AttrReader.new(name: val[2].value,
|
|
169
|
+
ivar_name: nil,
|
|
170
|
+
type: val[3],
|
|
171
|
+
annotations: val[0],
|
|
172
|
+
location: location,
|
|
173
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
174
|
+
}
|
|
175
|
+
| annotations kATTRREADER method_name attr_var_opt kCOLON type {
|
|
176
|
+
location = val[1].location + val[5].location
|
|
177
|
+
result = Members::AttrReader.new(name: val[2].value.to_sym,
|
|
178
|
+
ivar_name: val[3],
|
|
179
|
+
type: val[5],
|
|
180
|
+
annotations: val[0],
|
|
181
|
+
location: location,
|
|
182
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
183
|
+
}
|
|
184
|
+
| annotations kATTRWRITER keyword type {
|
|
185
|
+
location = val[1].location + val[3].location
|
|
186
|
+
result = Members::AttrWriter.new(name: val[2].value,
|
|
187
|
+
ivar_name: nil,
|
|
188
|
+
type: val[3],
|
|
189
|
+
annotations: val[0],
|
|
190
|
+
location: location,
|
|
191
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
192
|
+
}
|
|
193
|
+
| annotations kATTRWRITER method_name attr_var_opt kCOLON type {
|
|
194
|
+
location = val[1].location + val[5].location
|
|
195
|
+
result = Members::AttrWriter.new(name: val[2].value.to_sym,
|
|
196
|
+
ivar_name: val[3],
|
|
197
|
+
type: val[5],
|
|
198
|
+
annotations: val[0],
|
|
199
|
+
location: location,
|
|
200
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
201
|
+
}
|
|
202
|
+
| annotations kATTRACCESSOR keyword type {
|
|
203
|
+
location = val[1].location + val[3].location
|
|
204
|
+
result = Members::AttrAccessor.new(name: val[2].value,
|
|
205
|
+
ivar_name: nil,
|
|
206
|
+
type: val[3],
|
|
207
|
+
annotations: val[0],
|
|
208
|
+
location: location,
|
|
209
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
210
|
+
}
|
|
211
|
+
| annotations kATTRACCESSOR method_name attr_var_opt kCOLON type {
|
|
212
|
+
location = val[1].location + val[5].location
|
|
213
|
+
result = Members::AttrAccessor.new(name: val[2].value.to_sym,
|
|
214
|
+
ivar_name: val[3],
|
|
215
|
+
type: val[5],
|
|
216
|
+
annotations: val[0],
|
|
217
|
+
location: location,
|
|
218
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
attr_var_opt:
|
|
222
|
+
{ result = nil }
|
|
223
|
+
| kLPAREN kRPAREN { result = false }
|
|
224
|
+
| kLPAREN tIVAR kRPAREN { result = val[1].value }
|
|
225
|
+
|
|
226
|
+
var_type_member:
|
|
227
|
+
tIVAR kCOLON type {
|
|
228
|
+
location = val[0].location + val[2].location
|
|
229
|
+
result = Members::InstanceVariable.new(
|
|
230
|
+
name: val[0].value,
|
|
231
|
+
type: val[2],
|
|
232
|
+
location: location,
|
|
233
|
+
comment: leading_comment(location)
|
|
234
|
+
)
|
|
235
|
+
}
|
|
236
|
+
| tCLASSVAR kCOLON type {
|
|
237
|
+
type = val[2]
|
|
238
|
+
|
|
239
|
+
if type.is_a?(Types::Variable)
|
|
240
|
+
type = Types::ClassInstance.new(
|
|
241
|
+
name: TypeName.new(name: type.name, namespace: Namespace.empty),
|
|
242
|
+
args: [],
|
|
243
|
+
location: type.location
|
|
244
|
+
)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
location = val[0].location + val[2].location
|
|
248
|
+
result = Members::ClassVariable.new(
|
|
249
|
+
name: val[0].value,
|
|
250
|
+
type: type,
|
|
251
|
+
location: location,
|
|
252
|
+
comment: leading_comment(location)
|
|
253
|
+
)
|
|
254
|
+
}
|
|
255
|
+
| kSELF kDOT tIVAR kCOLON type {
|
|
256
|
+
type = val[4]
|
|
257
|
+
|
|
258
|
+
if type.is_a?(Types::Variable)
|
|
259
|
+
type = Types::ClassInstance.new(
|
|
260
|
+
name: TypeName.new(name: type.name, namespace: Namespace.empty),
|
|
261
|
+
args: [],
|
|
262
|
+
location: type.location
|
|
263
|
+
)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
location = val[0].location + val[4].location
|
|
267
|
+
result = Members::ClassInstanceVariable.new(
|
|
268
|
+
name: val[2].value,
|
|
269
|
+
type: type,
|
|
270
|
+
location: location,
|
|
271
|
+
comment: leading_comment(location)
|
|
272
|
+
)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
interface_decl:
|
|
276
|
+
annotations kINTERFACE start_new_scope interface_name module_type_params interface_members kEND {
|
|
277
|
+
reset_variable_scope
|
|
278
|
+
|
|
279
|
+
location = val[1].location + val[6].location
|
|
280
|
+
result = Declarations::Interface.new(
|
|
281
|
+
name: val[3].value,
|
|
282
|
+
type_params: val[4]&.value || Declarations::ModuleTypeParams.empty,
|
|
283
|
+
members: val[5],
|
|
284
|
+
annotations: val[0],
|
|
285
|
+
location: location,
|
|
286
|
+
comment: leading_comment(val[0].first&.location || location)
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
interface_members:
|
|
291
|
+
{ result = [] }
|
|
292
|
+
| interface_members interface_member {
|
|
293
|
+
result = val[0].push(val[1])
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
interface_member:
|
|
297
|
+
method_member {
|
|
298
|
+
unless val[0].kind == :instance
|
|
299
|
+
raise SemanticsError.new("Interface cannot have singleton method", subject: val[0], location: val[0].location)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
if val[0].types.last == :super
|
|
303
|
+
raise SemanticsError.new("Interface method cannot have `super` type", subject: val[0], location: val[0].location)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
result = val[0]
|
|
307
|
+
}
|
|
308
|
+
| include_member {
|
|
309
|
+
unless val[0].name.interface?
|
|
310
|
+
raise SemanticsError.new("Interface should include an interface", subject: val[0], location: val[0].location)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
result = val[0]
|
|
314
|
+
}
|
|
315
|
+
| alias_member
|
|
316
|
+
|
|
317
|
+
include_member:
|
|
318
|
+
annotations kINCLUDE qualified_name {
|
|
319
|
+
if val[2].value.alias?
|
|
320
|
+
raise SemanticsError.new("Should include module or interface", subject: val[2].value, location: val[2].location)
|
|
321
|
+
end
|
|
322
|
+
location = val[1].location + val[2].location
|
|
323
|
+
result = Members::Include.new(name: val[2].value,
|
|
324
|
+
args: [],
|
|
325
|
+
annotations: val[0],
|
|
326
|
+
location: location,
|
|
327
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
328
|
+
}
|
|
329
|
+
| annotations kINCLUDE qualified_name kLBRACKET type_list kRBRACKET {
|
|
330
|
+
if val[2].value.alias?
|
|
331
|
+
raise SemanticsError.new("Should include module or interface", subject: val[2].value, location: val[2].location)
|
|
332
|
+
end
|
|
333
|
+
location = val[1].location + val[5].location
|
|
334
|
+
result = Members::Include.new(name: val[2].value,
|
|
335
|
+
args: val[4],
|
|
336
|
+
annotations: val[0],
|
|
337
|
+
location: location,
|
|
338
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
extend_member:
|
|
342
|
+
annotations kEXTEND qualified_name {
|
|
343
|
+
if val[2].value.alias?
|
|
344
|
+
raise SemanticsError.new("Should extend module or interface", subject: val[2].value, location: val[2].location)
|
|
345
|
+
end
|
|
346
|
+
location = val[1].location + val[2].location
|
|
347
|
+
result = Members::Extend.new(name: val[2].value,
|
|
348
|
+
args: [],
|
|
349
|
+
annotations: val[0],
|
|
350
|
+
location: location,
|
|
351
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
352
|
+
}
|
|
353
|
+
| annotations kEXTEND qualified_name kLBRACKET type_list kRBRACKET {
|
|
354
|
+
if val[2].value.alias?
|
|
355
|
+
raise SemanticsError.new("Should extend module or interface", subject: val[2].value, location: val[2].location)
|
|
356
|
+
end
|
|
357
|
+
location = val[1].location + val[5].location
|
|
358
|
+
result = Members::Extend.new(name: val[2].value,
|
|
359
|
+
args: val[4],
|
|
360
|
+
annotations: val[0],
|
|
361
|
+
location: location,
|
|
362
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
prepend_member:
|
|
366
|
+
annotations kPREPEND qualified_name {
|
|
367
|
+
unless val[2].value.class?
|
|
368
|
+
raise SemanticsError.new("Should prepend module", subject: val[2].value, location: val[2].location)
|
|
369
|
+
end
|
|
370
|
+
location = val[1].location + val[2].location
|
|
371
|
+
result = Members::Prepend.new(name: val[2].value,
|
|
372
|
+
args: [],
|
|
373
|
+
annotations: val[0],
|
|
374
|
+
location: location,
|
|
375
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
376
|
+
}
|
|
377
|
+
| annotations kPREPEND qualified_name kLBRACKET type_list kRBRACKET {
|
|
378
|
+
unless val[2].value.class?
|
|
379
|
+
raise SemanticsError.new("Should prepend module", subject: val[2].value, location: val[2].location)
|
|
380
|
+
end
|
|
381
|
+
location = val[1].location + val[5].location
|
|
382
|
+
result = Members::Prepend.new(name: val[2].value,
|
|
383
|
+
args: val[4],
|
|
384
|
+
annotations: val[0],
|
|
385
|
+
location: location,
|
|
386
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
method_member:
|
|
390
|
+
annotations attributes kDEF method_kind def_name method_types {
|
|
391
|
+
location = val[2].location + val[5].last.location
|
|
392
|
+
types = val[5].map do |type|
|
|
393
|
+
case type
|
|
394
|
+
when LocatedValue
|
|
395
|
+
type.value
|
|
396
|
+
else
|
|
397
|
+
type
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
result = Members::MethodDefinition.new(
|
|
401
|
+
name: val[4].value,
|
|
402
|
+
kind: val[3],
|
|
403
|
+
types: types,
|
|
404
|
+
annotations: val[0],
|
|
405
|
+
location: location,
|
|
406
|
+
comment: leading_comment(val[0].first&.location || val[1].first&.location || val[2].location),
|
|
407
|
+
attributes: val[1].map(&:value)
|
|
408
|
+
)
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
attributes:
|
|
412
|
+
{ result = [] }
|
|
413
|
+
| attributes kINCOMPATIBLE {
|
|
414
|
+
result = val[0].push(val[1])
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
method_kind:
|
|
418
|
+
{ result = :instance }
|
|
419
|
+
| kSELF kDOT { result = :singleton }
|
|
420
|
+
| kSELFQ kDOT { result = :singleton_instance }
|
|
421
|
+
|
|
422
|
+
method_types:
|
|
423
|
+
method_type { result = [val[0]] }
|
|
424
|
+
| kSUPER { result = [LocatedValue.new(value: :super, location: val[0].location)] }
|
|
425
|
+
| method_type kBAR method_types {
|
|
426
|
+
result = val[2].unshift(val[0])
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
method_type:
|
|
430
|
+
start_merged_scope type_params params_opt block_opt kARROW simple_type {
|
|
431
|
+
location = (val[1] || val[2] || val[3] || val[4]).location + val[5].location
|
|
432
|
+
type_params = val[1]&.value || []
|
|
433
|
+
|
|
434
|
+
params = val[2]&.value || empty_params_result
|
|
435
|
+
|
|
436
|
+
type = Types::Function.new(
|
|
437
|
+
required_positionals: params[0],
|
|
438
|
+
optional_positionals: params[1],
|
|
439
|
+
rest_positionals: params[2],
|
|
440
|
+
trailing_positionals: params[3],
|
|
441
|
+
required_keywords: params[4],
|
|
442
|
+
optional_keywords: params[5],
|
|
443
|
+
rest_keywords: params[6],
|
|
444
|
+
return_type: val[5]
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
block = val[3]&.value
|
|
448
|
+
|
|
449
|
+
result = MethodType.new(type_params: type_params,
|
|
450
|
+
type: type,
|
|
451
|
+
block: block,
|
|
452
|
+
location: location)
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
params_opt:
|
|
456
|
+
{ result = nil }
|
|
457
|
+
| kLPAREN params kRPAREN {
|
|
458
|
+
result = LocatedValue.new(value: val[1], location: val[0].location + val[2].location)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
block_opt:
|
|
462
|
+
{ result = nil }
|
|
463
|
+
| kLBRACE function_type kRBRACE {
|
|
464
|
+
block = MethodType::Block.new(type: val[1].value, required: true)
|
|
465
|
+
result = LocatedValue.new(value: block, location: val[0].location + val[2].location)
|
|
466
|
+
}
|
|
467
|
+
| kQUESTION kLBRACE function_type kRBRACE {
|
|
468
|
+
block = MethodType::Block.new(type: val[2].value, required: false)
|
|
469
|
+
result = LocatedValue.new(value: block, location: val[0].location + val[3].location)
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
def_name:
|
|
473
|
+
keyword
|
|
474
|
+
| method_name kCOLON {
|
|
475
|
+
result = LocatedValue.new(value: val[0].value.to_sym,
|
|
476
|
+
location: val[0].location + val[1].location)
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
method_name:
|
|
480
|
+
tOPERATOR
|
|
481
|
+
| kAMP | kHAT | kSTAR | kLT | kEXCLAMATION | kSTAR2 | kBAR | kOUT | kIN
|
|
482
|
+
| method_name0
|
|
483
|
+
| method_name0 kQUESTION {
|
|
484
|
+
unless val[0].location.pred?(val[1].location)
|
|
485
|
+
raise SyntaxError.new(token_str: "kQUESTION", error_value: val[1])
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
result = LocatedValue.new(value: "#{val[0].value}?",
|
|
489
|
+
location: val[0].location + val[1].location)
|
|
490
|
+
}
|
|
491
|
+
| method_name0 kEXCLAMATION {
|
|
492
|
+
unless val[0].location.pred?(val[1].location)
|
|
493
|
+
raise SyntaxError.new(token_str: "kEXCLAMATION", error_value: val[1])
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
result = LocatedValue.new(value: "#{val[0].value}!",
|
|
497
|
+
location: val[0].location + val[1].location)
|
|
498
|
+
}
|
|
499
|
+
| tQUOTEDMETHOD
|
|
500
|
+
| tQUOTEDIDENT
|
|
501
|
+
| tWRITE_ATTR
|
|
502
|
+
|
|
503
|
+
method_name0: tUIDENT | tLIDENT | identifier_keywords
|
|
504
|
+
|
|
505
|
+
identifier_keywords:
|
|
506
|
+
kCLASS | kVOID | kNIL | kTRUE | kFALSE | kANY | kUNTYPED | kTOP | kBOT | kINSTANCE | kBOOL | kSINGLETON
|
|
507
|
+
| kTYPE | kMODULE | kPRIVATE | kPUBLIC | kEND | kINCLUDE | kEXTEND | kPREPEND
|
|
508
|
+
| kATTRREADER | kATTRACCESSOR | kATTRWRITER | kDEF | kEXTENSION | kSELF | kINCOMPATIBLE
|
|
509
|
+
| kUNCHECKED
|
|
510
|
+
|
|
511
|
+
module_type_params:
|
|
512
|
+
{ result = nil }
|
|
513
|
+
| kLBRACKET module_type_params0 kRBRACKET {
|
|
514
|
+
val[1].each {|p| insert_bound_variable(p.name) }
|
|
515
|
+
|
|
516
|
+
result = LocatedValue.new(value: val[1], location: val[0].location + val[2].location)
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
module_type_params0:
|
|
520
|
+
module_type_param {
|
|
521
|
+
result = Declarations::ModuleTypeParams.new()
|
|
522
|
+
result.add(val[0])
|
|
523
|
+
}
|
|
524
|
+
| module_type_params0 kCOMMA module_type_param {
|
|
525
|
+
result = val[0].add(val[2])
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
module_type_param:
|
|
529
|
+
type_param_check type_param_variance tUIDENT {
|
|
530
|
+
result = Declarations::ModuleTypeParams::TypeParam.new(name: val[2].value.to_sym,
|
|
531
|
+
variance: val[1],
|
|
532
|
+
skip_validation: val[0])
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
type_param_variance:
|
|
536
|
+
{ result = :invariant }
|
|
537
|
+
| kOUT { result = :covariant }
|
|
538
|
+
| kIN { result = :contravariant }
|
|
539
|
+
|
|
540
|
+
type_param_check:
|
|
541
|
+
{ result = false }
|
|
542
|
+
| kUNCHECKED { result = true }
|
|
543
|
+
|
|
544
|
+
type_params:
|
|
545
|
+
{ result = nil }
|
|
546
|
+
| kLBRACKET type_params0 kRBRACKET {
|
|
547
|
+
val[1].each {|var| insert_bound_variable(var) }
|
|
548
|
+
|
|
549
|
+
result = LocatedValue.new(value: val[1],
|
|
550
|
+
location: val[0].location + val[2].location)
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
type_params0:
|
|
554
|
+
tUIDENT {
|
|
555
|
+
result = [val[0].value.to_sym]
|
|
556
|
+
}
|
|
557
|
+
| type_params0 kCOMMA tUIDENT {
|
|
558
|
+
result = val[0].push(val[2].value.to_sym)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
alias_member:
|
|
562
|
+
annotations kALIAS method_name method_name {
|
|
563
|
+
location = val[1].location + val[3].location
|
|
564
|
+
result = Members::Alias.new(
|
|
565
|
+
new_name: val[2].value.to_sym,
|
|
566
|
+
old_name: val[3].value.to_sym,
|
|
567
|
+
kind: :instance,
|
|
568
|
+
annotations: val[0],
|
|
569
|
+
location: location,
|
|
570
|
+
comment: leading_comment(val[0].first&.location || location)
|
|
571
|
+
)
|
|
572
|
+
}
|
|
573
|
+
| annotations kALIAS kSELF kDOT method_name kSELF kDOT method_name {
|
|
574
|
+
location = val[1].location + val[7].location
|
|
575
|
+
result = Members::Alias.new(
|
|
576
|
+
new_name: val[4].value.to_sym,
|
|
577
|
+
old_name: val[7].value.to_sym,
|
|
578
|
+
kind: :singleton,
|
|
579
|
+
annotations: val[0],
|
|
580
|
+
location: location,
|
|
581
|
+
comment: leading_comment(val[0].first&.location || location)
|
|
582
|
+
)
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
type_decl:
|
|
586
|
+
annotations kTYPE qualified_name kEQ type {
|
|
587
|
+
location = val[1].location + val[4].location
|
|
588
|
+
result = Declarations::Alias.new(name: val[2].value,
|
|
589
|
+
type: val[4],
|
|
590
|
+
annotations: val[0],
|
|
591
|
+
location: location,
|
|
592
|
+
comment: leading_comment(val[0].first&.location || location))
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const_decl:
|
|
596
|
+
class_name kCOLON type {
|
|
597
|
+
location = val[0].location + val[2].location
|
|
598
|
+
result = Declarations::Constant.new(name: val[0].value,
|
|
599
|
+
type: val[2],
|
|
600
|
+
location: location,
|
|
601
|
+
comment: leading_comment(location))
|
|
602
|
+
}
|
|
603
|
+
| namespace tUKEYWORD type {
|
|
604
|
+
location = (val[0] || val[1]).location + val[2].location
|
|
605
|
+
name = TypeName.new(name: val[1].value, namespace: val[0]&.value || Namespace.empty)
|
|
606
|
+
result = Declarations::Constant.new(name: name,
|
|
607
|
+
type: val[2],
|
|
608
|
+
location: location,
|
|
609
|
+
comment: leading_comment(location))
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
global_decl:
|
|
613
|
+
tGLOBALIDENT kCOLON type {
|
|
614
|
+
location = val[0].location + val[2].location
|
|
615
|
+
result = Declarations::Global.new(name: val[0].value.to_sym,
|
|
616
|
+
type: val[2],
|
|
617
|
+
location: location,
|
|
618
|
+
comment: leading_comment(location))
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
type:
|
|
622
|
+
simple_type
|
|
623
|
+
| type kBAR type {
|
|
624
|
+
types = case l = val[0]
|
|
625
|
+
when Types::Union
|
|
626
|
+
l.types + [val[2]]
|
|
627
|
+
else
|
|
628
|
+
[l, val[2]]
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
result = Types::Union.new(types: types, location: val[0].location + val[2].location)
|
|
632
|
+
}
|
|
633
|
+
| type kAMP type {
|
|
634
|
+
types = case l = val[0]
|
|
635
|
+
when Types::Intersection
|
|
636
|
+
l.types + [val[2]]
|
|
637
|
+
else
|
|
638
|
+
[l, val[2]]
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
result = Types::Intersection.new(types: types,
|
|
642
|
+
location: val[0].location + val[2].location)
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
simple_type:
|
|
646
|
+
kVOID {
|
|
647
|
+
result = Types::Bases::Void.new(location: val[0].location)
|
|
648
|
+
}
|
|
649
|
+
| kANY {
|
|
650
|
+
RBS.logger.warn "`any` type is deprecated. Use `untyped` instead. (#{val[0].location.to_s})"
|
|
651
|
+
result = Types::Bases::Any.new(location: val[0].location)
|
|
652
|
+
}
|
|
653
|
+
| kUNTYPED {
|
|
654
|
+
result = Types::Bases::Any.new(location: val[0].location)
|
|
655
|
+
}
|
|
656
|
+
| kBOOL {
|
|
657
|
+
result = Types::Bases::Bool.new(location: val[0].location)
|
|
658
|
+
}
|
|
659
|
+
| kNIL {
|
|
660
|
+
result = Types::Bases::Nil.new(location: val[0].location)
|
|
661
|
+
}
|
|
662
|
+
| kTOP {
|
|
663
|
+
result = Types::Bases::Top.new(location: val[0].location)
|
|
664
|
+
}
|
|
665
|
+
| kBOT {
|
|
666
|
+
result = Types::Bases::Bottom.new(location: val[0].location)
|
|
667
|
+
}
|
|
668
|
+
| kSELF {
|
|
669
|
+
result = Types::Bases::Self.new(location: val[0].location)
|
|
670
|
+
}
|
|
671
|
+
| kSELFQ {
|
|
672
|
+
result = Types::Optional.new(type: Types::Bases::Self.new(location: val[0].location),
|
|
673
|
+
location: val[0].location)
|
|
674
|
+
}
|
|
675
|
+
| kINSTANCE {
|
|
676
|
+
result = Types::Bases::Instance.new(location: val[0].location)
|
|
677
|
+
}
|
|
678
|
+
| kCLASS {
|
|
679
|
+
result = Types::Bases::Class.new(location: val[0].location)
|
|
680
|
+
}
|
|
681
|
+
| kTRUE {
|
|
682
|
+
result = Types::Literal.new(literal: true, location: val[0].location)
|
|
683
|
+
}
|
|
684
|
+
| kFALSE {
|
|
685
|
+
result = Types::Literal.new(literal: false, location: val[0].location)
|
|
686
|
+
}
|
|
687
|
+
| tINTEGER {
|
|
688
|
+
result = Types::Literal.new(literal: val[0].value, location: val[0].location)
|
|
689
|
+
}
|
|
690
|
+
| tSTRING {
|
|
691
|
+
result = Types::Literal.new(literal: val[0].value, location: val[0].location)
|
|
692
|
+
}
|
|
693
|
+
| tSYMBOL {
|
|
694
|
+
result = Types::Literal.new(literal: val[0].value, location: val[0].location)
|
|
695
|
+
}
|
|
696
|
+
| qualified_name {
|
|
697
|
+
name = val[0].value
|
|
698
|
+
args = []
|
|
699
|
+
location = val[0].location
|
|
700
|
+
|
|
701
|
+
case
|
|
702
|
+
when name.class?
|
|
703
|
+
if is_bound_variable?(name.name)
|
|
704
|
+
result = Types::Variable.new(name: name.name, location: location)
|
|
705
|
+
else
|
|
706
|
+
result = Types::ClassInstance.new(name: name, args: args, location: location)
|
|
707
|
+
end
|
|
708
|
+
when name.alias?
|
|
709
|
+
result = Types::Alias.new(name: name, location: location)
|
|
710
|
+
when name.interface?
|
|
711
|
+
result = Types::Interface.new(name: name, args: args, location: location)
|
|
712
|
+
end
|
|
713
|
+
}
|
|
714
|
+
| qualified_name kLBRACKET type_list kRBRACKET {
|
|
715
|
+
name = val[0].value
|
|
716
|
+
args = val[2]
|
|
717
|
+
location = val[0].location + val[3].location
|
|
718
|
+
|
|
719
|
+
case
|
|
720
|
+
when name.class?
|
|
721
|
+
if is_bound_variable?(name.name)
|
|
722
|
+
raise SemanticsError.new("#{name.name} is type variable and cannot be applied", subject: name, location: location)
|
|
723
|
+
end
|
|
724
|
+
result = Types::ClassInstance.new(name: name, args: args, location: location)
|
|
725
|
+
when name.interface?
|
|
726
|
+
result = Types::Interface.new(name: name, args: args, location: location)
|
|
727
|
+
else
|
|
728
|
+
raise SyntaxError.new(token_str: "kLBRACKET", error_value: val[1])
|
|
729
|
+
end
|
|
730
|
+
}
|
|
731
|
+
| kLBRACKET kRBRACKET {
|
|
732
|
+
location = val[0].location + val[1].location
|
|
733
|
+
result = Types::Tuple.new(types: [], location: location)
|
|
734
|
+
}
|
|
735
|
+
| kLBRACKET type_list kRBRACKET {
|
|
736
|
+
location = val[0].location + val[2].location
|
|
737
|
+
types = val[1]
|
|
738
|
+
result = Types::Tuple.new(types: types, location: location)
|
|
739
|
+
}
|
|
740
|
+
| kLPAREN type kRPAREN {
|
|
741
|
+
type = val[1].dup
|
|
742
|
+
type.instance_eval do
|
|
743
|
+
@location = val[0].location + val[2].location
|
|
744
|
+
end
|
|
745
|
+
result = type
|
|
746
|
+
}
|
|
747
|
+
| kSINGLETON kLPAREN class_name kRPAREN {
|
|
748
|
+
result = Types::ClassSingleton.new(name: val[2].value,
|
|
749
|
+
location: val[0].location + val[3].location)
|
|
750
|
+
}
|
|
751
|
+
| kHAT function_type {
|
|
752
|
+
result = Types::Proc.new(type: val[1].value, location: val[0].location + val[1].location)
|
|
753
|
+
}
|
|
754
|
+
| simple_type kQUESTION {
|
|
755
|
+
result = Types::Optional.new(type: val[0], location: val[0].location + val[1].location)
|
|
756
|
+
}
|
|
757
|
+
| record_type
|
|
758
|
+
|
|
759
|
+
type_list:
|
|
760
|
+
type {
|
|
761
|
+
result = [val[0]]
|
|
762
|
+
}
|
|
763
|
+
| type_list kCOMMA type {
|
|
764
|
+
result = val[0] + [val[2]]
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
record_type:
|
|
768
|
+
kLBRACE record_fields kRBRACE {
|
|
769
|
+
result = Types::Record.new(
|
|
770
|
+
fields: val[1],
|
|
771
|
+
location: val[0].location + val[2].location
|
|
772
|
+
)
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
record_fields:
|
|
776
|
+
record_field {
|
|
777
|
+
result = val[0]
|
|
778
|
+
}
|
|
779
|
+
| record_field kCOMMA record_fields {
|
|
780
|
+
result = val[0].merge!(val[2])
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
record_field:
|
|
784
|
+
tSYMBOL kFATARROW type {
|
|
785
|
+
result = { val[0].value => val[2] }
|
|
786
|
+
}
|
|
787
|
+
| tSTRING kFATARROW type {
|
|
788
|
+
result = { val[0].value => val[2] }
|
|
789
|
+
}
|
|
790
|
+
| tINTEGER kFATARROW type {
|
|
791
|
+
result = { val[0].value => val[2] }
|
|
792
|
+
}
|
|
793
|
+
| keyword type {
|
|
794
|
+
result = { val[0].value => val[1] }
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
keyword_name:
|
|
798
|
+
keyword
|
|
799
|
+
| identifier_keywords kCOLON {
|
|
800
|
+
result = val[0]
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
keyword: tLKEYWORD | tUKEYWORD
|
|
804
|
+
|
|
805
|
+
function_type:
|
|
806
|
+
kLPAREN params kRPAREN kARROW simple_type {
|
|
807
|
+
location = val[0].location + val[4].location
|
|
808
|
+
type = Types::Function.new(
|
|
809
|
+
required_positionals: val[1][0],
|
|
810
|
+
optional_positionals: val[1][1],
|
|
811
|
+
rest_positionals: val[1][2],
|
|
812
|
+
trailing_positionals: val[1][3],
|
|
813
|
+
required_keywords: val[1][4],
|
|
814
|
+
optional_keywords: val[1][5],
|
|
815
|
+
rest_keywords: val[1][6],
|
|
816
|
+
return_type: val[4],
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
result = LocatedValue.new(value: type, location: location)
|
|
820
|
+
}
|
|
821
|
+
| kARROW simple_type {
|
|
822
|
+
location = val[0].location + val[1].location
|
|
823
|
+
type = Types::Function.new(
|
|
824
|
+
required_positionals: [],
|
|
825
|
+
optional_positionals: [],
|
|
826
|
+
rest_positionals: nil,
|
|
827
|
+
trailing_positionals: [],
|
|
828
|
+
required_keywords: {},
|
|
829
|
+
optional_keywords: {},
|
|
830
|
+
rest_keywords: nil,
|
|
831
|
+
return_type: val[2]
|
|
832
|
+
)
|
|
833
|
+
|
|
834
|
+
result = LocatedValue.new(value: type, location: location)
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
params:
|
|
838
|
+
required_positional kCOMMA params {
|
|
839
|
+
result = val[2]
|
|
840
|
+
result[0].unshift(val[0])
|
|
841
|
+
}
|
|
842
|
+
| required_positional {
|
|
843
|
+
result = empty_params_result
|
|
844
|
+
result[0].unshift(val[0])
|
|
845
|
+
}
|
|
846
|
+
| optional_positional_params
|
|
847
|
+
|
|
848
|
+
optional_positional_params:
|
|
849
|
+
optional_positional kCOMMA optional_positional_params {
|
|
850
|
+
result = val[2]
|
|
851
|
+
result[1].unshift(val[0])
|
|
852
|
+
}
|
|
853
|
+
| optional_positional {
|
|
854
|
+
result = empty_params_result
|
|
855
|
+
result[1].unshift(val[0])
|
|
856
|
+
}
|
|
857
|
+
| rest_positional_param
|
|
858
|
+
|
|
859
|
+
rest_positional_param:
|
|
860
|
+
rest_positional kCOMMA trailing_positional_params {
|
|
861
|
+
result = val[2]
|
|
862
|
+
result[2] = val[0]
|
|
863
|
+
}
|
|
864
|
+
| rest_positional {
|
|
865
|
+
result = empty_params_result
|
|
866
|
+
result[2] = val[0]
|
|
867
|
+
}
|
|
868
|
+
| trailing_positional_params
|
|
869
|
+
|
|
870
|
+
trailing_positional_params:
|
|
871
|
+
required_positional kCOMMA trailing_positional_params {
|
|
872
|
+
result = val[2]
|
|
873
|
+
result[3].unshift(val[0])
|
|
874
|
+
}
|
|
875
|
+
| required_positional {
|
|
876
|
+
result = empty_params_result
|
|
877
|
+
result[3].unshift(val[0])
|
|
878
|
+
}
|
|
879
|
+
| keyword_params
|
|
880
|
+
|
|
881
|
+
keyword_params:
|
|
882
|
+
{
|
|
883
|
+
result = empty_params_result
|
|
884
|
+
}
|
|
885
|
+
| required_keyword kCOMMA keyword_params {
|
|
886
|
+
result = val[2]
|
|
887
|
+
result[4].merge!(val[0])
|
|
888
|
+
}
|
|
889
|
+
| required_keyword {
|
|
890
|
+
result = empty_params_result
|
|
891
|
+
result[4].merge!(val[0])
|
|
892
|
+
}
|
|
893
|
+
| optional_keyword kCOMMA keyword_params {
|
|
894
|
+
result = val[2]
|
|
895
|
+
result[5].merge!(val[0])
|
|
896
|
+
}
|
|
897
|
+
| optional_keyword {
|
|
898
|
+
result = empty_params_result
|
|
899
|
+
result[5].merge!(val[0])
|
|
900
|
+
}
|
|
901
|
+
| rest_keyword {
|
|
902
|
+
result = empty_params_result
|
|
903
|
+
result[6] = val[0]
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
required_positional:
|
|
907
|
+
type var_name_opt {
|
|
908
|
+
result = Types::Function::Param.new(type: val[0],
|
|
909
|
+
name: val[1]&.value&.to_sym)
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
optional_positional:
|
|
913
|
+
kQUESTION type var_name_opt {
|
|
914
|
+
result = Types::Function::Param.new(type: val[1],
|
|
915
|
+
name: val[2]&.value&.to_sym)
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
rest_positional:
|
|
919
|
+
kSTAR type var_name_opt {
|
|
920
|
+
result = Types::Function::Param.new(type: val[1],
|
|
921
|
+
name: val[2]&.value&.to_sym)
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
required_keyword:
|
|
925
|
+
keyword_name type var_name_opt {
|
|
926
|
+
param = Types::Function::Param.new(type: val[1],
|
|
927
|
+
name: val[2]&.value&.to_sym)
|
|
928
|
+
result = { val[0].value => param }
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
optional_keyword:
|
|
932
|
+
kQUESTION keyword_name type var_name_opt {
|
|
933
|
+
param = Types::Function::Param.new(type: val[2],
|
|
934
|
+
name: val[3]&.value&.to_sym)
|
|
935
|
+
result = { val[1].value => param }
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
rest_keyword:
|
|
939
|
+
kSTAR2 type var_name_opt {
|
|
940
|
+
result = Types::Function::Param.new(type: val[1],
|
|
941
|
+
name: val[2]&.value&.to_sym)
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
var_name_opt:
|
|
945
|
+
| tLIDENT | tINTERFACEIDENT | tQUOTEDIDENT
|
|
946
|
+
|
|
947
|
+
qualified_name:
|
|
948
|
+
namespace simple_name {
|
|
949
|
+
namespace = val[0]&.value || Namespace.empty
|
|
950
|
+
name = val[1].value.to_sym
|
|
951
|
+
type_name = TypeName.new(namespace: namespace, name: name)
|
|
952
|
+
location = (loc0 = val[0]&.location) ? loc0 + val[1].location : val[1].location
|
|
953
|
+
result = LocatedValue.new(value: type_name, location: location)
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
simple_name:
|
|
957
|
+
tUIDENT | tLIDENT | tINTERFACEIDENT
|
|
958
|
+
|
|
959
|
+
interface_name:
|
|
960
|
+
namespace tINTERFACEIDENT {
|
|
961
|
+
namespace = val[0]&.value || Namespace.empty
|
|
962
|
+
name = val[1].value.to_sym
|
|
963
|
+
type_name = TypeName.new(namespace: namespace, name: name)
|
|
964
|
+
location = (loc0 = val[0]&.location) ? loc0 + val[1].location : val[1].location
|
|
965
|
+
result = LocatedValue.new(value: type_name, location: location)
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
class_name:
|
|
969
|
+
namespace tUIDENT {
|
|
970
|
+
namespace = val[0]&.value || Namespace.empty
|
|
971
|
+
name = val[1].value.to_sym
|
|
972
|
+
type_name = TypeName.new(namespace: namespace, name: name)
|
|
973
|
+
location = (loc0 = val[0]&.location) ? loc0 + val[1].location : val[1].location
|
|
974
|
+
result = LocatedValue.new(value: type_name, location: location)
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
namespace:
|
|
978
|
+
{
|
|
979
|
+
result = nil
|
|
980
|
+
}
|
|
981
|
+
| kCOLON2 {
|
|
982
|
+
result = LocatedValue.new(value: Namespace.root, location: val[0].location)
|
|
983
|
+
}
|
|
984
|
+
| kCOLON2 tNAMESPACE {
|
|
985
|
+
namespace = Namespace.parse(val[1].value).absolute!
|
|
986
|
+
result = LocatedValue.new(value: namespace, location: val[0].location + val[1].location)
|
|
987
|
+
}
|
|
988
|
+
| tNAMESPACE {
|
|
989
|
+
namespace = Namespace.parse(val[0].value)
|
|
990
|
+
result = LocatedValue.new(value: namespace, location: val[0].location)
|
|
991
|
+
}
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
---- inner
|
|
995
|
+
|
|
996
|
+
Types = RBS::Types
|
|
997
|
+
Namespace = RBS::Namespace
|
|
998
|
+
TypeName = RBS::TypeName
|
|
999
|
+
Declarations = RBS::AST::Declarations
|
|
1000
|
+
Members = RBS::AST::Members
|
|
1001
|
+
MethodType = RBS::MethodType
|
|
1002
|
+
Annotation = RBS::AST::Annotation
|
|
1003
|
+
|
|
1004
|
+
class LocatedValue
|
|
1005
|
+
attr_reader :location
|
|
1006
|
+
attr_reader :value
|
|
1007
|
+
|
|
1008
|
+
def initialize(location:, value:)
|
|
1009
|
+
@location = location
|
|
1010
|
+
@value = value
|
|
1011
|
+
end
|
|
1012
|
+
end
|
|
1013
|
+
|
|
1014
|
+
require "strscan"
|
|
1015
|
+
|
|
1016
|
+
attr_reader :input
|
|
1017
|
+
attr_reader :buffer
|
|
1018
|
+
attr_reader :eof_re
|
|
1019
|
+
|
|
1020
|
+
def initialize(type, buffer:, eof_re:)
|
|
1021
|
+
super()
|
|
1022
|
+
@type = type
|
|
1023
|
+
@buffer = buffer
|
|
1024
|
+
@input = StringScanner.new(buffer.content)
|
|
1025
|
+
@eof_re = eof_re
|
|
1026
|
+
@eof = false
|
|
1027
|
+
@bound_variables_stack = []
|
|
1028
|
+
@comments = {}
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
def start_merged_variables_scope
|
|
1032
|
+
set = @bound_variables_stack.last&.dup || Set.new
|
|
1033
|
+
@bound_variables_stack.push set
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
def start_new_variables_scope
|
|
1037
|
+
@bound_variables_stack.push Set.new
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
def reset_variable_scope
|
|
1041
|
+
@bound_variables_stack.pop
|
|
1042
|
+
end
|
|
1043
|
+
|
|
1044
|
+
def insert_bound_variable(var)
|
|
1045
|
+
@bound_variables_stack.last << var
|
|
1046
|
+
end
|
|
1047
|
+
|
|
1048
|
+
def is_bound_variable?(var)
|
|
1049
|
+
(@bound_variables_stack.last || Set.new).member?(var)
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
def self.parse_signature(input, eof_re: nil)
|
|
1053
|
+
case input
|
|
1054
|
+
when RBS::Buffer
|
|
1055
|
+
buffer = input
|
|
1056
|
+
else
|
|
1057
|
+
buffer = RBS::Buffer.new(name: nil, content: input.to_s)
|
|
1058
|
+
end
|
|
1059
|
+
|
|
1060
|
+
self.new(:SIGNATURE, buffer: buffer, eof_re: eof_re).do_parse
|
|
1061
|
+
end
|
|
1062
|
+
|
|
1063
|
+
def self.parse_type(input, variables: [], eof_re: nil)
|
|
1064
|
+
case input
|
|
1065
|
+
when RBS::Buffer
|
|
1066
|
+
buffer = input
|
|
1067
|
+
else
|
|
1068
|
+
buffer = RBS::Buffer.new(name: nil, content: input.to_s)
|
|
1069
|
+
end
|
|
1070
|
+
|
|
1071
|
+
self.new(:TYPE, buffer: buffer, eof_re: eof_re).yield_self do |parser|
|
|
1072
|
+
parser.start_new_variables_scope
|
|
1073
|
+
|
|
1074
|
+
variables.each do |var|
|
|
1075
|
+
parser.insert_bound_variable var
|
|
1076
|
+
end
|
|
1077
|
+
|
|
1078
|
+
parser.do_parse
|
|
1079
|
+
ensure
|
|
1080
|
+
parser.reset_variable_scope
|
|
1081
|
+
end
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
def self.parse_method_type(input, variables: [], eof_re: nil)
|
|
1085
|
+
case input
|
|
1086
|
+
when RBS::Buffer
|
|
1087
|
+
buffer = input
|
|
1088
|
+
else
|
|
1089
|
+
buffer = RBS::Buffer.new(name: nil, content: input.to_s)
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
self.new(:METHODTYPE, buffer: buffer, eof_re: eof_re).yield_self do |parser|
|
|
1093
|
+
parser.start_new_variables_scope
|
|
1094
|
+
|
|
1095
|
+
variables.each do |var|
|
|
1096
|
+
parser.insert_bound_variable var
|
|
1097
|
+
end
|
|
1098
|
+
|
|
1099
|
+
parser.do_parse
|
|
1100
|
+
ensure
|
|
1101
|
+
parser.reset_variable_scope
|
|
1102
|
+
end
|
|
1103
|
+
end
|
|
1104
|
+
|
|
1105
|
+
def leading_comment(location)
|
|
1106
|
+
@comments[location.start_line-1]
|
|
1107
|
+
end
|
|
1108
|
+
|
|
1109
|
+
def push_comment(string, location)
|
|
1110
|
+
new_comment = AST::Comment.new(string: string+"\n", location: location)
|
|
1111
|
+
|
|
1112
|
+
if (prev_comment = leading_comment(location)) && prev_comment.location.start_column == location.start_column
|
|
1113
|
+
@comments.delete prev_comment.location.end_line
|
|
1114
|
+
new_comment = AST::Comment.new(string: prev_comment.string + new_comment.string,
|
|
1115
|
+
location: prev_comment.location + new_comment.location)
|
|
1116
|
+
end
|
|
1117
|
+
|
|
1118
|
+
@comments[new_comment.location.end_line] = new_comment
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
def new_token(type, value = input.matched)
|
|
1122
|
+
start_index = input.charpos - input.matched.size
|
|
1123
|
+
end_index = input.charpos
|
|
1124
|
+
|
|
1125
|
+
location = RBS::Location.new(buffer: buffer,
|
|
1126
|
+
start_pos: start_index,
|
|
1127
|
+
end_pos: end_index)
|
|
1128
|
+
|
|
1129
|
+
[type, LocatedValue.new(location: location, value: value)]
|
|
1130
|
+
end
|
|
1131
|
+
|
|
1132
|
+
def empty_params_result
|
|
1133
|
+
[
|
|
1134
|
+
[],
|
|
1135
|
+
[],
|
|
1136
|
+
nil,
|
|
1137
|
+
[],
|
|
1138
|
+
{},
|
|
1139
|
+
{},
|
|
1140
|
+
nil
|
|
1141
|
+
]
|
|
1142
|
+
end
|
|
1143
|
+
|
|
1144
|
+
KEYWORDS = {
|
|
1145
|
+
"class" => :kCLASS,
|
|
1146
|
+
"type" => :kTYPE,
|
|
1147
|
+
"def" => :kDEF,
|
|
1148
|
+
"self" => :kSELF,
|
|
1149
|
+
"void" => :kVOID,
|
|
1150
|
+
"any" => :kANY,
|
|
1151
|
+
"untyped" => :kUNTYPED,
|
|
1152
|
+
"top" => :kTOP,
|
|
1153
|
+
"bot" => :kBOT,
|
|
1154
|
+
"instance" => :kINSTANCE,
|
|
1155
|
+
"bool" => :kBOOL,
|
|
1156
|
+
"nil" => :kNIL,
|
|
1157
|
+
"true" => :kTRUE,
|
|
1158
|
+
"false" => :kFALSE,
|
|
1159
|
+
"singleton" => :kSINGLETON,
|
|
1160
|
+
"interface" => :kINTERFACE,
|
|
1161
|
+
"end" => :kEND,
|
|
1162
|
+
"include" => :kINCLUDE,
|
|
1163
|
+
"extend" => :kEXTEND,
|
|
1164
|
+
"prepend" => :kPREPEND,
|
|
1165
|
+
"module" => :kMODULE,
|
|
1166
|
+
"attr_reader" => :kATTRREADER,
|
|
1167
|
+
"attr_writer" => :kATTRWRITER,
|
|
1168
|
+
"attr_accessor" => :kATTRACCESSOR,
|
|
1169
|
+
"super" => :kSUPER,
|
|
1170
|
+
"public" => :kPUBLIC,
|
|
1171
|
+
"private" => :kPRIVATE,
|
|
1172
|
+
"alias" => :kALIAS,
|
|
1173
|
+
"extension" => :kEXTENSION,
|
|
1174
|
+
"incompatible" => :kINCOMPATIBLE,
|
|
1175
|
+
"unchecked" => :kUNCHECKED,
|
|
1176
|
+
"out" => :kOUT,
|
|
1177
|
+
"in" => :kIN,
|
|
1178
|
+
}
|
|
1179
|
+
KEYWORDS_RE = /#{Regexp.union(*KEYWORDS.keys)}\b/
|
|
1180
|
+
|
|
1181
|
+
PUNCTS = {
|
|
1182
|
+
"===" => :tOPERATOR,
|
|
1183
|
+
"==" => :tOPERATOR,
|
|
1184
|
+
"=~" => :tOPERATOR,
|
|
1185
|
+
"!~" => :tOPERATOR,
|
|
1186
|
+
"!=" => :tOPERATOR,
|
|
1187
|
+
">=" => :tOPERATOR,
|
|
1188
|
+
"<<" => :tOPERATOR,
|
|
1189
|
+
"<=>" => :tOPERATOR,
|
|
1190
|
+
"<=" => :tOPERATOR,
|
|
1191
|
+
">>" => :tOPERATOR,
|
|
1192
|
+
">" => :tOPERATOR,
|
|
1193
|
+
"~" => :tOPERATOR,
|
|
1194
|
+
"+@" => :tOPERATOR,
|
|
1195
|
+
"+" => :tOPERATOR,
|
|
1196
|
+
"[]=" => :tOPERATOR,
|
|
1197
|
+
"[]" => :tOPERATOR,
|
|
1198
|
+
"::" => :kCOLON2,
|
|
1199
|
+
":" => :kCOLON,
|
|
1200
|
+
"(" => :kLPAREN,
|
|
1201
|
+
")" => :kRPAREN,
|
|
1202
|
+
"[" => :kLBRACKET,
|
|
1203
|
+
"]" => :kRBRACKET,
|
|
1204
|
+
"{" => :kLBRACE,
|
|
1205
|
+
"}" => :kRBRACE,
|
|
1206
|
+
"," => :kCOMMA,
|
|
1207
|
+
"|" => :kBAR,
|
|
1208
|
+
"&" => :kAMP,
|
|
1209
|
+
"^" => :kHAT,
|
|
1210
|
+
"->" => :kARROW,
|
|
1211
|
+
"=>" => :kFATARROW,
|
|
1212
|
+
"=" => :kEQ,
|
|
1213
|
+
"?" => :kQUESTION,
|
|
1214
|
+
"!" => :kEXCLAMATION,
|
|
1215
|
+
"**" => :kSTAR2,
|
|
1216
|
+
"*" => :kSTAR,
|
|
1217
|
+
"." => :kDOT,
|
|
1218
|
+
"<" => :kLT,
|
|
1219
|
+
"-@" => :tOPERATOR,
|
|
1220
|
+
"-" => :tOPERATOR,
|
|
1221
|
+
"/" => :tOPERATOR,
|
|
1222
|
+
"`" => :tOPERATOR,
|
|
1223
|
+
"%" => :tOPERATOR,
|
|
1224
|
+
}
|
|
1225
|
+
PUNCTS_RE = Regexp.union(*PUNCTS.keys)
|
|
1226
|
+
|
|
1227
|
+
ANNOTATION_RE = Regexp.union(/%a\{.*?\}/,
|
|
1228
|
+
/%a\[.*?\]/,
|
|
1229
|
+
/%a\(.*?\)/,
|
|
1230
|
+
/%a\<.*?\>/,
|
|
1231
|
+
/%a\|.*?\|/)
|
|
1232
|
+
def next_token
|
|
1233
|
+
if @type
|
|
1234
|
+
type = @type
|
|
1235
|
+
@type = nil
|
|
1236
|
+
return [:"type_#{type}", nil]
|
|
1237
|
+
end
|
|
1238
|
+
|
|
1239
|
+
return if @eof
|
|
1240
|
+
|
|
1241
|
+
while true
|
|
1242
|
+
return if input.eos?
|
|
1243
|
+
|
|
1244
|
+
case
|
|
1245
|
+
when input.scan(/\s+/)
|
|
1246
|
+
# skip
|
|
1247
|
+
when input.scan(/#(( *)|( ?(?<string>.*)))\n/)
|
|
1248
|
+
start_index = input.charpos - input.matched.size
|
|
1249
|
+
end_index = input.charpos-1
|
|
1250
|
+
|
|
1251
|
+
location = RBS::Location.new(buffer: buffer,
|
|
1252
|
+
start_pos: start_index,
|
|
1253
|
+
end_pos: end_index)
|
|
1254
|
+
|
|
1255
|
+
push_comment input[:string] || "", location
|
|
1256
|
+
else
|
|
1257
|
+
break
|
|
1258
|
+
end
|
|
1259
|
+
end
|
|
1260
|
+
|
|
1261
|
+
case
|
|
1262
|
+
when eof_re && input.scan(eof_re)
|
|
1263
|
+
@eof = true
|
|
1264
|
+
[:tEOF, input.matched]
|
|
1265
|
+
when input.scan(/`[a-zA-Z_]\w*`/)
|
|
1266
|
+
s = input.matched.yield_self {|s| s[1, s.length-2] }
|
|
1267
|
+
new_token(:tQUOTEDIDENT, s)
|
|
1268
|
+
when input.scan(/`(\\`|[^` :])+`/)
|
|
1269
|
+
s = input.matched.yield_self {|s| s[1, s.length-2] }.gsub(/\\`/, '`')
|
|
1270
|
+
new_token(:tQUOTEDMETHOD, s)
|
|
1271
|
+
when input.scan(ANNOTATION_RE)
|
|
1272
|
+
s = input.matched.yield_self {|s| s[3, s.length-4] }.strip
|
|
1273
|
+
new_token(:tANNOTATION, s)
|
|
1274
|
+
when input.scan(/self\?/)
|
|
1275
|
+
new_token(:kSELFQ, "self?")
|
|
1276
|
+
when input.scan(/(([a-zA-Z]\w*)|(_\w+))=/)
|
|
1277
|
+
new_token(:tWRITE_ATTR)
|
|
1278
|
+
when input.scan(KEYWORDS_RE)
|
|
1279
|
+
new_token(KEYWORDS[input.matched], input.matched.to_sym)
|
|
1280
|
+
when input.scan(/:((@{,2}|\$)?\w+(\?|\!)?|\+|\-)\b?/)
|
|
1281
|
+
s = input.matched.yield_self {|s| s[1, s.length] }.to_sym
|
|
1282
|
+
new_token(:tSYMBOL, s)
|
|
1283
|
+
when input.scan(/[+-]?\d[\d_]*/)
|
|
1284
|
+
new_token(:tINTEGER, input.matched.to_i)
|
|
1285
|
+
when input.scan(PUNCTS_RE)
|
|
1286
|
+
new_token(PUNCTS[input.matched])
|
|
1287
|
+
when input.scan(/(::)?([A-Z]\w*::)+/)
|
|
1288
|
+
new_token(:tNAMESPACE)
|
|
1289
|
+
when input.scan(/[a-z_]\w*:/)
|
|
1290
|
+
new_token(:tLKEYWORD, input.matched.chop.to_sym)
|
|
1291
|
+
when input.scan(/[A-Z]\w*:/)
|
|
1292
|
+
new_token(:tUKEYWORD, input.matched.chop.to_sym)
|
|
1293
|
+
when input.scan(/\$[A-Za-z_]\w*/)
|
|
1294
|
+
new_token(:tGLOBALIDENT)
|
|
1295
|
+
when input.scan(/@[a-zA-Z_]\w*/)
|
|
1296
|
+
new_token(:tIVAR, input.matched.to_sym)
|
|
1297
|
+
when input.scan(/@@[a-zA-Z_]\w*/)
|
|
1298
|
+
new_token(:tCLASSVAR, input.matched.to_sym)
|
|
1299
|
+
when input.scan(/_[a-zA-Z]\w*\b/)
|
|
1300
|
+
new_token(:tINTERFACEIDENT)
|
|
1301
|
+
when input.scan(/[A-Z]\w*\b/)
|
|
1302
|
+
new_token(:tUIDENT)
|
|
1303
|
+
when input.scan(/[a-z_]\w*\b/)
|
|
1304
|
+
new_token(:tLIDENT)
|
|
1305
|
+
when input.scan(/"(\\"|[^"])*"/)
|
|
1306
|
+
s = input.matched.yield_self {|s| s[1, s.length - 2] }.gsub(/\\"/, '"')
|
|
1307
|
+
new_token(:tSTRING, s)
|
|
1308
|
+
when input.scan(/'(\\'|[^'])*'/)
|
|
1309
|
+
s = input.matched.yield_self {|s| s[1, s.length - 2] }.gsub(/\\'/, "'")
|
|
1310
|
+
new_token(:tSTRING, s)
|
|
1311
|
+
else
|
|
1312
|
+
raise "Unexpected token: #{input.peek(10)}..."
|
|
1313
|
+
end
|
|
1314
|
+
end
|
|
1315
|
+
|
|
1316
|
+
def on_error(token_id, error_value, value_stack)
|
|
1317
|
+
raise SyntaxError.new(token_str: token_to_str(token_id), error_value: error_value, value_stack: value_stack)
|
|
1318
|
+
end
|
|
1319
|
+
|
|
1320
|
+
class SyntaxError < StandardError
|
|
1321
|
+
attr_reader :token_str, :error_value, :value_stack
|
|
1322
|
+
|
|
1323
|
+
def initialize(token_str:, error_value:, value_stack: nil)
|
|
1324
|
+
@token_str = token_str
|
|
1325
|
+
@error_value = error_value
|
|
1326
|
+
@value_stack = value_stack
|
|
1327
|
+
|
|
1328
|
+
super "parse error on value: #{error_value.inspect} (#{token_str})"
|
|
1329
|
+
end
|
|
1330
|
+
end
|
|
1331
|
+
|
|
1332
|
+
class SemanticsError < StandardError
|
|
1333
|
+
attr_reader :subject, :location, :original_message
|
|
1334
|
+
|
|
1335
|
+
def initialize(message, subject:, location:)
|
|
1336
|
+
@subject = subject
|
|
1337
|
+
@location = location
|
|
1338
|
+
@original_message = message
|
|
1339
|
+
|
|
1340
|
+
super "parse error on #{location}: #{message}"
|
|
1341
|
+
end
|
|
1342
|
+
end
|
|
1343
|
+
|
|
1344
|
+
---- footer
|