steep 0.1.0.pre → 0.1.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +72 -51
- data/bin/smoke_runner.rb +6 -2
- data/lib/steep/cli.rb +4 -4
- data/lib/steep/drivers/check.rb +4 -0
- data/lib/steep/interface.rb +11 -4
- data/lib/steep/parser.y +23 -5
- data/lib/steep/signature/class.rb +118 -26
- data/lib/steep/signature/errors.rb +28 -0
- data/lib/steep/signature/interface.rb +2 -1
- data/lib/steep/type_assignability.rb +13 -8
- data/lib/steep/type_construction.rb +41 -6
- data/lib/steep/type_name.rb +31 -1
- data/lib/steep/types/name.rb +2 -2
- data/lib/steep/version.rb +1 -1
- data/sig/signature.rbi +92 -0
- data/smoke/array/b.rb +16 -0
- data/smoke/class/a.rbi +15 -0
- data/smoke/class/d.rb +9 -0
- data/smoke/class/e.rb +12 -0
- data/smoke/class/f.rb +8 -0
- data/smoke/enumerator/a.rb +19 -0
- data/smoke/initialize/a.rb +12 -0
- data/smoke/initialize/a.rbi +3 -0
- data/smoke/module/a.rb +1 -1
- data/smoke/module/c.rb +23 -0
- data/stdlib/builtin.rbi +19 -4
- data/steep.gemspec +2 -0
- metadata +12 -4
@@ -22,6 +22,10 @@ module Steep
|
|
22
22
|
super(signature: signature)
|
23
23
|
@type = type
|
24
24
|
end
|
25
|
+
|
26
|
+
def puts(io)
|
27
|
+
io.puts "UnknownTypeName: signature=#{signature.name}, type=#{type}"
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
class IncompatibleOverride < Base
|
@@ -40,6 +44,10 @@ module Steep
|
|
40
44
|
@this_method = this_method
|
41
45
|
@super_method = super_method
|
42
46
|
end
|
47
|
+
|
48
|
+
def puts(io)
|
49
|
+
io.puts "IncompatibleOverride: signature=#{signature.name}, method=#{method_name}"
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
53
|
class InvalidTypeApplication < Base
|
@@ -51,6 +59,10 @@ module Steep
|
|
51
59
|
@type_name = type_name
|
52
60
|
@type_args = type_args
|
53
61
|
end
|
62
|
+
|
63
|
+
def puts(io)
|
64
|
+
io.puts "InvalidTypeApplication: signature=#{signature.name}, type_name=#{type_name}, type_args=#{type_args}"
|
65
|
+
end
|
54
66
|
end
|
55
67
|
|
56
68
|
class InvalidSelfType < Base
|
@@ -60,6 +72,11 @@ module Steep
|
|
60
72
|
super(signature: signature)
|
61
73
|
@member = member
|
62
74
|
end
|
75
|
+
|
76
|
+
|
77
|
+
def puts(io)
|
78
|
+
io.puts "InvalidSelfType: signature=#{signature.name}, module=#{member.name}"
|
79
|
+
end
|
63
80
|
end
|
64
81
|
|
65
82
|
class UnexpectedTypeNameKind < Base
|
@@ -71,6 +88,17 @@ module Steep
|
|
71
88
|
@type = type
|
72
89
|
@expected_kind = expected_kind
|
73
90
|
end
|
91
|
+
|
92
|
+
|
93
|
+
def puts(io)
|
94
|
+
io.puts "UnexpectedTypeNameKind: signature=#{signature.name}, type=#{type}, kind=#{expected_kind}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class ConstructorNoCheck < Base
|
99
|
+
def puts(io)
|
100
|
+
io.puts "ConstructorNoCheck: signature=#{signature.name}"
|
101
|
+
end
|
74
102
|
end
|
75
103
|
end
|
76
104
|
end
|
@@ -32,11 +32,12 @@ module Steep
|
|
32
32
|
# @type var map: Hash<Symbol, Steep__Type>
|
33
33
|
map = Hash[self.params.zip(params)]
|
34
34
|
Steep::Interface.new(name: name,
|
35
|
+
params: params,
|
35
36
|
methods: methods.transform_values {|method|
|
36
37
|
types = method.map {|method_type|
|
37
38
|
method_type.substitute(klass: klass, instance: instance, params: map)
|
38
39
|
}
|
39
|
-
Steep::Interface::Method.new(types: types, super_method: nil)
|
40
|
+
Steep::Interface::Method.new(types: types, super_method: nil, attributes: [])
|
40
41
|
})
|
41
42
|
end
|
42
43
|
|
@@ -70,7 +70,7 @@ module Steep
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def test_interface(src, dest, known_pairs)
|
73
|
-
if src
|
73
|
+
if src == dest
|
74
74
|
return true
|
75
75
|
end
|
76
76
|
|
@@ -140,7 +140,7 @@ module Steep
|
|
140
140
|
assigning_pairs << [src.rest, dest_type.last]
|
141
141
|
end
|
142
142
|
end
|
143
|
-
when src.required.size + src.optional.size >= dest.required.size + dest.optional.size
|
143
|
+
when src.required.size + src.optional.size >= dest.required.size + dest.optional.size
|
144
144
|
while src_flat.size > 0
|
145
145
|
src_type = src_flat.shift
|
146
146
|
dest_type = dest_flat.shift
|
@@ -148,7 +148,11 @@ module Steep
|
|
148
148
|
if dest_type
|
149
149
|
assigning_pairs << [src_type.last, dest_type.last]
|
150
150
|
else
|
151
|
-
|
151
|
+
if src_type.first == :required
|
152
|
+
return false
|
153
|
+
else
|
154
|
+
break
|
155
|
+
end
|
152
156
|
end
|
153
157
|
end
|
154
158
|
else
|
@@ -216,7 +220,7 @@ module Steep
|
|
216
220
|
test(src: dest.return_type, dest: src.return_type, known_pairs: known_pairs)
|
217
221
|
end
|
218
222
|
|
219
|
-
def resolve_interface(name, params, klass: nil, instance: nil)
|
223
|
+
def resolve_interface(name, params, klass: nil, instance: nil, constructor: nil)
|
220
224
|
klass ||= Types::Name.module(name: name.name, params: params)
|
221
225
|
instance ||= Types::Name.instance(name: name.name, params: params)
|
222
226
|
|
@@ -225,10 +229,10 @@ module Steep
|
|
225
229
|
signatures[name.name].to_interface(klass: klass, instance: instance, params: params)
|
226
230
|
when TypeName::Instance
|
227
231
|
methods = signatures[name.name].instance_methods(assignability: self, klass: klass, instance: instance, params: params)
|
228
|
-
Interface.new(name: name, methods: methods)
|
232
|
+
Interface.new(name: name, params: params, methods: methods.reject {|key, _| key == :initialize })
|
229
233
|
when TypeName::Module
|
230
|
-
methods = signatures[name.name].module_methods(assignability: self, klass: klass, instance: instance, params: params)
|
231
|
-
Interface.new(name: name, methods: methods)
|
234
|
+
methods = signatures[name.name].module_methods(assignability: self, klass: klass, instance: instance, params: params, constructor: constructor)
|
235
|
+
Interface.new(name: name, params: params, methods: methods)
|
232
236
|
else
|
233
237
|
raise "Unexpected type name: #{name.inspect}"
|
234
238
|
end
|
@@ -284,7 +288,8 @@ module Steep
|
|
284
288
|
}
|
285
289
|
method = methods[name]
|
286
290
|
when Types::Name
|
287
|
-
|
291
|
+
constructor = type.name.is_a?(TypeName::Module) && type.name.constructor
|
292
|
+
interface = resolve_interface(type.name, type.params, constructor: constructor)
|
288
293
|
method = interface.methods[name]
|
289
294
|
else
|
290
295
|
raise "Unexpected type: #{type}"
|
@@ -3,12 +3,14 @@ module Steep
|
|
3
3
|
class MethodContext
|
4
4
|
attr_reader :name
|
5
5
|
attr_reader :method
|
6
|
+
attr_reader :constructor
|
6
7
|
|
7
|
-
def initialize(name:, method:, method_type:, return_type:)
|
8
|
+
def initialize(name:, method:, method_type:, return_type:, constructor:)
|
8
9
|
@name = name
|
9
10
|
@method = method
|
10
11
|
@return_type = return_type
|
11
12
|
@method_type = method_type
|
13
|
+
@constructor = constructor
|
12
14
|
end
|
13
15
|
|
14
16
|
def return_type
|
@@ -87,7 +89,7 @@ module Steep
|
|
87
89
|
end
|
88
90
|
|
89
91
|
if (type = annotations.lookup_method_type(method_name))
|
90
|
-
Interface::Method.new(types: [type], super_method: entry&.super_method)
|
92
|
+
Interface::Method.new(types: [type], super_method: entry&.super_method, attributes: [])
|
91
93
|
else
|
92
94
|
entry
|
93
95
|
end
|
@@ -110,11 +112,15 @@ module Steep
|
|
110
112
|
var_types = {}
|
111
113
|
end
|
112
114
|
|
115
|
+
# FIXME: reading signature directory does not look good...
|
116
|
+
constructor_method = entry&.attributes&.include?(:constructor)
|
117
|
+
|
113
118
|
method_context = MethodContext.new(
|
114
119
|
name: method_name,
|
115
120
|
method: entry,
|
116
121
|
method_type: annotations.lookup_method_type(method_name),
|
117
122
|
return_type: annots.return_type,
|
123
|
+
constructor: constructor_method
|
118
124
|
)
|
119
125
|
|
120
126
|
ivar_types = annots.ivar_types.keys.each.with_object({}) do |var, env|
|
@@ -213,7 +219,18 @@ module Steep
|
|
213
219
|
end
|
214
220
|
|
215
221
|
when :send
|
216
|
-
|
222
|
+
if self_class?(node)
|
223
|
+
module_type = module_context.module_type
|
224
|
+
type = if module_type.is_a?(Types::Name)
|
225
|
+
Types::Name.new(name: module_type.name.updated(constructor: method_context.constructor),
|
226
|
+
params: module_type.params)
|
227
|
+
else
|
228
|
+
module_type
|
229
|
+
end
|
230
|
+
typing.add_typing(node, type)
|
231
|
+
else
|
232
|
+
type_send(node, with_block: false)
|
233
|
+
end
|
217
234
|
|
218
235
|
when :super
|
219
236
|
if self_type && method_context&.method
|
@@ -449,6 +466,8 @@ module Steep
|
|
449
466
|
when :module
|
450
467
|
annots = source.annotations(block: node)
|
451
468
|
|
469
|
+
module_type = Types::Name.instance(name: :Module)
|
470
|
+
|
452
471
|
if annots.implement_module
|
453
472
|
signature = assignability.signatures[annots.implement_module]
|
454
473
|
raise "Module instance should be an module: #{annots.instance_type || annots.implment_module}" unless signature.is_a?(Signature::Module)
|
@@ -456,19 +475,31 @@ module Steep
|
|
456
475
|
ty = Types::Name.instance(name: annots.implement_module)
|
457
476
|
|
458
477
|
if signature.self_type
|
459
|
-
instance_type = Types::Merge.new(types: [
|
478
|
+
instance_type = Types::Merge.new(types: [Types::Name.instance(name: :Object),
|
479
|
+
signature.self_type,
|
480
|
+
ty])
|
460
481
|
else
|
461
|
-
instance_type =
|
482
|
+
instance_type = Types::Merge.new(types: [Types::Name.instance(name: :Object),
|
483
|
+
ty])
|
462
484
|
end
|
485
|
+
|
486
|
+
module_type = Types::Merge.new(types: [
|
487
|
+
Types::Name.instance(name: :Module),
|
488
|
+
Types::Name.module(name: annots.implement_module)
|
489
|
+
])
|
463
490
|
end
|
464
491
|
|
465
492
|
if annots.instance_type
|
466
493
|
instance_type = annots.instance_type
|
467
494
|
end
|
468
495
|
|
496
|
+
if annots.module_type
|
497
|
+
module_type = annots.module_type
|
498
|
+
end
|
499
|
+
|
469
500
|
module_context_ = ModuleContext.new(
|
470
501
|
instance_type: instance_type,
|
471
|
-
module_type:
|
502
|
+
module_type: module_type,
|
472
503
|
const_types: annots.const_types
|
473
504
|
)
|
474
505
|
|
@@ -989,5 +1020,9 @@ module Steep
|
|
989
1020
|
typing.add_error Errors::FallbackAny.new(node: node)
|
990
1021
|
typing.add_typing node, Types::Any.new
|
991
1022
|
end
|
1023
|
+
|
1024
|
+
def self_class?(node)
|
1025
|
+
node.type == :send && node.children[0]&.type == :self && node.children[1] == :class
|
1026
|
+
end
|
992
1027
|
end
|
993
1028
|
end
|
data/lib/steep/type_name.rb
CHANGED
@@ -27,8 +27,38 @@ module Steep
|
|
27
27
|
class Interface < Base; end
|
28
28
|
|
29
29
|
class Module < Base
|
30
|
+
attr_reader :constructor
|
31
|
+
|
30
32
|
def to_s
|
31
|
-
|
33
|
+
k = case constructor
|
34
|
+
when nil
|
35
|
+
""
|
36
|
+
when true
|
37
|
+
" constructor"
|
38
|
+
when false
|
39
|
+
" noconstructor"
|
40
|
+
end
|
41
|
+
|
42
|
+
"#{name}.module#{k}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(name:, constructor:)
|
46
|
+
super(name: name)
|
47
|
+
@constructor = constructor
|
48
|
+
end
|
49
|
+
|
50
|
+
def ==(other)
|
51
|
+
other.is_a?(self.class) && other.name == name && other.constructor == constructor
|
52
|
+
end
|
53
|
+
|
54
|
+
NOTHING = Object.new
|
55
|
+
|
56
|
+
def updated(constructor: NOTHING)
|
57
|
+
if NOTHING == constructor
|
58
|
+
constructor = self.constructor
|
59
|
+
end
|
60
|
+
|
61
|
+
self.class.new(name: name, constructor: constructor)
|
32
62
|
end
|
33
63
|
end
|
34
64
|
|
data/lib/steep/types/name.rb
CHANGED
@@ -21,8 +21,8 @@ module Steep
|
|
21
21
|
self.new(name: TypeName::Interface.new(name: name), params: params)
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.module(name:, params: [])
|
25
|
-
self.new(name: TypeName::Module.new(name: name), params: params)
|
24
|
+
def self.module(name:, params: [], constructor: nil)
|
25
|
+
self.new(name: TypeName::Module.new(name: name, constructor: constructor), params: params)
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.instance(name:, params: [])
|
data/lib/steep/version.rb
CHANGED
data/sig/signature.rbi
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
class Steep__Signature__Error
|
2
2
|
def initialize: (signature: Steep__Signature) -> any
|
3
3
|
def signature: -> Steep__Signature
|
4
|
+
def puts: (any) -> any
|
4
5
|
end
|
5
6
|
|
6
7
|
class Steep__Signature__Errors__UnknownTypeName <: Steep__Signature__Error
|
@@ -8,8 +9,21 @@ class Steep__Signature__Errors__UnknownTypeName <: Steep__Signature__Error
|
|
8
9
|
def type: -> Steep__Type
|
9
10
|
end
|
10
11
|
|
12
|
+
class Steep__BlockType
|
13
|
+
def params: -> Steep__MethodParams
|
14
|
+
def return_type: -> Steep__Type
|
15
|
+
end
|
16
|
+
|
17
|
+
class Steep__MethodParams
|
18
|
+
def each_type: { (Steep__Type) -> any } -> instance
|
19
|
+
end
|
20
|
+
|
11
21
|
class Steep__MethodType
|
12
22
|
def substitute: (klass: Steep__Type, instance: Steep__Type, params: Hash<Symbol, Steep__Type>) -> Steep__MethodType
|
23
|
+
def updated: (?type_params: Array<Symbol>, ?params: Steep__MethodParams, ?block: any, ?return_type: Steep__Type) -> Steep__MethodType
|
24
|
+
def params: -> Steep__MethodParams
|
25
|
+
def return_type: -> Steep__Type
|
26
|
+
def block: -> Steep__BlockType
|
13
27
|
end
|
14
28
|
|
15
29
|
class Steep__Interface
|
@@ -19,6 +33,7 @@ end
|
|
19
33
|
class Steep__Method
|
20
34
|
def initialize: (types: Array<Steep__MethodType>, super_method: Steep__Method) -> any
|
21
35
|
def substitute: (klass: Steep__Type, instance: Steep__Type, params: Hash<Symbol, Steep__Type>) -> Steep__Method
|
36
|
+
def types: -> Array<Steep__MethodType>
|
22
37
|
end
|
23
38
|
|
24
39
|
class Steep__Signature
|
@@ -34,6 +49,83 @@ class Steep__Signature__Errors__IncompatibleOverride <: Steep__Signature__Error
|
|
34
49
|
def super_method: -> Steep__Method
|
35
50
|
end
|
36
51
|
|
52
|
+
class Steep__SignatureMember__Method <: Steep__Signature__Member
|
53
|
+
def initialize: (name: Symbol, types: Array<Steep__MethodType>) -> any
|
54
|
+
def name: -> Symbol
|
55
|
+
def types: -> Array<Steep__MethodType>
|
56
|
+
end
|
57
|
+
|
58
|
+
class Steep__SignatureMember__Include <: Steep__Signature__Member
|
59
|
+
def initialize: (name: Symbol) -> any
|
60
|
+
def name: -> Symbol
|
61
|
+
end
|
62
|
+
|
63
|
+
class Steep__SignatureMember__Extend <: Steep__Signature__Member
|
64
|
+
def initialize: (name: Symbol) -> any
|
65
|
+
def name: -> Symbol
|
66
|
+
end
|
67
|
+
|
68
|
+
interface _Steep__SignatureMember__Mixin
|
69
|
+
def name: -> Steep__Type
|
70
|
+
end
|
71
|
+
|
72
|
+
interface _Steep__WithMethods
|
73
|
+
def instance_methods: (assignability: any, klass: Steep__Type, instance: Steep__Type, params: Array<Steep__Type>) -> Hash<Symbol, Steep__Method>
|
74
|
+
def module_methods: (assignability: any, klass: Steep__Type, instance: Steep__Type, params: Array<Steep__Type>) -> Hash<Symbol, Steep__Method>
|
75
|
+
def type_application_hash: (Array<Steep__Type>) -> Hash<Symbol, Steep__Type>
|
76
|
+
def members: -> Array<Steep__Signature__Member>
|
77
|
+
def is_class?: -> _Boolean
|
78
|
+
end
|
79
|
+
|
80
|
+
module Steep__Signature__WithMethods : _Steep__WithMethods
|
81
|
+
def instance_methods: (assignability: any, klass: Steep__Type, instance: Steep__Type, params: Array<Steep__Type>) -> Hash<Symbol, Steep__Method>
|
82
|
+
def module_methods: (assignability: any, klass: Steep__Type, instance: Steep__Type, params: Array<Steep__Type>) -> Hash<Symbol, Steep__Method>
|
83
|
+
def merge_methods: (Hash<Symbol, Steep__Method>, Hash<Symbol, Steep__Method>) -> Hash<Symbol, Steep__Method>
|
84
|
+
end
|
85
|
+
|
86
|
+
interface _Steep__WithMembers
|
87
|
+
def members: -> Array<Steep__Signature__Member>
|
88
|
+
def params: -> Array<Symbol>
|
89
|
+
end
|
90
|
+
|
91
|
+
module Steep__Signature__WithMembers : _Steep__WithMembers
|
92
|
+
def each_type: { (Steep__Type) -> any } -> any
|
93
|
+
def validate_mixins: (any, Steep__Interface) -> any
|
94
|
+
end
|
95
|
+
|
96
|
+
interface _Steep__WithParams
|
97
|
+
end
|
98
|
+
|
99
|
+
module Steep__Signature__WithParams : _Steep__WithParams
|
100
|
+
def type_application_hash: (Array<Steep__Type>) -> Hash<Symbol, Steep__Type>
|
101
|
+
end
|
102
|
+
|
103
|
+
class Steep__Signature__Module
|
104
|
+
include Steep__Signature__WithMethods
|
105
|
+
include Steep__Signature__WithMembers
|
106
|
+
include Steep__Signature__WithParams
|
107
|
+
|
108
|
+
def initialize: (name: Symbol, params: Array<Symbol>, members: Array<Steep__Signature__Member>, self_type: Steep__Type) -> any
|
109
|
+
def name: -> Symbol
|
110
|
+
def params: -> Array<Symbol>
|
111
|
+
def members: -> Array<Steep__Signature__Member>
|
112
|
+
def self_type: -> Steep__Type
|
113
|
+
def is_class?: -> _Boolean
|
114
|
+
end
|
115
|
+
|
116
|
+
class Steep__Signature__Class
|
117
|
+
include Steep__Signature__WithMethods
|
118
|
+
include Steep__Signature__WithMembers
|
119
|
+
include Steep__Signature__WithParams
|
120
|
+
|
121
|
+
def initialize: (name: Symbol, params: Array<Symbol>, members: Array<Steep__Signature__Member>, super_class: Steep__Types__Name) -> any
|
122
|
+
def name: -> Symbol
|
123
|
+
def params: -> Array<Symbol>
|
124
|
+
def members: -> Array<Steep__Signature__Member>
|
125
|
+
def super_class: -> Steep__Types__Name
|
126
|
+
def is_class?: -> _Boolean
|
127
|
+
end
|
128
|
+
|
37
129
|
class Steep__Signature__Extension
|
38
130
|
def initialize: (module_name: Symbol, extension_name: Symbol, members: Array<Steep__Signature__Member>) -> any
|
39
131
|
def module_name: -> Symbol
|
data/smoke/array/b.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
x = ""
|
2
|
+
y = 1
|
3
|
+
|
4
|
+
# !expects IncompatibleAssignment: lhs_type=String, rhs_type=Integer
|
5
|
+
x = y
|
6
|
+
# !expects IncompatibleAssignment: lhs_type=Integer, rhs_type=String
|
7
|
+
y = x
|
8
|
+
|
9
|
+
# @type var a: Array<Integer>
|
10
|
+
# @type var b: Array<String>
|
11
|
+
|
12
|
+
a = []
|
13
|
+
# !expects IncompatibleAssignment: lhs_type=Array<String>, rhs_type=Array<Integer>
|
14
|
+
b = a
|
15
|
+
# !expects IncompatibleAssignment: lhs_type=Array<Integer>, rhs_type=Array<String>
|
16
|
+
a = b
|
data/smoke/class/a.rbi
CHANGED
@@ -7,3 +7,18 @@ end
|
|
7
7
|
class B
|
8
8
|
def name: -> String
|
9
9
|
end
|
10
|
+
|
11
|
+
class C
|
12
|
+
def (constructor) foo: -> instance
|
13
|
+
def bar: -> instance
|
14
|
+
end
|
15
|
+
|
16
|
+
class D
|
17
|
+
def initialize: (String) -> any
|
18
|
+
def foo: -> any
|
19
|
+
end
|
20
|
+
|
21
|
+
class E
|
22
|
+
def initialize: () -> any
|
23
|
+
def foo: -> any
|
24
|
+
end
|