steep 0.1.0.pre2 → 0.1.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 +5 -5
- data/.travis.yml +1 -1
- data/README.md +146 -33
- data/bin/smoke_runner.rb +43 -10
- data/lib/steep/ast/annotation/collection.rb +93 -0
- data/lib/steep/ast/annotation.rb +131 -0
- data/lib/steep/ast/buffer.rb +47 -0
- data/lib/steep/ast/location.rb +82 -0
- data/lib/steep/ast/method_type.rb +116 -0
- data/lib/steep/ast/signature/class.rb +33 -0
- data/lib/steep/ast/signature/const.rb +17 -0
- data/lib/steep/ast/signature/env.rb +123 -0
- data/lib/steep/ast/signature/extension.rb +21 -0
- data/lib/steep/ast/signature/gvar.rb +17 -0
- data/lib/steep/ast/signature/interface.rb +31 -0
- data/lib/steep/ast/signature/members.rb +71 -0
- data/lib/steep/ast/signature/module.rb +21 -0
- data/lib/steep/ast/type_params.rb +13 -0
- data/lib/steep/ast/types/any.rb +39 -0
- data/lib/steep/ast/types/bot.rb +39 -0
- data/lib/steep/ast/types/class.rb +35 -0
- data/lib/steep/ast/types/helper.rb +21 -0
- data/lib/steep/ast/types/instance.rb +39 -0
- data/lib/steep/ast/types/intersection.rb +74 -0
- data/lib/steep/ast/types/name.rb +124 -0
- data/lib/steep/ast/types/self.rb +39 -0
- data/lib/steep/ast/types/top.rb +39 -0
- data/lib/steep/ast/types/union.rb +74 -0
- data/lib/steep/ast/types/var.rb +57 -0
- data/lib/steep/ast/types/void.rb +35 -0
- data/lib/steep/cli.rb +28 -1
- data/lib/steep/drivers/annotations.rb +32 -0
- data/lib/steep/drivers/check.rb +53 -77
- data/lib/steep/drivers/scaffold.rb +303 -0
- data/lib/steep/drivers/utils/each_signature.rb +66 -0
- data/lib/steep/drivers/utils/validator.rb +115 -0
- data/lib/steep/drivers/validate.rb +39 -0
- data/lib/steep/errors.rb +291 -19
- data/lib/steep/interface/abstract.rb +44 -0
- data/lib/steep/interface/builder.rb +470 -0
- data/lib/steep/interface/instantiated.rb +126 -0
- data/lib/steep/interface/ivar_chain.rb +26 -0
- data/lib/steep/interface/method.rb +60 -0
- data/lib/steep/{interface.rb → interface/method_type.rb} +111 -100
- data/lib/steep/interface/substitution.rb +65 -0
- data/lib/steep/module_name.rb +116 -0
- data/lib/steep/parser.rb +1314 -814
- data/lib/steep/parser.y +536 -175
- data/lib/steep/source.rb +220 -25
- data/lib/steep/subtyping/check.rb +673 -0
- data/lib/steep/subtyping/constraints.rb +275 -0
- data/lib/steep/subtyping/relation.rb +41 -0
- data/lib/steep/subtyping/result.rb +126 -0
- data/lib/steep/subtyping/trace.rb +48 -0
- data/lib/steep/subtyping/variable_occurrence.rb +49 -0
- data/lib/steep/subtyping/variable_variance.rb +69 -0
- data/lib/steep/type_construction.rb +1630 -524
- data/lib/steep/type_inference/block_params.rb +100 -0
- data/lib/steep/type_inference/constant_env.rb +55 -0
- data/lib/steep/type_inference/send_args.rb +222 -0
- data/lib/steep/type_inference/type_env.rb +226 -0
- data/lib/steep/type_name.rb +27 -7
- data/lib/steep/typing.rb +4 -0
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +71 -16
- data/smoke/and/a.rb +4 -2
- data/smoke/array/a.rb +4 -5
- data/smoke/array/b.rb +4 -4
- data/smoke/block/a.rb +2 -2
- data/smoke/block/a.rbi +2 -0
- data/smoke/block/b.rb +15 -0
- data/smoke/case/a.rb +3 -3
- data/smoke/class/a.rb +3 -3
- data/smoke/class/b.rb +0 -2
- data/smoke/class/d.rb +2 -2
- data/smoke/class/e.rb +1 -1
- data/smoke/class/f.rb +2 -2
- data/smoke/class/g.rb +8 -0
- data/smoke/const/a.rb +3 -3
- data/smoke/dstr/a.rb +1 -1
- data/smoke/ensure/a.rb +22 -0
- data/smoke/enumerator/a.rb +6 -6
- data/smoke/enumerator/b.rb +22 -0
- data/smoke/extension/a.rb +2 -2
- data/smoke/extension/b.rb +3 -3
- data/smoke/extension/c.rb +1 -1
- data/smoke/hello/hello.rb +2 -2
- data/smoke/if/a.rb +4 -2
- data/smoke/kwbegin/a.rb +8 -0
- data/smoke/literal/a.rb +5 -5
- data/smoke/method/a.rb +5 -5
- data/smoke/method/a.rbi +4 -0
- data/smoke/method/b.rb +29 -0
- data/smoke/module/a.rb +3 -3
- data/smoke/module/a.rbi +9 -0
- data/smoke/module/b.rb +2 -2
- data/smoke/module/c.rb +1 -1
- data/smoke/module/d.rb +5 -0
- data/smoke/module/e.rb +13 -0
- data/smoke/module/f.rb +13 -0
- data/smoke/rescue/a.rb +62 -0
- data/smoke/super/a.rb +2 -2
- data/smoke/type_case/a.rb +35 -0
- data/smoke/yield/a.rb +2 -2
- data/stdlib/builtin.rbi +463 -24
- data/steep.gemspec +3 -2
- metadata +91 -29
- data/lib/steep/annotation.rb +0 -223
- data/lib/steep/signature/class.rb +0 -450
- data/lib/steep/signature/extension.rb +0 -51
- data/lib/steep/signature/interface.rb +0 -49
- data/lib/steep/types/any.rb +0 -31
- data/lib/steep/types/class.rb +0 -27
- data/lib/steep/types/instance.rb +0 -27
- data/lib/steep/types/merge.rb +0 -32
- data/lib/steep/types/name.rb +0 -57
- data/lib/steep/types/union.rb +0 -42
- data/lib/steep/types/var.rb +0 -38
- data/lib/steep/types.rb +0 -4
data/lib/steep/parser.y
CHANGED
@@ -1,84 +1,191 @@
|
|
1
1
|
class Steep::Parser
|
2
2
|
|
3
|
+
expect 1
|
4
|
+
|
3
5
|
rule
|
4
6
|
|
5
7
|
target: type_METHOD method_type { result = val[1] }
|
6
8
|
| type_SIGNATURE signatures { result = val[1] }
|
7
9
|
| type_ANNOTATION annotation { result = val[1] }
|
8
10
|
|
9
|
-
method_type:
|
10
|
-
|
11
|
+
method_type:
|
12
|
+
type_params params block_opt ARROW return_type {
|
13
|
+
result = AST::MethodType.new(location: AST::Location.concat(*val.compact.map(&:location)),
|
14
|
+
type_params: val[0],
|
15
|
+
params: val[1]&.value,
|
16
|
+
block: val[2],
|
17
|
+
return_type: val[4])
|
18
|
+
}
|
11
19
|
|
12
20
|
return_type: simple_type
|
13
|
-
| LPAREN union_seq RPAREN { result = Types::Union.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
| LPAREN union_seq RPAREN { result = AST::Types::Union.build(location: val[0].location + val[2].location,
|
22
|
+
types: val[1]) }
|
23
|
+
|
24
|
+
params: { result = nil }
|
25
|
+
| LPAREN params0 RPAREN { result = LocatedValue.new(location: val[0].location + val[2].location,
|
26
|
+
value: val[1]) }
|
27
|
+
| type { result = LocatedValue.new(location: val[0].location,
|
28
|
+
value: AST::MethodType::Params::Required.new(location: val[0].location, type: val[0])) }
|
29
|
+
|
30
|
+
params0: required_param { result = AST::MethodType::Params::Required.new(location: val[0].location, type: val[0]) }
|
31
|
+
| required_param COMMA params0 {
|
32
|
+
location = val[0].location
|
33
|
+
result = AST::MethodType::Params::Required.new(location: location,
|
34
|
+
type: val[0],
|
35
|
+
next_params: val[2])
|
36
|
+
}
|
21
37
|
| params1 { result = val[0] }
|
22
38
|
|
23
|
-
params1: optional_param { result =
|
24
|
-
| optional_param COMMA params1 {
|
39
|
+
params1: optional_param { result = AST::MethodType::Params::Optional.new(location: val[0].first, type: val[0].last) }
|
40
|
+
| optional_param COMMA params1 {
|
41
|
+
location = val[0].first
|
42
|
+
result = AST::MethodType::Params::Optional.new(type: val[0].last, location: location, next_params: val[2])
|
43
|
+
}
|
25
44
|
| params2 { result = val[0] }
|
26
45
|
|
27
|
-
params2: rest_param { result =
|
28
|
-
| rest_param COMMA params3 {
|
46
|
+
params2: rest_param { result = AST::MethodType::Params::Rest.new(location: val[0].first, type: val[0].last) }
|
47
|
+
| rest_param COMMA params3 {
|
48
|
+
loc = val[0].first
|
49
|
+
result = AST::MethodType::Params::Rest.new(location: loc, type: val[0].last, next_params: val[2])
|
50
|
+
}
|
29
51
|
| params3 { result = val[0] }
|
30
52
|
|
31
|
-
params3: required_keyword {
|
32
|
-
|
33
|
-
|
34
|
-
|
53
|
+
params3: required_keyword {
|
54
|
+
location, name, type = val[0]
|
55
|
+
result = AST::MethodType::Params::RequiredKeyword.new(location: location, name: name, type: type)
|
56
|
+
}
|
57
|
+
| optional_keyword {
|
58
|
+
location, name, type = val[0]
|
59
|
+
result = AST::MethodType::Params::OptionalKeyword.new(location: location, name: name, type: type)
|
60
|
+
}
|
61
|
+
| required_keyword COMMA params3 {
|
62
|
+
location, name, type = val[0]
|
63
|
+
result = AST::MethodType::Params::RequiredKeyword.new(location: location,
|
64
|
+
name: name,
|
65
|
+
type: type,
|
66
|
+
next_params: val[2])
|
67
|
+
}
|
68
|
+
| optional_keyword COMMA params3 {
|
69
|
+
location, name, type = val[0]
|
70
|
+
result = AST::MethodType::Params::OptionalKeyword.new(location: location,
|
71
|
+
name: name,
|
72
|
+
type: type,
|
73
|
+
next_params: val[2])
|
74
|
+
}
|
35
75
|
| params4 { result = val[0] }
|
36
76
|
|
37
|
-
params4: { result =
|
38
|
-
| STAR2 type {
|
77
|
+
params4: { result = nil }
|
78
|
+
| STAR2 type {
|
79
|
+
result = AST::MethodType::Params::RestKeyword.new(location: val[0].location + val[1].location,
|
80
|
+
type: val[1])
|
81
|
+
}
|
39
82
|
|
40
83
|
required_param: type { result = val[0] }
|
41
|
-
optional_param: QUESTION type { result = val[1]
|
42
|
-
|
43
|
-
|
44
|
-
|
84
|
+
optional_param: QUESTION type { result = [val[0].location + val[1].location,
|
85
|
+
val[1]] }
|
86
|
+
rest_param: STAR type { result = [val[0].location + val[1].location,
|
87
|
+
val[1]] }
|
88
|
+
required_keyword: keyword COLON type { result = [val[0].location + val[2].location,
|
89
|
+
val[0].value,
|
90
|
+
val[2]] }
|
91
|
+
optional_keyword: QUESTION keyword COLON type { result = [val[0].location + val[3].location,
|
92
|
+
val[1].value,
|
93
|
+
val[3]] }
|
45
94
|
|
46
95
|
block_opt: { result = nil }
|
47
|
-
| LBRACE RBRACE {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
96
|
+
| LBRACE RBRACE {
|
97
|
+
result = AST::MethodType::Block.new(params: nil,
|
98
|
+
return_type: nil,
|
99
|
+
location: val[0].location + val[1].location)
|
100
|
+
}
|
101
|
+
| LBRACE block_params ARROW type RBRACE {
|
102
|
+
result = AST::MethodType::Block.new(params: val[1],
|
103
|
+
return_type: val[3],
|
104
|
+
location: val[0].location + val[4].location)
|
105
|
+
}
|
106
|
+
|
107
|
+
block_params: { result = nil }
|
108
|
+
| LPAREN block_params0 RPAREN {
|
109
|
+
result = val[1]
|
110
|
+
}
|
111
|
+
|
112
|
+
block_params0: required_param {
|
113
|
+
result = AST::MethodType::Params::Required.new(location: val[0].location,
|
114
|
+
type: val[0])
|
115
|
+
}
|
116
|
+
| required_param COMMA block_params0 {
|
117
|
+
result = AST::MethodType::Params::Required.new(location: val[0].location,
|
118
|
+
type: val[0],
|
119
|
+
next_params: val[2])
|
120
|
+
}
|
56
121
|
| block_params1 { result = val[0] }
|
57
122
|
|
58
|
-
block_params1: optional_param {
|
59
|
-
|
123
|
+
block_params1: optional_param {
|
124
|
+
result = AST::MethodType::Params::Optional.new(location: val[0].first,
|
125
|
+
type: val[0].last)
|
126
|
+
}
|
127
|
+
| optional_param COMMA block_params1 {
|
128
|
+
loc = val.first[0] + (val[2] || val[1]).location
|
129
|
+
type = val.first[1]
|
130
|
+
next_params = val[2]
|
131
|
+
result = AST::MethodType::Params::Optional.new(location: loc, type: type, next_params: next_params)
|
132
|
+
}
|
60
133
|
| block_params2 { result = val[0] }
|
61
134
|
|
62
|
-
block_params2: { result =
|
63
|
-
| rest_param {
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
135
|
+
block_params2: { result = nil }
|
136
|
+
| rest_param {
|
137
|
+
result = AST::MethodType::Params::Rest.new(location: val[0].first, type: val[0].last)
|
138
|
+
}
|
139
|
+
|
140
|
+
simple_type: type_name {
|
141
|
+
result = AST::Types::Name.new(name: val[0].value, location: val[0].location, args: [])
|
142
|
+
}
|
143
|
+
| instance_type_name LT type_seq GT {
|
144
|
+
loc = val[0].location + val[3].location
|
145
|
+
name = val[0].value
|
146
|
+
args = val[2]
|
147
|
+
result = AST::Types::Name.new(location: loc, name: name, args: args)
|
148
|
+
}
|
149
|
+
| ANY { result = AST::Types::Any.new(location: val[0].location) }
|
150
|
+
| TVAR { result = AST::Types::Var.new(location: val[0].location, name: val[0].value) }
|
151
|
+
| CLASS { result = AST::Types::Class.new(location: val[0].location) }
|
152
|
+
| MODULE { result = AST::Types::Class.new(location: val[0].location) }
|
153
|
+
| INSTANCE { result = AST::Types::Instance.new(location: val[0].location) }
|
154
|
+
| SELF { result = AST::Types::Self.new(location: val[0].location) }
|
155
|
+
| VOID { result = AST::Types::Void.new(location: val[0].location) }
|
156
|
+
| NIL { result = AST::Types::Name.new_instance(name: ModuleName.new(name: "NilClass", absolute: true),
|
157
|
+
location: val[0].location) }
|
158
|
+
|
159
|
+
instance_type_name: module_name {
|
160
|
+
result = LocatedValue.new(value: TypeName::Instance.new(name: val[0].value),
|
161
|
+
location: val[0].location)
|
162
|
+
}
|
163
|
+
| INTERFACE_NAME {
|
164
|
+
result = LocatedValue.new(value: TypeName::Interface.new(name: val[0].value),
|
165
|
+
location: val[0].location)
|
166
|
+
}
|
167
|
+
|
168
|
+
type_name: instance_type_name
|
169
|
+
| module_name DOT CLASS constructor {
|
170
|
+
loc = val[0].location + (val[3] || val[2]).location
|
171
|
+
result = LocatedValue.new(value: TypeName::Class.new(name: val[0].value, constructor: val[3]&.value),
|
172
|
+
location: loc)
|
173
|
+
}
|
174
|
+
| module_name DOT MODULE {
|
175
|
+
loc = val[0].location + val.last.location
|
176
|
+
result = LocatedValue.new(value: TypeName::Module.new(name: val[0].value),
|
177
|
+
location: loc)
|
178
|
+
}
|
75
179
|
|
76
180
|
constructor: { result = nil }
|
77
181
|
| CONSTRUCTOR
|
78
182
|
| NOCONSTRUCTOR
|
79
183
|
|
80
184
|
type: simple_type
|
81
|
-
| union_seq {
|
185
|
+
| union_seq {
|
186
|
+
loc = val[0].first.location + val[0].last.location
|
187
|
+
result = AST::Types::Union.build(types: val[0], location: loc)
|
188
|
+
}
|
82
189
|
|
83
190
|
type_seq: type { result = [val[0]] }
|
84
191
|
| type COMMA type_seq { result = [val[0]] + val[2] }
|
@@ -89,62 +196,195 @@ union_seq: simple_type BAR simple_type { result = [val[0], val[2]] }
|
|
89
196
|
keyword: IDENT
|
90
197
|
| MODULE_NAME
|
91
198
|
| INTERFACE_NAME
|
92
|
-
| ANY
|
93
|
-
| CLASS
|
94
|
-
| MODULE
|
95
|
-
| INSTANCE
|
96
|
-
| BLOCK
|
97
|
-
| INCLUDE
|
199
|
+
| ANY
|
200
|
+
| CLASS
|
201
|
+
| MODULE
|
202
|
+
| INSTANCE
|
203
|
+
| BLOCK
|
204
|
+
| INCLUDE
|
98
205
|
|
99
206
|
signatures: { result = [] }
|
100
207
|
| interface signatures { result = [val[0]] + val[1] }
|
101
208
|
| class_decl signatures { result = [val[0]] + val[1] }
|
102
209
|
| module_decl signatures { result = [val[0]] + val[1] }
|
103
210
|
| extension_decl signatures { result = [val[0]] + val[1] }
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
211
|
+
| const_decl signatures { result = [val[0]] + val[1] }
|
212
|
+
| gvar_decl signatures { result = [val[0]] + val[1] }
|
213
|
+
|
214
|
+
gvar_decl: GVAR COLON type {
|
215
|
+
loc = val.first.location + val.last.location
|
216
|
+
result = AST::Signature::Gvar.new(
|
217
|
+
location: loc,
|
218
|
+
name: val[0].value,
|
219
|
+
type: val[2]
|
220
|
+
)
|
221
|
+
}
|
222
|
+
|
223
|
+
const_decl: module_name COLON type {
|
224
|
+
loc = val.first.location + val.last.location
|
225
|
+
result = AST::Signature::Const.new(
|
226
|
+
location: loc,
|
227
|
+
name: val[0].value,
|
228
|
+
type: val[2]
|
229
|
+
)
|
230
|
+
}
|
231
|
+
|
232
|
+
interface: INTERFACE interface_name type_params interface_members END {
|
233
|
+
loc = val.first.location + val.last.location
|
234
|
+
result = AST::Signature::Interface.new(
|
235
|
+
location: loc,
|
236
|
+
name: val[1].value,
|
237
|
+
params: val[2],
|
238
|
+
methods: val[3]
|
239
|
+
)
|
240
|
+
}
|
241
|
+
|
242
|
+
class_decl: CLASS module_name type_params super_opt class_members END {
|
243
|
+
loc = val.first.location + val.last.location
|
244
|
+
result = AST::Signature::Class.new(name: val[1].value.absolute!,
|
245
|
+
params: val[2],
|
246
|
+
super_class: val[3],
|
247
|
+
members: val[4],
|
248
|
+
location: loc)
|
249
|
+
}
|
250
|
+
module_decl: MODULE module_name type_params self_type_opt class_members END {
|
251
|
+
loc = val.first.location + val.last.location
|
252
|
+
result = AST::Signature::Module.new(name: val[1].value.absolute!,
|
253
|
+
location: loc,
|
254
|
+
params: val[2],
|
255
|
+
self_type: val[3],
|
256
|
+
members: val[4])
|
257
|
+
}
|
258
|
+
extension_decl: EXTENSION module_name type_params LPAREN UIDENT RPAREN class_members END {
|
259
|
+
loc = val.first.location + val.last.location
|
260
|
+
result = AST::Signature::Extension.new(module_name: val[1].value.absolute!,
|
261
|
+
name: val[4].value,
|
262
|
+
location: loc,
|
263
|
+
params: val[2],
|
264
|
+
members: val[6])
|
265
|
+
}
|
109
266
|
|
110
267
|
self_type_opt: { result = nil }
|
111
268
|
| COLON type { result = val[1] }
|
112
269
|
|
113
|
-
interface_name: INTERFACE_NAME
|
270
|
+
interface_name: INTERFACE_NAME
|
271
|
+
|
272
|
+
module_name: module_name0
|
273
|
+
| COLON2 module_name0 {
|
274
|
+
loc = val.first.location + val.last.location
|
275
|
+
result = LocatedValue.new(location: loc, value: val[1].value.absolute!)
|
276
|
+
}
|
114
277
|
|
115
|
-
|
278
|
+
module_name0: UIDENT {
|
279
|
+
result = LocatedValue.new(location: val[0].location, value: ModuleName.parse(val[0].value))
|
280
|
+
}
|
281
|
+
| UIDENT COLON2 module_name0 {
|
282
|
+
location = val[0].location + val.last.location
|
283
|
+
name = ModuleName.parse(val[0].value) + val.last.value
|
284
|
+
result = LocatedValue.new(location: location, value: name)
|
285
|
+
}
|
116
286
|
|
117
287
|
class_members: { result = [] }
|
118
288
|
| class_member class_members { result = [val[0]] + val[1] }
|
119
289
|
|
120
|
-
class_member: instance_method_member
|
121
|
-
|
|
122
|
-
|
|
123
|
-
| include_member
|
124
|
-
| extend_member
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
290
|
+
class_member: instance_method_member
|
291
|
+
| module_method_member
|
292
|
+
| module_instance_method_member
|
293
|
+
| include_member
|
294
|
+
| extend_member
|
295
|
+
| ivar_member
|
296
|
+
|
297
|
+
ivar_member: IVAR_NAME COLON type {
|
298
|
+
loc = val.first.location + val.last.location
|
299
|
+
result = AST::Signature::Members::Ivar.new(
|
300
|
+
location: loc,
|
301
|
+
name: val[0].value,
|
302
|
+
type: val[2]
|
303
|
+
)
|
304
|
+
}
|
305
|
+
|
306
|
+
instance_method_member: DEF constructor_method method_name COLON method_type_union {
|
307
|
+
loc = val.first.location + val.last.last.location
|
308
|
+
result = AST::Signature::Members::Method.new(
|
309
|
+
name: val[2].value,
|
310
|
+
types: val[4],
|
311
|
+
kind: :instance,
|
312
|
+
location: loc,
|
313
|
+
attributes: [val[1] ? :constructor : nil].compact
|
314
|
+
)
|
315
|
+
}
|
316
|
+
module_method_member: DEF constructor_method SELF DOT method_name COLON method_type_union {
|
317
|
+
loc = val.first.location + val.last.last.location
|
318
|
+
result = AST::Signature::Members::Method.new(
|
319
|
+
name: val[4].value,
|
320
|
+
types: val[6],
|
321
|
+
kind: :module,
|
322
|
+
location: loc,
|
323
|
+
attributes: [val[1] ? :constructor : nil].compact
|
324
|
+
)
|
325
|
+
}
|
326
|
+
module_instance_method_member: DEF constructor_method SELFQ DOT method_name COLON method_type_union {
|
327
|
+
loc = val.first.location + val.last.last.location
|
328
|
+
result = AST::Signature::Members::Method.new(
|
329
|
+
name: val[4].value,
|
330
|
+
types: val[6],
|
331
|
+
kind: :module_instance,
|
332
|
+
location: loc,
|
333
|
+
attributes: [val[1] ? :constructor : nil].compact
|
334
|
+
)
|
335
|
+
}
|
336
|
+
include_member: INCLUDE module_name {
|
337
|
+
loc = val.first.location + val.last.location
|
338
|
+
name = val[1].value
|
339
|
+
result = AST::Signature::Members::Include.new(name: name, location: loc, args: [])
|
340
|
+
}
|
341
|
+
| INCLUDE module_name LT type_seq GT {
|
342
|
+
loc = val.first.location + val.last.location
|
343
|
+
name = val[1].value
|
344
|
+
result = AST::Signature::Members::Include.new(name: name, location: loc, args: val[3])
|
345
|
+
}
|
346
|
+
extend_member: EXTEND module_name {
|
347
|
+
loc = val.first.location + val.last.location
|
348
|
+
name = val[1].value
|
349
|
+
result = AST::Signature::Members::Extend.new(name: name, location: loc, args: [])
|
350
|
+
}
|
351
|
+
| EXTEND module_name LT type_seq GT {
|
352
|
+
loc = val.first.location + val.last.location
|
353
|
+
name = val[1].value
|
354
|
+
result = AST::Signature::Members::Extend.new(name: name, location: loc, args: val[3])
|
355
|
+
}
|
131
356
|
|
132
357
|
constructor_method: { result = false }
|
133
358
|
| LPAREN CONSTRUCTOR RPAREN { result = true }
|
134
359
|
|
135
360
|
super_opt: { result = nil }
|
136
|
-
| LTCOLON
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
361
|
+
| LTCOLON super_class { result = val[1] }
|
362
|
+
|
363
|
+
super_class: module_name {
|
364
|
+
result = AST::Signature::SuperClass.new(location: val[0].location, name: val[0].value, args: [])
|
365
|
+
}
|
366
|
+
| module_name LT type_seq GT {
|
367
|
+
loc = val[0].location + val[3].location
|
368
|
+
name = val[0].value
|
369
|
+
result = AST::Signature::SuperClass.new(location: loc, name: name, args: val[2])
|
370
|
+
}
|
371
|
+
|
372
|
+
type_params: { result = nil }
|
373
|
+
| LT type_param_seq GT {
|
374
|
+
location = val[0].location + val[2].location
|
375
|
+
result = AST::TypeParams.new(location: location, variables: val[1])
|
376
|
+
}
|
377
|
+
|
378
|
+
type_param_seq: TVAR { result = [val[0].value] }
|
379
|
+
| TVAR COMMA type_param_seq { result = [val[0].value] + val[2] }
|
380
|
+
|
381
|
+
interface_members: { result = [] }
|
382
|
+
| interface_method interface_members { result = val[1].unshift(val[0]) }
|
383
|
+
|
384
|
+
interface_method: DEF method_name COLON method_type_union {
|
385
|
+
loc = val[0].location + val[3].last.location
|
386
|
+
result = AST::Signature::Interface::Method.new(location: loc, name: val[1].value, types: val[3])
|
387
|
+
}
|
148
388
|
|
149
389
|
method_type_union: method_type { result = [val[0]] }
|
150
390
|
| method_type BAR method_type_union { result = [val[0]] + val[2] }
|
@@ -152,34 +392,107 @@ method_type_union: method_type { result = [val[0]] }
|
|
152
392
|
method_name: IDENT
|
153
393
|
| MODULE_NAME
|
154
394
|
| INTERFACE_NAME
|
155
|
-
| ANY
|
156
|
-
| INTERFACE
|
157
|
-
| END
|
158
|
-
| PLUS
|
159
|
-
| CLASS
|
160
|
-
| MODULE
|
161
|
-
| INSTANCE
|
395
|
+
| ANY | VOID
|
396
|
+
| INTERFACE
|
397
|
+
| END
|
398
|
+
| PLUS
|
399
|
+
| CLASS
|
400
|
+
| MODULE
|
401
|
+
| INSTANCE
|
402
|
+
| EXTEND
|
403
|
+
| INCLUDE
|
162
404
|
| OPERATOR
|
163
405
|
| METHOD_NAME
|
164
|
-
| BLOCK
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
406
|
+
| BLOCK
|
407
|
+
| UIDENT
|
408
|
+
| BREAK
|
409
|
+
| STAR | STAR2
|
410
|
+
| PERCENT | MINUS
|
411
|
+
| LT | GT
|
412
|
+
| METHOD
|
413
|
+
| BAR { result = LocatedValue.new(location: val[0].location, value: :|) }
|
414
|
+
| CONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: :constructor) }
|
415
|
+
| NOCONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: :noconstructor) }
|
416
|
+
| ANY QUESTION {
|
417
|
+
raise ParseError, "\nunexpected method name any ?" unless val[0].location.pred?(val[1].location)
|
418
|
+
result = LocatedValue.new(location: val[0].location + val[1].location, value: :any?)
|
419
|
+
}
|
420
|
+
| GT GT {
|
421
|
+
raise ParseError, "\nunexpected method name > >" unless val[0].location.pred?(val[1].location)
|
422
|
+
result = LocatedValue.new(location: val[0].location + val[1].location, value: :>>)
|
423
|
+
}
|
424
|
+
|
425
|
+
annotation: AT_TYPE VAR subject COLON type {
|
426
|
+
loc = val.first.location + val.last.location
|
427
|
+
result = AST::Annotation::VarType.new(location: loc,
|
428
|
+
name: val[2].value,
|
429
|
+
type: val[4])
|
430
|
+
}
|
431
|
+
| AT_TYPE METHOD subject COLON method_type {
|
432
|
+
loc = val.first.location + val.last.location
|
433
|
+
result = AST::Annotation::MethodType.new(location: loc,
|
434
|
+
name: val[2].value,
|
435
|
+
type: val[4])
|
436
|
+
}
|
437
|
+
| AT_TYPE RETURN COLON type {
|
438
|
+
loc = val.first.location + val.last.location
|
439
|
+
result = AST::Annotation::ReturnType.new(type: val[3], location: loc)
|
440
|
+
}
|
441
|
+
| AT_TYPE BLOCK COLON type {
|
442
|
+
loc = val.first.location + val.last.location
|
443
|
+
result = AST::Annotation::BlockType.new(type: val[3], location: loc)
|
444
|
+
}
|
445
|
+
| AT_TYPE SELF COLON type {
|
446
|
+
loc = val.first.location + val.last.location
|
447
|
+
result = AST::Annotation::SelfType.new(type: val[3], location: loc)
|
448
|
+
}
|
449
|
+
| AT_TYPE CONST module_name COLON type {
|
450
|
+
loc = val.first.location + val.last.location
|
451
|
+
result = AST::Annotation::ConstType.new(name: val[2].value,
|
452
|
+
type: val[4],
|
453
|
+
location: loc)
|
454
|
+
}
|
455
|
+
| AT_TYPE INSTANCE COLON type {
|
456
|
+
loc = val.first.location + val.last.location
|
457
|
+
result = AST::Annotation::InstanceType.new(type: val[3], location: loc)
|
458
|
+
}
|
459
|
+
| AT_TYPE MODULE COLON type {
|
460
|
+
loc = val.first.location + val.last.location
|
461
|
+
result = AST::Annotation::ModuleType.new(type: val[3], location: loc)
|
462
|
+
}
|
463
|
+
| AT_TYPE IVAR IVAR_NAME COLON type {
|
464
|
+
loc = val.first.location + val.last.location
|
465
|
+
result = AST::Annotation::IvarType.new(name: val[2].value, type: val[4], location: loc)
|
466
|
+
}
|
467
|
+
| AT_IMPLEMENTS module_name type_params {
|
468
|
+
loc = val[0].location + (val[2]&.location || val[1].location)
|
469
|
+
args = val[2]&.variables || []
|
470
|
+
name = AST::Annotation::Implements::Module.new(name: val[1].value, args: args)
|
471
|
+
result = AST::Annotation::Implements.new(name: name, location: loc)
|
472
|
+
}
|
473
|
+
| AT_DYNAMIC dynamic_names {
|
474
|
+
loc = val[0].location + val[1].last.location
|
475
|
+
result = AST::Annotation::Dynamic.new(names: val[1], location: loc)
|
476
|
+
}
|
477
|
+
| AT_TYPE BREAK COLON type {
|
478
|
+
loc = val.first.location + val.last.location
|
479
|
+
result = AST::Annotation::BreakType.new(type: val[3], location: loc)
|
480
|
+
}
|
481
|
+
|
482
|
+
dynamic_names: dynamic_name COMMA dynamic_names { result = [val[0]] + val[2] }
|
483
|
+
| dynamic_name { result = val }
|
484
|
+
|
485
|
+
dynamic_name: method_name {
|
486
|
+
result = AST::Annotation::Dynamic::Name.new(name: val[0].value, location: val[0].location, kind: :instance)
|
487
|
+
}
|
488
|
+
| SELF DOT method_name {
|
489
|
+
loc = val.first.location + val.last.location
|
490
|
+
result = AST::Annotation::Dynamic::Name.new(name: val[2].value, location: loc, kind: :module)
|
491
|
+
}
|
492
|
+
| SELFQ DOT method_name {
|
493
|
+
loc = val.first.location + val.last.location
|
494
|
+
result = AST::Annotation::Dynamic::Name.new(name: val[2].value, location: loc, kind: :module_instance)
|
495
|
+
}
|
183
496
|
|
184
497
|
subject: IDENT { result = val[0] }
|
185
498
|
|
@@ -190,27 +503,53 @@ end
|
|
190
503
|
require "strscan"
|
191
504
|
|
192
505
|
attr_reader :input
|
506
|
+
attr_reader :buffer
|
507
|
+
attr_reader :offset
|
193
508
|
|
194
|
-
def initialize(type, input)
|
509
|
+
def initialize(type, buffer:, offset:, input: nil)
|
195
510
|
super()
|
196
511
|
@type = type
|
197
|
-
@
|
512
|
+
@buffer = buffer
|
513
|
+
@input = StringScanner.new(input || buffer.content)
|
514
|
+
@offset = offset
|
198
515
|
end
|
199
516
|
|
200
|
-
def self.parse_method(input)
|
201
|
-
new(:METHOD, input).do_parse
|
517
|
+
def self.parse_method(input, name: nil)
|
518
|
+
new(:METHOD, buffer: AST::Buffer.new(name: name, content: input), offset: 0).do_parse
|
202
519
|
end
|
203
520
|
|
204
|
-
def self.parse_signature(input)
|
205
|
-
new(:SIGNATURE, input).do_parse
|
521
|
+
def self.parse_signature(input, name: nil)
|
522
|
+
new(:SIGNATURE, buffer: AST::Buffer.new(name: name, content: input), offset: 0).do_parse
|
206
523
|
end
|
207
524
|
|
208
|
-
def self.parse_annotation_opt(input)
|
209
|
-
new(:ANNOTATION, input).do_parse
|
210
|
-
rescue
|
525
|
+
def self.parse_annotation_opt(input, buffer:, offset: 0)
|
526
|
+
new(:ANNOTATION, input: input, buffer: buffer, offset: offset).do_parse
|
527
|
+
rescue => exn
|
528
|
+
Steep.logger.debug "Parsing comment failed: #{exn.inspect}"
|
211
529
|
nil
|
212
530
|
end
|
213
531
|
|
532
|
+
class LocatedValue
|
533
|
+
attr_reader :location
|
534
|
+
attr_reader :value
|
535
|
+
|
536
|
+
def initialize(location:, value:)
|
537
|
+
@location = location
|
538
|
+
@value = value
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
def new_token(type, value = nil)
|
543
|
+
start_index = offset + input.pos - input.matched.bytesize
|
544
|
+
end_index = offset + input.pos
|
545
|
+
|
546
|
+
location = AST::Location.new(buffer: buffer,
|
547
|
+
start_pos: start_index,
|
548
|
+
end_pos: end_index)
|
549
|
+
|
550
|
+
[type, LocatedValue.new(location: location, value: value)]
|
551
|
+
end
|
552
|
+
|
214
553
|
def next_token
|
215
554
|
if @type
|
216
555
|
type = @type
|
@@ -226,104 +565,126 @@ def next_token
|
|
226
565
|
when input.eos?
|
227
566
|
[false, false]
|
228
567
|
when input.scan(/->/)
|
229
|
-
|
568
|
+
new_token(:ARROW)
|
230
569
|
when input.scan(/\?/)
|
231
|
-
|
570
|
+
new_token(:QUESTION)
|
232
571
|
when input.scan(/\(/)
|
233
|
-
|
572
|
+
new_token(:LPAREN, nil)
|
234
573
|
when input.scan(/\)/)
|
235
|
-
|
574
|
+
new_token(:RPAREN, nil)
|
236
575
|
when input.scan(/{/)
|
237
|
-
|
576
|
+
new_token(:LBRACE, nil)
|
238
577
|
when input.scan(/}/)
|
239
|
-
|
578
|
+
new_token(:RBRACE, nil)
|
240
579
|
when input.scan(/,/)
|
241
|
-
|
242
|
-
when input.scan(
|
243
|
-
|
244
|
-
when input.scan(/::[A-Z]\w*(::[A-Z]\w*)*/)
|
245
|
-
[:CONST_PATH, input.matched.to_sym]
|
580
|
+
new_token(:COMMA, nil)
|
581
|
+
when input.scan(/::/)
|
582
|
+
new_token(:COLON2)
|
246
583
|
when input.scan(/:/)
|
247
|
-
|
584
|
+
new_token(:COLON)
|
248
585
|
when input.scan(/\*\*/)
|
249
|
-
|
586
|
+
new_token(:STAR2, :**)
|
250
587
|
when input.scan(/\*/)
|
251
|
-
|
588
|
+
new_token(:STAR, :*)
|
252
589
|
when input.scan(/\+/)
|
253
|
-
|
590
|
+
new_token(:PLUS, :+)
|
254
591
|
when input.scan(/\./)
|
255
|
-
|
592
|
+
new_token(:DOT)
|
256
593
|
when input.scan(/<:/)
|
257
|
-
|
594
|
+
new_token(:LTCOLON)
|
258
595
|
when input.scan(/(\[\]=)|(\[\])|===|==|\^|!=|<</)
|
259
|
-
|
596
|
+
new_token(:OPERATOR, input.matched.to_sym)
|
597
|
+
when input.scan(/<=/)
|
598
|
+
new_token(:OPERATOR, :<=)
|
599
|
+
when input.scan(/>=/)
|
600
|
+
new_token(:OPERATOR, :>=)
|
260
601
|
when input.scan(/</)
|
261
|
-
|
602
|
+
new_token(:LT, :<)
|
262
603
|
when input.scan(/>/)
|
263
|
-
|
604
|
+
new_token(:GT, :>)
|
605
|
+
when input.scan(/nil\b/)
|
606
|
+
new_token(:NIL, :nil)
|
264
607
|
when input.scan(/any\b/)
|
265
|
-
|
608
|
+
new_token(:ANY, :any)
|
609
|
+
when input.scan(/void\b/)
|
610
|
+
new_token(:VOID, :void)
|
266
611
|
when input.scan(/interface\b/)
|
267
|
-
|
612
|
+
new_token(:INTERFACE, :interface)
|
268
613
|
when input.scan(/end\b/)
|
269
|
-
|
614
|
+
new_token(:END, :end)
|
270
615
|
when input.scan(/\|/)
|
271
|
-
|
616
|
+
new_token(:BAR, :bar)
|
272
617
|
when input.scan(/def\b/)
|
273
|
-
|
618
|
+
new_token(:DEF)
|
274
619
|
when input.scan(/@type\b/)
|
275
|
-
|
620
|
+
new_token(:AT_TYPE)
|
276
621
|
when input.scan(/@implements\b/)
|
277
|
-
|
622
|
+
new_token(:AT_IMPLEMENTS)
|
278
623
|
when input.scan(/@dynamic\b/)
|
279
|
-
|
624
|
+
new_token(:AT_DYNAMIC)
|
280
625
|
when input.scan(/const\b/)
|
281
|
-
|
626
|
+
new_token(:CONST, :const)
|
282
627
|
when input.scan(/var\b/)
|
283
|
-
|
628
|
+
new_token(:VAR, :var)
|
284
629
|
when input.scan(/return\b/)
|
285
|
-
|
630
|
+
new_token(:RETURN)
|
286
631
|
when input.scan(/block\b/)
|
287
|
-
|
632
|
+
new_token(:BLOCK, :block)
|
633
|
+
when input.scan(/break\b/)
|
634
|
+
new_token(:BREAK, :break)
|
288
635
|
when input.scan(/method\b/)
|
289
|
-
|
636
|
+
new_token(:METHOD, :method)
|
290
637
|
when input.scan(/self\?/)
|
291
|
-
|
638
|
+
new_token(:SELFQ)
|
292
639
|
when input.scan(/self\b/)
|
293
|
-
|
640
|
+
new_token(:SELF, :self)
|
294
641
|
when input.scan(/'\w+/)
|
295
|
-
|
642
|
+
new_token(:TVAR, input.matched.gsub(/\A'/, '').to_sym)
|
296
643
|
when input.scan(/instance\b/)
|
297
|
-
|
644
|
+
new_token(:INSTANCE, :instance)
|
298
645
|
when input.scan(/class\b/)
|
299
|
-
|
646
|
+
new_token(:CLASS, :class)
|
300
647
|
when input.scan(/module\b/)
|
301
|
-
|
648
|
+
new_token(:MODULE, :module)
|
649
|
+
when input.scan(/include\?/)
|
650
|
+
new_token(:METHOD_NAME, :include?)
|
302
651
|
when input.scan(/include\b/)
|
303
|
-
|
652
|
+
new_token(:INCLUDE, :include)
|
304
653
|
when input.scan(/extend\b/)
|
305
|
-
|
654
|
+
new_token(:EXTEND, :extend)
|
306
655
|
when input.scan(/instance\b/)
|
307
|
-
|
656
|
+
new_token(:INSTANCE, :instance)
|
308
657
|
when input.scan(/ivar\b/)
|
309
|
-
|
658
|
+
new_token(:IVAR, :ivar)
|
659
|
+
when input.scan(/%/)
|
660
|
+
new_token(:PERCENT, :%)
|
661
|
+
when input.scan(/-/)
|
662
|
+
new_token(:MINUS, :-)
|
663
|
+
when input.scan(/&/)
|
664
|
+
new_token(:OPERATOR, :&)
|
665
|
+
when input.scan(/~/)
|
666
|
+
new_token(:OPERATOR, :~)
|
667
|
+
when input.scan(/\//)
|
668
|
+
new_token(:OPERATOR, :/)
|
669
|
+
when input.scan(/!/)
|
670
|
+
new_token(:OPERATOR, :!)
|
310
671
|
when input.scan(/extension\b/)
|
311
|
-
|
672
|
+
new_token(:EXTENSION, :extension)
|
312
673
|
when input.scan(/constructor\b/)
|
313
|
-
|
674
|
+
new_token(:CONSTRUCTOR, true)
|
314
675
|
when input.scan(/noconstructor\b/)
|
315
|
-
|
316
|
-
when input.scan(
|
317
|
-
|
318
|
-
when input.scan(
|
319
|
-
|
676
|
+
new_token(:NOCONSTRUCTOR, false)
|
677
|
+
when input.scan(/\w+(\!|\?|=)/)
|
678
|
+
new_token(:METHOD_NAME, input.matched.to_sym)
|
679
|
+
when input.scan(/\$\w+\b/)
|
680
|
+
new_token(:GVAR, input.matched.to_sym)
|
320
681
|
when input.scan(/[A-Z]\w*/)
|
321
|
-
|
682
|
+
new_token(:UIDENT, input.matched.to_sym)
|
322
683
|
when input.scan(/_\w+/)
|
323
|
-
|
324
|
-
when input.scan(
|
325
|
-
|
684
|
+
new_token(:INTERFACE_NAME, input.matched.to_sym)
|
685
|
+
when input.scan(/@\w+/)
|
686
|
+
new_token(:IVAR_NAME, input.matched.to_sym)
|
326
687
|
when input.scan(/\w+/)
|
327
|
-
|
688
|
+
new_token(:IDENT, input.matched.to_sym)
|
328
689
|
end
|
329
690
|
end
|