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.
Files changed (119) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +1 -1
  3. data/README.md +146 -33
  4. data/bin/smoke_runner.rb +43 -10
  5. data/lib/steep/ast/annotation/collection.rb +93 -0
  6. data/lib/steep/ast/annotation.rb +131 -0
  7. data/lib/steep/ast/buffer.rb +47 -0
  8. data/lib/steep/ast/location.rb +82 -0
  9. data/lib/steep/ast/method_type.rb +116 -0
  10. data/lib/steep/ast/signature/class.rb +33 -0
  11. data/lib/steep/ast/signature/const.rb +17 -0
  12. data/lib/steep/ast/signature/env.rb +123 -0
  13. data/lib/steep/ast/signature/extension.rb +21 -0
  14. data/lib/steep/ast/signature/gvar.rb +17 -0
  15. data/lib/steep/ast/signature/interface.rb +31 -0
  16. data/lib/steep/ast/signature/members.rb +71 -0
  17. data/lib/steep/ast/signature/module.rb +21 -0
  18. data/lib/steep/ast/type_params.rb +13 -0
  19. data/lib/steep/ast/types/any.rb +39 -0
  20. data/lib/steep/ast/types/bot.rb +39 -0
  21. data/lib/steep/ast/types/class.rb +35 -0
  22. data/lib/steep/ast/types/helper.rb +21 -0
  23. data/lib/steep/ast/types/instance.rb +39 -0
  24. data/lib/steep/ast/types/intersection.rb +74 -0
  25. data/lib/steep/ast/types/name.rb +124 -0
  26. data/lib/steep/ast/types/self.rb +39 -0
  27. data/lib/steep/ast/types/top.rb +39 -0
  28. data/lib/steep/ast/types/union.rb +74 -0
  29. data/lib/steep/ast/types/var.rb +57 -0
  30. data/lib/steep/ast/types/void.rb +35 -0
  31. data/lib/steep/cli.rb +28 -1
  32. data/lib/steep/drivers/annotations.rb +32 -0
  33. data/lib/steep/drivers/check.rb +53 -77
  34. data/lib/steep/drivers/scaffold.rb +303 -0
  35. data/lib/steep/drivers/utils/each_signature.rb +66 -0
  36. data/lib/steep/drivers/utils/validator.rb +115 -0
  37. data/lib/steep/drivers/validate.rb +39 -0
  38. data/lib/steep/errors.rb +291 -19
  39. data/lib/steep/interface/abstract.rb +44 -0
  40. data/lib/steep/interface/builder.rb +470 -0
  41. data/lib/steep/interface/instantiated.rb +126 -0
  42. data/lib/steep/interface/ivar_chain.rb +26 -0
  43. data/lib/steep/interface/method.rb +60 -0
  44. data/lib/steep/{interface.rb → interface/method_type.rb} +111 -100
  45. data/lib/steep/interface/substitution.rb +65 -0
  46. data/lib/steep/module_name.rb +116 -0
  47. data/lib/steep/parser.rb +1314 -814
  48. data/lib/steep/parser.y +536 -175
  49. data/lib/steep/source.rb +220 -25
  50. data/lib/steep/subtyping/check.rb +673 -0
  51. data/lib/steep/subtyping/constraints.rb +275 -0
  52. data/lib/steep/subtyping/relation.rb +41 -0
  53. data/lib/steep/subtyping/result.rb +126 -0
  54. data/lib/steep/subtyping/trace.rb +48 -0
  55. data/lib/steep/subtyping/variable_occurrence.rb +49 -0
  56. data/lib/steep/subtyping/variable_variance.rb +69 -0
  57. data/lib/steep/type_construction.rb +1630 -524
  58. data/lib/steep/type_inference/block_params.rb +100 -0
  59. data/lib/steep/type_inference/constant_env.rb +55 -0
  60. data/lib/steep/type_inference/send_args.rb +222 -0
  61. data/lib/steep/type_inference/type_env.rb +226 -0
  62. data/lib/steep/type_name.rb +27 -7
  63. data/lib/steep/typing.rb +4 -0
  64. data/lib/steep/version.rb +1 -1
  65. data/lib/steep.rb +71 -16
  66. data/smoke/and/a.rb +4 -2
  67. data/smoke/array/a.rb +4 -5
  68. data/smoke/array/b.rb +4 -4
  69. data/smoke/block/a.rb +2 -2
  70. data/smoke/block/a.rbi +2 -0
  71. data/smoke/block/b.rb +15 -0
  72. data/smoke/case/a.rb +3 -3
  73. data/smoke/class/a.rb +3 -3
  74. data/smoke/class/b.rb +0 -2
  75. data/smoke/class/d.rb +2 -2
  76. data/smoke/class/e.rb +1 -1
  77. data/smoke/class/f.rb +2 -2
  78. data/smoke/class/g.rb +8 -0
  79. data/smoke/const/a.rb +3 -3
  80. data/smoke/dstr/a.rb +1 -1
  81. data/smoke/ensure/a.rb +22 -0
  82. data/smoke/enumerator/a.rb +6 -6
  83. data/smoke/enumerator/b.rb +22 -0
  84. data/smoke/extension/a.rb +2 -2
  85. data/smoke/extension/b.rb +3 -3
  86. data/smoke/extension/c.rb +1 -1
  87. data/smoke/hello/hello.rb +2 -2
  88. data/smoke/if/a.rb +4 -2
  89. data/smoke/kwbegin/a.rb +8 -0
  90. data/smoke/literal/a.rb +5 -5
  91. data/smoke/method/a.rb +5 -5
  92. data/smoke/method/a.rbi +4 -0
  93. data/smoke/method/b.rb +29 -0
  94. data/smoke/module/a.rb +3 -3
  95. data/smoke/module/a.rbi +9 -0
  96. data/smoke/module/b.rb +2 -2
  97. data/smoke/module/c.rb +1 -1
  98. data/smoke/module/d.rb +5 -0
  99. data/smoke/module/e.rb +13 -0
  100. data/smoke/module/f.rb +13 -0
  101. data/smoke/rescue/a.rb +62 -0
  102. data/smoke/super/a.rb +2 -2
  103. data/smoke/type_case/a.rb +35 -0
  104. data/smoke/yield/a.rb +2 -2
  105. data/stdlib/builtin.rbi +463 -24
  106. data/steep.gemspec +3 -2
  107. metadata +91 -29
  108. data/lib/steep/annotation.rb +0 -223
  109. data/lib/steep/signature/class.rb +0 -450
  110. data/lib/steep/signature/extension.rb +0 -51
  111. data/lib/steep/signature/interface.rb +0 -49
  112. data/lib/steep/types/any.rb +0 -31
  113. data/lib/steep/types/class.rb +0 -27
  114. data/lib/steep/types/instance.rb +0 -27
  115. data/lib/steep/types/merge.rb +0 -32
  116. data/lib/steep/types/name.rb +0 -57
  117. data/lib/steep/types/union.rb +0 -42
  118. data/lib/steep/types/var.rb +0 -38
  119. 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: type_params params block_opt ARROW return_type
10
- { result = Interface::MethodType.new(type_params: val[0], params: val[1], block: val[2], return_type: val[4]) }
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.new(types: val[1]) }
14
-
15
- params: { result = Interface::Params.empty }
16
- | LPAREN params0 RPAREN { result = val[1] }
17
- | type { result = Interface::Params.empty.with(required: [val[0]]) }
18
-
19
- params0: required_param { result = Interface::Params.empty.with(required: [val[0]]) }
20
- | required_param COMMA params0 { result = val[2].with(required: [val[0]] + val[2].required) }
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 = Interface::Params.empty.with(optional: [val[0]]) }
24
- | optional_param COMMA params1 { result = val[2].with(optional: [val[0]] + val[2].optional) }
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 = Interface::Params.empty.with(rest: val[0]) }
28
- | rest_param COMMA params3 { result = val[2].with(rest: val[0]) }
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 { result = Interface::Params.empty.with(required_keywords: val[0]) }
32
- | optional_keyword { result = Interface::Params.empty.with(optional_keywords: val[0]) }
33
- | required_keyword COMMA params3 { result = val[2].with(required_keywords: val[2].required_keywords.merge(val[0])) }
34
- | optional_keyword COMMA params3 { result = val[2].with(optional_keywords: val[2].optional_keywords.merge(val[0])) }
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 = Interface::Params.empty }
38
- | STAR2 type { result = Interface::Params.empty.with(rest_keywords: val[1]) }
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
- rest_param: STAR type { result = val[1] }
43
- required_keyword: keyword COLON type { result = { val[0] => val[2] } }
44
- optional_keyword: QUESTION keyword COLON type { result = { val[1] => val[3] } }
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 { result = Interface::Block.new(params: Interface::Params.empty.with(rest: Types::Any.new),
48
- return_type: Types::Any.new) }
49
- | LBRACE block_params ARROW type RBRACE { result = Interface::Block.new(params: val[1], return_type: val[3]) }
50
-
51
- block_params: LPAREN block_params0 RPAREN { result = val[1] }
52
- | { result = Interface::Params.empty.with(rest: Types::Any.new) }
53
-
54
- block_params0: required_param { result = Interface::Params.empty.with(required: [val[0]]) }
55
- | required_param COMMA block_params0 { result = val[2].with(required: [val[0]] + val[2].required) }
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 { result = Interface::Params.empty.with(optional: [val[0]]) }
59
- | optional_param COMMA block_params1 { result = val[2].with(optional: [val[0]] + val[2].optional) }
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 = Interface::Params.empty }
63
- | rest_param { result = Interface::Params.empty.with(rest: val[0]) }
64
-
65
- simple_type: INTERFACE_NAME { result = Types::Name.interface(name: val[0]) }
66
- | INTERFACE_NAME LT type_seq GT { result = Types::Name.interface(name: val[0], params: val[2]) }
67
- | MODULE_NAME { result = Types::Name.instance(name: val[0])}
68
- | MODULE_NAME LT type_seq GT { result = Types::Name.instance(name: val[0], params: val[2]) }
69
- | CLASS_IDENT constructor { result = Types::Name.module(name: val[0], constructor: val[1]) }
70
- | ANY { result = Types::Any.new }
71
- | TVAR { result = Types::Var.new(name: val[0]) }
72
- | CLASS { result = Types::Class.new }
73
- | MODULE { result = Types::Class.new }
74
- | INSTANCE { result = Types::Instance.new }
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 { result = Types::Union.new(types: val[0]) }
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 { result = :any }
93
- | CLASS { result = :class }
94
- | MODULE { result = :module }
95
- | INSTANCE { result = :instance }
96
- | BLOCK { result = :block }
97
- | INCLUDE { result = :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
- interface: INTERFACE interface_name type_params method_decls END { result = Signature::Interface.new(name: val[1], params: val[2], methods: val[3]) }
106
- class_decl: CLASS class_name type_params super_opt class_members END { result = Signature::Class.new(name: val[1], params: val[2], super_class: val[3], members: val[4] )}
107
- module_decl: MODULE class_name type_params self_type_opt class_members END { result = Signature::Module.new(name: val[1], params: val[2], self_type: val[3], members: val[4]) }
108
- extension_decl: EXTENSION class_name LPAREN class_name RPAREN class_members END { result = Signature::Extension.new(module_name: val[1], extension_name: val[3], members: val[5]) }
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 { result = val[0] }
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
- class_name: MODULE_NAME { result = val[0] }
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 { result = val[0] }
121
- | class_method_member { result = val[0] }
122
- | class_instance_method_member { result = val[0] }
123
- | include_member { result = val[0] }
124
- | extend_member { result = val[0] }
125
-
126
- instance_method_member: DEF constructor_method method_name COLON method_type_union { result = Signature::Members::InstanceMethod.new(name: val[2], types: val[4], constructor: val[1]) }
127
- class_method_member: DEF constructor_method SELF DOT method_name COLON method_type_union { result = Signature::Members::ModuleMethod.new(name: val[4], types: val[6], constructor: val[1]) }
128
- class_instance_method_member: DEF constructor_method SELFQ DOT method_name COLON method_type_union { result = Signature::Members::ModuleInstanceMethod.new(name: val[4], types: val[6], constructor: val[1]) }
129
- include_member: INCLUDE type { result = Signature::Members::Include.new(name: val[1]) }
130
- extend_member: EXTEND type { result = Signature::Members::Extend.new(name: val[1]) }
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 type { result = val[1] }
137
-
138
- type_params: { result = [] }
139
- | LT type_param_seq GT { result = val[1] }
140
-
141
- type_param_seq: TVAR { result = [val[0]] }
142
- | TVAR COMMA type_param_seq { result = [val[0]] + val[2] }
143
-
144
- method_decls: { result = {} }
145
- | method_decl method_decls { result = val[1].merge(val[0]) }
146
-
147
- method_decl: DEF method_name COLON method_type_union { result = { val[1] => val[3] }}
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 { result = :any }
156
- | INTERFACE { result = :interface }
157
- | END { result = :end }
158
- | PLUS { result = :+ }
159
- | CLASS { result = :class }
160
- | MODULE { result = :module }
161
- | INSTANCE { result = :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 { result = :block }
165
- | INCLUDE { result = :include }
166
- | CONSTRUCTOR { result = :constructor }
167
- | NOCONSTRUCTOR { result = :noconstructor }
168
- | GT GT { result = :>> }
169
-
170
- annotation: AT_TYPE VAR subject COLON type { result = Annotation::VarType.new(var: val[2], type: val[4]) }
171
- | AT_TYPE METHOD subject COLON method_type { result = Annotation::MethodType.new(method: val[2], type: val[4]) }
172
- | AT_TYPE RETURN COLON type { result = Annotation::ReturnType.new(type: val[3]) }
173
- | AT_TYPE BLOCK COLON type { result = Annotation::BlockType.new(type: val[3]) }
174
- | AT_TYPE SELF COLON type { result = Annotation::SelfType.new(type: val[3]) }
175
- | AT_TYPE CONST CONST_PATH COLON type { result = Annotation::ConstType.new(name: val[2], type: val[4]) }
176
- | AT_TYPE CONST MODULE_NAME COLON type { result = Annotation::ConstType.new(name: val[2], type: val[4]) }
177
- | AT_TYPE INSTANCE COLON type { result = Annotation::InstanceType.new(type: val[3]) }
178
- | AT_TYPE MODULE COLON type { result = Annotation::ModuleType.new(type: val[3]) }
179
- | AT_TYPE IVAR IVAR_NAME COLON type { result = Annotation::IvarType.new(name: val[2], type: val[4]) }
180
- | AT_TYPE { raise "Invalid type annotation" }
181
- | AT_IMPLEMENTS MODULE_NAME { result = Annotation::Implements.new(module_name: val[1]) }
182
- | AT_DYNAMIC method_name { result = Annotation::Dynamic.new(name: val[1]) }
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
- @input = StringScanner.new(input)
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
- [:ARROW, nil]
568
+ new_token(:ARROW)
230
569
  when input.scan(/\?/)
231
- [:QUESTION, nil]
570
+ new_token(:QUESTION)
232
571
  when input.scan(/\(/)
233
- [:LPAREN, nil]
572
+ new_token(:LPAREN, nil)
234
573
  when input.scan(/\)/)
235
- [:RPAREN, nil]
574
+ new_token(:RPAREN, nil)
236
575
  when input.scan(/{/)
237
- [:LBRACE, nil]
576
+ new_token(:LBRACE, nil)
238
577
  when input.scan(/}/)
239
- [:RBRACE, nil]
578
+ new_token(:RBRACE, nil)
240
579
  when input.scan(/,/)
241
- [:COMMA, nil]
242
- when input.scan(/[A-Z]\w*(::[A-Z]\w*)+/)
243
- [:CONST_PATH, input.matched.to_sym]
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
- [:COLON, nil]
584
+ new_token(:COLON)
248
585
  when input.scan(/\*\*/)
249
- [:STAR2, nil]
586
+ new_token(:STAR2, :**)
250
587
  when input.scan(/\*/)
251
- [:STAR, nil]
588
+ new_token(:STAR, :*)
252
589
  when input.scan(/\+/)
253
- [:PLUS, nil]
590
+ new_token(:PLUS, :+)
254
591
  when input.scan(/\./)
255
- [:DOT, nil]
592
+ new_token(:DOT)
256
593
  when input.scan(/<:/)
257
- [:LTCOLON, nil]
594
+ new_token(:LTCOLON)
258
595
  when input.scan(/(\[\]=)|(\[\])|===|==|\^|!=|<</)
259
- [:OPERATOR, input.matched.to_sym]
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
- [:LT, nil]
602
+ new_token(:LT, :<)
262
603
  when input.scan(/>/)
263
- [:GT, nil]
604
+ new_token(:GT, :>)
605
+ when input.scan(/nil\b/)
606
+ new_token(:NIL, :nil)
264
607
  when input.scan(/any\b/)
265
- [:ANY, nil]
608
+ new_token(:ANY, :any)
609
+ when input.scan(/void\b/)
610
+ new_token(:VOID, :void)
266
611
  when input.scan(/interface\b/)
267
- [:INTERFACE, nil]
612
+ new_token(:INTERFACE, :interface)
268
613
  when input.scan(/end\b/)
269
- [:END, nil]
614
+ new_token(:END, :end)
270
615
  when input.scan(/\|/)
271
- [:BAR, nil]
616
+ new_token(:BAR, :bar)
272
617
  when input.scan(/def\b/)
273
- [:DEF, nil]
618
+ new_token(:DEF)
274
619
  when input.scan(/@type\b/)
275
- [:AT_TYPE, nil]
620
+ new_token(:AT_TYPE)
276
621
  when input.scan(/@implements\b/)
277
- [:AT_IMPLEMENTS, nil]
622
+ new_token(:AT_IMPLEMENTS)
278
623
  when input.scan(/@dynamic\b/)
279
- [:AT_DYNAMIC, nil]
624
+ new_token(:AT_DYNAMIC)
280
625
  when input.scan(/const\b/)
281
- [:CONST, nil]
626
+ new_token(:CONST, :const)
282
627
  when input.scan(/var\b/)
283
- [:VAR, nil]
628
+ new_token(:VAR, :var)
284
629
  when input.scan(/return\b/)
285
- [:RETURN, nil]
630
+ new_token(:RETURN)
286
631
  when input.scan(/block\b/)
287
- [:BLOCK, nil]
632
+ new_token(:BLOCK, :block)
633
+ when input.scan(/break\b/)
634
+ new_token(:BREAK, :break)
288
635
  when input.scan(/method\b/)
289
- [:METHOD, nil]
636
+ new_token(:METHOD, :method)
290
637
  when input.scan(/self\?/)
291
- [:SELFQ, nil]
638
+ new_token(:SELFQ)
292
639
  when input.scan(/self\b/)
293
- [:SELF, nil]
640
+ new_token(:SELF, :self)
294
641
  when input.scan(/'\w+/)
295
- [:TVAR, input.matched.gsub(/\A'/, '').to_sym]
642
+ new_token(:TVAR, input.matched.gsub(/\A'/, '').to_sym)
296
643
  when input.scan(/instance\b/)
297
- [:INSTANCE, nil]
644
+ new_token(:INSTANCE, :instance)
298
645
  when input.scan(/class\b/)
299
- [:CLASS, nil]
646
+ new_token(:CLASS, :class)
300
647
  when input.scan(/module\b/)
301
- [:MODULE, nil]
648
+ new_token(:MODULE, :module)
649
+ when input.scan(/include\?/)
650
+ new_token(:METHOD_NAME, :include?)
302
651
  when input.scan(/include\b/)
303
- [:INCLUDE, nil]
652
+ new_token(:INCLUDE, :include)
304
653
  when input.scan(/extend\b/)
305
- [:EXTEND, nil]
654
+ new_token(:EXTEND, :extend)
306
655
  when input.scan(/instance\b/)
307
- [:INSTANCE, nil]
656
+ new_token(:INSTANCE, :instance)
308
657
  when input.scan(/ivar\b/)
309
- [:IVAR, nil]
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
- [:EXTENSION, nil]
672
+ new_token(:EXTENSION, :extension)
312
673
  when input.scan(/constructor\b/)
313
- [:CONSTRUCTOR, true]
674
+ new_token(:CONSTRUCTOR, true)
314
675
  when input.scan(/noconstructor\b/)
315
- [:NOCONSTRUCTOR, false]
316
- when input.scan(/[A-Z]\w*\.(class|module)\b/)
317
- [:CLASS_IDENT, input.matched.gsub(/\.(class|module)$/, '').to_sym]
318
- when input.scan(/\w+(\!|\?)/)
319
- [:METHOD_NAME, input.matched.to_sym]
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
- [:MODULE_NAME, input.matched.to_sym]
682
+ new_token(:UIDENT, input.matched.to_sym)
322
683
  when input.scan(/_\w+/)
323
- [:INTERFACE_NAME, input.matched.to_sym]
324
- when input.scan(/@[\w_]+/)
325
- [:IVAR_NAME, input.matched.to_sym]
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
- [:IDENT, input.matched.to_sym]
688
+ new_token(:IDENT, input.matched.to_sym)
328
689
  end
329
690
  end