steep 0.5.1 → 0.6.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 +4 -4
- data/CHANGELOG.md +9 -1
- data/bin/smoke_runner.rb +1 -1
- data/lib/steep.rb +6 -4
- data/lib/steep/ast/builtin.rb +96 -0
- data/lib/steep/ast/location.rb +9 -5
- data/lib/steep/ast/namespace.rb +80 -0
- data/lib/steep/ast/signature/env.rb +37 -31
- data/lib/steep/ast/types/boolean.rb +2 -2
- data/lib/steep/ast/types/hash.rb +50 -0
- data/lib/steep/ast/types/literal.rb +12 -10
- data/lib/steep/ast/types/name.rb +135 -94
- data/lib/steep/ast/types/nil.rb +3 -1
- data/lib/steep/ast/types/proc.rb +3 -1
- data/lib/steep/drivers/check.rb +4 -4
- data/lib/steep/drivers/utils/validator.rb +11 -16
- data/lib/steep/interface/builder.rb +201 -146
- data/lib/steep/interface/instantiated.rb +8 -0
- data/lib/steep/names.rb +86 -0
- data/lib/steep/parser.y +1093 -668
- data/lib/steep/source.rb +2 -2
- data/lib/steep/subtyping/check.rb +199 -63
- data/lib/steep/subtyping/constraints.rb +2 -5
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +194 -175
- data/lib/steep/type_inference/block_params.rb +9 -21
- data/lib/steep/type_inference/constant_env.rb +26 -30
- data/lib/steep/type_inference/send_args.rb +4 -7
- data/lib/steep/type_inference/type_env.rb +3 -3
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +1 -1
- data/smoke/alias/b.rb +1 -1
- data/smoke/class/i.rbi +1 -1
- data/smoke/hash/a.rbi +8 -0
- data/smoke/hash/c.rb +18 -0
- data/smoke/hash/d.rb +6 -0
- data/smoke/hello/hello.rb +2 -2
- data/smoke/interface/a.rb +14 -0
- data/smoke/interface/a.rbi +12 -0
- data/smoke/module/a.rb +1 -1
- data/smoke/module/a.rbi +3 -3
- data/smoke/module/b.rb +1 -1
- data/smoke/stdout/a.rb +2 -2
- data/stdlib/builtin.rbi +6 -7
- data/steep.gemspec +1 -1
- metadata +14 -7
- data/lib/steep/module_name.rb +0 -116
- data/lib/steep/type_name.rb +0 -93
@@ -42,16 +42,18 @@ module Steep
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def back_type
|
45
|
-
case value
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
45
|
+
klass = case value
|
46
|
+
when Integer
|
47
|
+
Builtin::Integer
|
48
|
+
when String
|
49
|
+
Builtin::String
|
50
|
+
when Symbol
|
51
|
+
Builtin::Symbol
|
52
|
+
else
|
53
|
+
raise "Unexpected literal type: #{value.inspect}"
|
54
|
+
end
|
55
|
+
|
56
|
+
Name::Instance.new(name: klass.module_name, args: [], location: location)
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
data/lib/steep/ast/types/name.rb
CHANGED
@@ -1,126 +1,167 @@
|
|
1
1
|
module Steep
|
2
2
|
module AST
|
3
3
|
module Types
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
4
|
+
module Name
|
5
|
+
class Base
|
6
|
+
attr_reader :location
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
def initialize(name:, location: nil)
|
10
|
+
@location = location
|
11
|
+
@name = name
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
def free_variables
|
15
|
+
Set.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def subst(s)
|
19
|
+
self
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
def level
|
23
|
+
[0]
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
|
-
|
27
|
+
class Applying < Base
|
28
|
+
attr_reader :args
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
else
|
31
|
-
"#{name}<#{args.join(", ")}>"
|
30
|
+
def initialize(name:, args:, location: nil)
|
31
|
+
super(name: name, location: location)
|
32
|
+
@args = args
|
32
33
|
end
|
33
|
-
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
def ==(other)
|
36
|
+
other.class == self.class &&
|
37
|
+
other.name == name &&
|
38
|
+
other.args == args
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
name = ModuleName.parse(name) unless name.is_a?(ModuleName)
|
41
|
-
new(location: location,
|
42
|
-
name: TypeName::Module.new(name: name),
|
43
|
-
args: args)
|
44
|
-
end
|
41
|
+
alias eql? ==
|
45
42
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
name: TypeName::Class.new(name: name, constructor: constructor),
|
50
|
-
args: args)
|
51
|
-
end
|
43
|
+
def hash
|
44
|
+
self.class.hash ^ name.hash ^ args.hash
|
45
|
+
end
|
52
46
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
args
|
58
|
-
|
47
|
+
def to_s
|
48
|
+
if args.empty?
|
49
|
+
"#{name}"
|
50
|
+
else
|
51
|
+
"#{name}<#{args.join(", ")}>"
|
52
|
+
end
|
53
|
+
end
|
59
54
|
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
def with_location(new_location)
|
56
|
+
self.class.new(name: name, args: args, location: new_location)
|
57
|
+
end
|
63
58
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
59
|
+
def subst(s)
|
60
|
+
self.class.new(location: location,
|
61
|
+
name: name,
|
62
|
+
args: args.map {|a| a.subst(s) })
|
63
|
+
end
|
69
64
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
65
|
+
def free_variables
|
66
|
+
args.each.with_object(Set.new) do |type, vars|
|
67
|
+
vars.merge(type.free_variables)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
include Helper::ChildrenLevel
|
72
|
+
|
73
|
+
def level
|
74
|
+
[0] + level_of_children(args)
|
80
75
|
end
|
81
76
|
end
|
82
77
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
78
|
+
class Class < Base
|
79
|
+
attr_reader :constructor
|
80
|
+
|
81
|
+
def initialize(name:, constructor:, location: nil)
|
82
|
+
raise "Name should be a module name: #{name.inspect}" unless name.is_a?(Names::Module)
|
83
|
+
super(name: name, location: location)
|
84
|
+
@constructor = constructor
|
85
|
+
end
|
86
|
+
|
87
|
+
def ==(other)
|
88
|
+
other.class == self.class &&
|
89
|
+
other.name == name &&
|
90
|
+
other.constructor == constructor
|
91
|
+
end
|
92
|
+
|
93
|
+
alias eql? ==
|
94
|
+
|
95
|
+
def hash
|
96
|
+
self.class.hash ^ name.hash ^ constructor.hash
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_s
|
100
|
+
k = case constructor
|
101
|
+
when true
|
102
|
+
" constructor"
|
103
|
+
when false
|
104
|
+
" noconstructor"
|
105
|
+
when nil
|
106
|
+
""
|
107
|
+
end
|
108
|
+
"#{name.to_s}.class#{k}"
|
109
|
+
end
|
110
|
+
|
111
|
+
def with_location(new_location)
|
112
|
+
self.class.new(name: name, constructor: constructor, location: new_location)
|
113
|
+
end
|
114
|
+
|
115
|
+
def to_instance(*args)
|
116
|
+
Instance.new(name: name, args: args)
|
117
|
+
end
|
118
|
+
|
119
|
+
NOTHING = ::Object.new
|
120
|
+
|
121
|
+
def updated(constructor: NOTHING)
|
122
|
+
if NOTHING == constructor
|
123
|
+
constructor = self.constructor
|
124
|
+
end
|
125
|
+
|
126
|
+
self.class.new(name: name, constructor: constructor, location: location)
|
96
127
|
end
|
97
128
|
end
|
98
129
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
130
|
+
class Module < Base
|
131
|
+
def ==(other)
|
132
|
+
other.class == self.class &&
|
133
|
+
other.name == name
|
134
|
+
end
|
135
|
+
|
136
|
+
alias eql? ==
|
137
|
+
|
138
|
+
def hash
|
139
|
+
self.class.hash ^ name.hash
|
140
|
+
end
|
141
|
+
|
142
|
+
def to_s
|
143
|
+
"#{name.to_s}.module"
|
144
|
+
end
|
145
|
+
|
146
|
+
def with_location(new_location)
|
147
|
+
self.class.new(name: name, location: new_location)
|
111
148
|
end
|
112
149
|
end
|
113
150
|
|
114
|
-
|
115
|
-
|
116
|
-
|
151
|
+
class Instance < Applying
|
152
|
+
def to_class(constructor:)
|
153
|
+
Class.new(name: name, location: location, constructor: constructor)
|
154
|
+
end
|
155
|
+
|
156
|
+
def to_module
|
157
|
+
Module.new(name: name, location: location)
|
117
158
|
end
|
118
159
|
end
|
119
160
|
|
120
|
-
|
161
|
+
class Interface < Applying
|
162
|
+
end
|
121
163
|
|
122
|
-
|
123
|
-
[0] + level_of_children(args)
|
164
|
+
class Alias < Applying
|
124
165
|
end
|
125
166
|
end
|
126
167
|
end
|
data/lib/steep/ast/types/nil.rb
CHANGED
data/lib/steep/ast/types/proc.rb
CHANGED
data/lib/steep/drivers/check.rb
CHANGED
@@ -63,11 +63,11 @@ module Steep
|
|
63
63
|
sources.each do |source|
|
64
64
|
Steep.logger.tagged source.path do
|
65
65
|
Steep.logger.debug "Typechecking..."
|
66
|
-
annotations = source.annotations(block: source.node, builder: check.builder, current_module:
|
66
|
+
annotations = source.annotations(block: source.node, builder: check.builder, current_module: AST::Namespace.root)
|
67
67
|
|
68
68
|
pp annotations if verbose
|
69
69
|
|
70
|
-
const_env = TypeInference::ConstantEnv.new(builder: check.builder,
|
70
|
+
const_env = TypeInference::ConstantEnv.new(builder: check.builder, context: nil)
|
71
71
|
type_env = TypeInference::TypeEnv.build(annotations: annotations,
|
72
72
|
subtyping: check,
|
73
73
|
const_env: const_env,
|
@@ -77,13 +77,13 @@ module Steep
|
|
77
77
|
checker: check,
|
78
78
|
annotations: annotations,
|
79
79
|
source: source,
|
80
|
-
self_type: AST::
|
80
|
+
self_type: AST::Builtin::Object.instance_type,
|
81
81
|
block_context: nil,
|
82
82
|
module_context: TypeConstruction::ModuleContext.new(
|
83
83
|
instance_type: nil,
|
84
84
|
module_type: nil,
|
85
85
|
implement_name: nil,
|
86
|
-
current_namespace:
|
86
|
+
current_namespace: AST::Namespace.root,
|
87
87
|
const_env: const_env
|
88
88
|
),
|
89
89
|
method_context: nil,
|
@@ -21,11 +21,10 @@ module Steep
|
|
21
21
|
case sig
|
22
22
|
when AST::Signature::Interface
|
23
23
|
yield_self do
|
24
|
-
|
25
|
-
instance_interface = builder.build(instance_name)
|
24
|
+
instance_interface = builder.build_interface(sig.name)
|
26
25
|
|
27
26
|
args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
28
|
-
instance_type = AST::Types::Name.
|
27
|
+
instance_type = AST::Types::Name::Interface.new(name: sig.name, args: args)
|
29
28
|
|
30
29
|
instance_interface.instantiate(type: instance_type,
|
31
30
|
args: args,
|
@@ -35,16 +34,14 @@ module Steep
|
|
35
34
|
|
36
35
|
when AST::Signature::Module
|
37
36
|
yield_self do
|
38
|
-
|
39
|
-
instance_interface = builder.build(instance_name)
|
37
|
+
instance_interface = builder.build_instance(sig.name, with_initialize: true)
|
40
38
|
instance_args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
41
39
|
|
42
|
-
|
43
|
-
module_interface = builder.build(module_name)
|
40
|
+
module_interface = builder.build_module(sig.name)
|
44
41
|
module_args = module_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
45
42
|
|
46
|
-
instance_type = AST::Types::Name.
|
47
|
-
module_type = AST::Types::Name.
|
43
|
+
instance_type = AST::Types::Name::Instance.new(name: sig.name, args: instance_args)
|
44
|
+
module_type = AST::Types::Name::Module.new(name: sig.name)
|
48
45
|
|
49
46
|
stdout.puts "👀 Validating instance methods..." if verbose
|
50
47
|
instance_interface.instantiate(type: instance_type,
|
@@ -61,16 +58,14 @@ module Steep
|
|
61
58
|
|
62
59
|
when AST::Signature::Class
|
63
60
|
yield_self do
|
64
|
-
|
65
|
-
instance_interface = builder.build(instance_name)
|
61
|
+
instance_interface = builder.build_instance(sig.name, with_initialize: true)
|
66
62
|
instance_args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
67
63
|
|
68
|
-
|
69
|
-
module_interface = builder.build(module_name)
|
64
|
+
module_interface = builder.build_class(sig.name, constructor: true)
|
70
65
|
module_args = module_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
71
66
|
|
72
|
-
instance_type = AST::Types::Name.
|
73
|
-
module_type = AST::Types::Name.
|
67
|
+
instance_type = AST::Types::Name::Instance.new(name: sig.name, args: instance_args)
|
68
|
+
module_type = AST::Types::Name::Class.new(name: sig.name, constructor: true)
|
74
69
|
|
75
70
|
stdout.puts "👀 Validating instance methods..." if verbose
|
76
71
|
instance_interface.instantiate(type: instance_type,
|
@@ -94,7 +89,7 @@ module Steep
|
|
94
89
|
when Interface::Method
|
95
90
|
stdout.puts " #{s.name}(#{s.type_name}) <: #{t.name}(#{t.type_name})"
|
96
91
|
when Interface::MethodType
|
97
|
-
stdout.puts " #{s
|
92
|
+
stdout.puts " #{s} <: #{t} (#{s.location&.name||"?"}:#{s.location&.start_line||"?"})"
|
98
93
|
else
|
99
94
|
stdout.puts " #{s} <: #{t}"
|
100
95
|
end
|
@@ -15,47 +15,53 @@ module Steep
|
|
15
15
|
end
|
16
16
|
|
17
17
|
attr_reader :signatures
|
18
|
-
attr_reader :
|
18
|
+
attr_reader :class_cache
|
19
|
+
attr_reader :module_cache
|
20
|
+
attr_reader :instance_cache
|
21
|
+
attr_reader :interface_cache
|
19
22
|
|
20
23
|
def initialize(signatures:)
|
21
|
-
@cache = {}
|
22
24
|
@signatures = signatures
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
begin
|
28
|
-
case type_name
|
29
|
-
when TypeName::Instance
|
30
|
-
type_name.map_module_name {|name|
|
31
|
-
signatures.find_class_or_module(name, current_module: current).name
|
32
|
-
}
|
33
|
-
when TypeName::Module
|
34
|
-
type_name.map_module_name {|name|
|
35
|
-
signatures.find_module(name, current_module: current).name
|
36
|
-
}
|
37
|
-
when TypeName::Class
|
38
|
-
type_name.map_module_name {|name|
|
39
|
-
signatures.find_class(name, current_module: current).name
|
40
|
-
}
|
41
|
-
else
|
42
|
-
type_name
|
43
|
-
end
|
44
|
-
rescue => exn
|
45
|
-
STDERR.puts "Cannot find absolute type name: #{exn.inspect}"
|
46
|
-
type_name
|
47
|
-
end
|
48
|
-
else
|
49
|
-
type_name.map_module_name(&:absolute!)
|
50
|
-
end
|
25
|
+
@class_cache = {}
|
26
|
+
@module_cache = {}
|
27
|
+
@instance_cache = {}
|
28
|
+
@interface_cache = {}
|
51
29
|
end
|
52
30
|
|
53
31
|
def absolute_type(type, current:)
|
54
32
|
case type
|
55
|
-
when AST::Types::Name
|
56
|
-
|
57
|
-
|
58
|
-
|
33
|
+
when AST::Types::Name::Instance
|
34
|
+
signature = signatures.find_class_or_module(type.name, current_module: current)
|
35
|
+
AST::Types::Name::Instance.new(
|
36
|
+
name: signature.name,
|
37
|
+
args: type.args.map {|arg| absolute_type(arg, current: current) },
|
38
|
+
location: type.location
|
39
|
+
)
|
40
|
+
when AST::Types::Name::Class
|
41
|
+
signature = signatures.find_class(type.name, current_module: current)
|
42
|
+
AST::Types::Name::Class.new(
|
43
|
+
name: signature.name,
|
44
|
+
constructor: type.constructor,
|
45
|
+
location: type.location
|
46
|
+
)
|
47
|
+
when AST::Types::Name::Module
|
48
|
+
signature = signatures.find_class_or_module(type.name, current_module: current)
|
49
|
+
AST::Types::Name::Module.new(
|
50
|
+
name: signature.name,
|
51
|
+
location: type.location
|
52
|
+
)
|
53
|
+
when AST::Types::Name::Interface
|
54
|
+
signature = signatures.find_interface(type.name, namespace: current)
|
55
|
+
AST::Types::Name::Interface.new(
|
56
|
+
name: signature.name,
|
57
|
+
args: type.args.map {|arg| absolute_type(arg, current: current) },
|
58
|
+
location: type.location
|
59
|
+
)
|
60
|
+
when AST::Types::Name::Alias
|
61
|
+
signature = signatures.find_alias(type.name, namespace: current)
|
62
|
+
AST::Types::Name::Alias.new(
|
63
|
+
name: signature.name,
|
64
|
+
args: type.args.map {|arg| absolute_type(arg, current: current) },
|
59
65
|
location: type.location
|
60
66
|
)
|
61
67
|
when AST::Types::Union
|
@@ -79,53 +85,72 @@ module Steep
|
|
79
85
|
return_type: absolute_type(type.return_type, current: current),
|
80
86
|
location: type.location
|
81
87
|
)
|
88
|
+
when AST::Types::Hash
|
89
|
+
AST::Types::Hash.new(
|
90
|
+
elements: type.elements.transform_values {|ty| absolute_type(ty, current: current) },
|
91
|
+
location: type.location
|
92
|
+
)
|
82
93
|
else
|
83
94
|
type
|
84
95
|
end
|
85
96
|
end
|
86
97
|
|
87
|
-
def
|
88
|
-
|
89
|
-
cache_key = [type_name, with_initialize]
|
90
|
-
cached = cache[cache_key]
|
98
|
+
def cache_interface(cache, key:, &block)
|
99
|
+
cached = cache[key]
|
91
100
|
|
92
101
|
case cached
|
93
102
|
when nil
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
when TypeName::Instance
|
99
|
-
instance_to_interface(signatures.find_class_or_module(type_name.name), with_initialize: with_initialize)
|
100
|
-
when TypeName::Module
|
101
|
-
module_to_interface(signatures.find_module(type_name.name))
|
102
|
-
when TypeName::Class
|
103
|
-
class_to_interface(signatures.find_class_or_module(type_name.name),
|
104
|
-
constructor: type_name.constructor)
|
105
|
-
when TypeName::Interface
|
106
|
-
interface_to_interface(type_name.name,
|
107
|
-
signatures.find_interface(type_name.name))
|
108
|
-
else
|
109
|
-
raise "Unexpected type_name: #{type_name.inspect}"
|
110
|
-
end
|
111
|
-
|
112
|
-
cache[cache_key]= interface
|
113
|
-
rescue RecursiveDefinitionError => exn
|
114
|
-
exn.chain.unshift(type_name)
|
115
|
-
raise
|
116
|
-
end
|
117
|
-
when TypeName::Base
|
118
|
-
raise RecursiveDefinitionError, type_name
|
103
|
+
cache[key] = key
|
104
|
+
cache[key] = yield
|
105
|
+
when key
|
106
|
+
raise RecursiveDefinitionError, key
|
119
107
|
else
|
120
108
|
cached
|
121
109
|
end
|
110
|
+
rescue RecursiveDefinitionError => exn
|
111
|
+
cache.delete key
|
112
|
+
raise exn
|
113
|
+
end
|
114
|
+
|
115
|
+
def assert_absolute_name!(name)
|
116
|
+
raise "Name should be absolute: #{name}" unless name.absolute?
|
117
|
+
end
|
118
|
+
|
119
|
+
def build_class(module_name, constructor:)
|
120
|
+
assert_absolute_name! module_name
|
121
|
+
signature = signatures.find_class(module_name, current_module: AST::Namespace.root)
|
122
|
+
cache_interface(class_cache, key: [signature.name, !!constructor]) do
|
123
|
+
class_to_interface(signature, constructor: constructor)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def build_module(module_name)
|
128
|
+
assert_absolute_name! module_name
|
129
|
+
signature = signatures.find_module(module_name, current_module: AST::Namespace.root)
|
130
|
+
cache_interface(module_cache, key: signature.name) do
|
131
|
+
module_to_interface(signature)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def build_instance(module_name, with_initialize:)
|
136
|
+
assert_absolute_name! module_name
|
137
|
+
signature = signatures.find_class_or_module(module_name, current_module: AST::Namespace.root)
|
138
|
+
cache_interface(instance_cache, key: [signature.name, with_initialize]) do
|
139
|
+
instance_to_interface(signature, with_initialize: with_initialize)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def build_interface(interface_name)
|
144
|
+
signature = signatures.find_interface(interface_name)
|
145
|
+
cache_interface(interface_cache, key: [signature.name]) do
|
146
|
+
interface_to_interface(nil, signature)
|
147
|
+
end
|
122
148
|
end
|
123
149
|
|
124
|
-
def merge_mixin(
|
125
|
-
|
150
|
+
def merge_mixin(interface, args, methods:, ivars:, supers:, current:)
|
151
|
+
supers.push(*interface.supers)
|
126
152
|
|
127
|
-
|
128
|
-
instantiated = mixed.instantiate(
|
153
|
+
instantiated = interface.instantiate(
|
129
154
|
type: AST::Types::Self.new,
|
130
155
|
args: args,
|
131
156
|
instance_type: AST::Types::Instance.new,
|
@@ -143,13 +168,13 @@ module Steep
|
|
143
168
|
merge_ivars ivars, instantiated.ivars
|
144
169
|
end
|
145
170
|
|
146
|
-
def add_method(type_name, method, methods:, extra_attributes: [])
|
171
|
+
def add_method(type_name, method, methods:, extra_attributes: [], current:)
|
147
172
|
super_method = methods[method.name]
|
148
173
|
new_method = Method.new(
|
149
174
|
type_name: type_name,
|
150
175
|
name: method.name,
|
151
176
|
types: method.types.map do |method_type|
|
152
|
-
method_type_to_method_type(method_type, current:
|
177
|
+
method_type_to_method_type(method_type, current: current)
|
153
178
|
end,
|
154
179
|
super_method: super_method,
|
155
180
|
attributes: method.attributes + extra_attributes
|
@@ -163,12 +188,13 @@ module Steep
|
|
163
188
|
end
|
164
189
|
|
165
190
|
def class_to_interface(sig, constructor:)
|
166
|
-
|
191
|
+
module_name = sig.name
|
192
|
+
namespace = module_name.namespace.append(module_name.name)
|
167
193
|
|
168
194
|
supers = []
|
169
195
|
methods = {
|
170
196
|
new: Method.new(
|
171
|
-
type_name:
|
197
|
+
type_name: Names::Module.parse(name: "__Builtin__"),
|
172
198
|
name: :new,
|
173
199
|
types: [
|
174
200
|
MethodType.new(type_params: [],
|
@@ -179,45 +205,47 @@ module Steep
|
|
179
205
|
)
|
180
206
|
],
|
181
207
|
super_method: nil,
|
182
|
-
attributes: []
|
208
|
+
attributes: [:incompatible]
|
183
209
|
)
|
184
210
|
}
|
185
211
|
|
186
|
-
klass =
|
212
|
+
klass = build_instance(AST::Builtin::Class.module_name, with_initialize: false)
|
187
213
|
instantiated = klass.instantiate(
|
188
214
|
type: AST::Types::Self.new,
|
189
|
-
args: [
|
215
|
+
args: [],
|
190
216
|
instance_type: AST::Types::Instance.new,
|
191
217
|
module_type: AST::Types::Class.new
|
192
218
|
)
|
193
219
|
methods.merge!(instantiated.methods)
|
194
220
|
|
195
|
-
unless
|
196
|
-
super_class_name = sig.super_class&.name&.
|
197
|
-
|
198
|
-
|
199
|
-
methods: methods,
|
200
|
-
ivars: {},
|
201
|
-
supers: supers,
|
202
|
-
current: sig.name)
|
221
|
+
unless module_name == AST::Builtin::BasicObject.module_name
|
222
|
+
super_class_name = sig.super_class&.name&.yield_self {|name| signatures.find_class(name, current_module: namespace).name } || AST::Builtin::Object.module_name
|
223
|
+
class_interface = build_class(super_class_name, constructor: constructor)
|
224
|
+
merge_mixin(class_interface, [], methods: methods, ivars: {}, supers: supers, current: namespace)
|
203
225
|
end
|
204
226
|
|
205
227
|
sig.members.each do |member|
|
206
228
|
case member
|
207
229
|
when AST::Signature::Members::Include
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
230
|
+
member_name = signatures.find_module(member.name, current_module: AST::Namespace.root).name
|
231
|
+
build_module(member_name).yield_self do |module_interface|
|
232
|
+
merge_mixin(module_interface,
|
233
|
+
[],
|
234
|
+
methods: methods,
|
235
|
+
supers: supers,
|
236
|
+
ivars: {},
|
237
|
+
current: namespace)
|
238
|
+
end
|
214
239
|
when AST::Signature::Members::Extend
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
240
|
+
member_name = signatures.find_module(member.name, current_module: AST::Namespace.root).name
|
241
|
+
build_instance(member_name, with_initialize: false).yield_self do |module_interface|
|
242
|
+
merge_mixin(module_interface,
|
243
|
+
member.args.map {|type| absolute_type(type, current: namespace) },
|
244
|
+
methods: methods,
|
245
|
+
ivars: {},
|
246
|
+
supers: supers,
|
247
|
+
current: namespace)
|
248
|
+
end
|
221
249
|
end
|
222
250
|
end
|
223
251
|
|
@@ -226,14 +254,14 @@ module Steep
|
|
226
254
|
when AST::Signature::Members::Method
|
227
255
|
case
|
228
256
|
when member.module_method?
|
229
|
-
add_method(
|
257
|
+
add_method(module_name, member, methods: methods, current: namespace)
|
230
258
|
when member.instance_method? && member.name == :initialize
|
231
259
|
if constructor
|
232
260
|
methods[:new] = Method.new(
|
233
|
-
type_name:
|
261
|
+
type_name: module_name,
|
234
262
|
name: :new,
|
235
263
|
types: member.types.map do |method_type_sig|
|
236
|
-
method_type = method_type_to_method_type(method_type_sig, current:
|
264
|
+
method_type = method_type_to_method_type(method_type_sig, current: namespace).with(return_type: AST::Types::Instance.new)
|
237
265
|
args = (sig.params&.variables || []) + method_type.type_params
|
238
266
|
|
239
267
|
method_type.with(
|
@@ -242,7 +270,7 @@ module Steep
|
|
242
270
|
)
|
243
271
|
end,
|
244
272
|
super_method: nil,
|
245
|
-
attributes: []
|
273
|
+
attributes: [:incompatible]
|
246
274
|
)
|
247
275
|
end
|
248
276
|
end
|
@@ -254,18 +282,27 @@ module Steep
|
|
254
282
|
case member
|
255
283
|
when AST::Signature::Members::Method
|
256
284
|
if member.module_method?
|
257
|
-
add_method(
|
285
|
+
add_method(module_name, member, methods: methods, current: namespace)
|
258
286
|
end
|
259
287
|
end
|
260
288
|
end
|
261
289
|
end
|
262
290
|
|
291
|
+
if methods[:new]&.type_name == AST::Builtin::Class.module_name
|
292
|
+
new_types = [MethodType.new(type_params: [],
|
293
|
+
params: Params.empty,
|
294
|
+
block: nil,
|
295
|
+
return_type: AST::Types::Instance.new,
|
296
|
+
location: nil)]
|
297
|
+
methods[:new] = methods[:new].with_types(new_types)
|
298
|
+
end
|
299
|
+
|
263
300
|
unless constructor
|
264
301
|
methods.delete(:new)
|
265
302
|
end
|
266
303
|
|
267
304
|
Abstract.new(
|
268
|
-
name:
|
305
|
+
name: module_name,
|
269
306
|
params: [],
|
270
307
|
methods: methods,
|
271
308
|
supers: supers,
|
@@ -274,13 +311,14 @@ module Steep
|
|
274
311
|
end
|
275
312
|
|
276
313
|
def module_to_interface(sig)
|
277
|
-
|
314
|
+
module_name = sig.name
|
315
|
+
namespace = module_name.namespace.append(module_name.name)
|
278
316
|
|
279
|
-
supers = [sig.self_type].compact.map {|type| absolute_type(type, current:
|
317
|
+
supers = [sig.self_type].compact.map {|type| absolute_type(type, current: namespace) }
|
280
318
|
methods = {}
|
281
319
|
ivar_chains = {}
|
282
320
|
|
283
|
-
module_instance =
|
321
|
+
module_instance = build_instance(AST::Builtin::Module.module_name, with_initialize: false)
|
284
322
|
instantiated = module_instance.instantiate(
|
285
323
|
type: AST::Types::Self.new,
|
286
324
|
args: [],
|
@@ -292,19 +330,26 @@ module Steep
|
|
292
330
|
sig.members.each do |member|
|
293
331
|
case member
|
294
332
|
when AST::Signature::Members::Include
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
333
|
+
member_name = signatures.find_module(member.name, current_module: AST::Namespace.root).name
|
334
|
+
build_module(member_name).yield_self do |module_interface|
|
335
|
+
merge_mixin(module_interface,
|
336
|
+
member.args.map {|type| absolute_type(type, current: namespace) },
|
337
|
+
methods: methods,
|
338
|
+
ivars: ivar_chains,
|
339
|
+
supers: supers,
|
340
|
+
current: namespace)
|
341
|
+
end
|
301
342
|
when AST::Signature::Members::Extend
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
343
|
+
member_name = signatures.find_module(member.name, current_module: AST::Namespace.root).name
|
344
|
+
build_instance(member_name, with_initialize: false).yield_self do |module_interface|
|
345
|
+
merge_mixin(module_interface,
|
346
|
+
member.args.map {|type| absolute_type(type, current: namespace) },
|
347
|
+
methods: methods,
|
348
|
+
ivars: ivar_chains,
|
349
|
+
supers: supers,
|
350
|
+
current: namespace)
|
351
|
+
|
352
|
+
end
|
308
353
|
end
|
309
354
|
end
|
310
355
|
|
@@ -312,29 +357,29 @@ module Steep
|
|
312
357
|
case member
|
313
358
|
when AST::Signature::Members::Method
|
314
359
|
if member.module_method?
|
315
|
-
add_method(
|
360
|
+
add_method(module_name, member, methods: methods, current: namespace)
|
316
361
|
end
|
317
362
|
when AST::Signature::Members::Ivar
|
318
363
|
merge_ivars(ivar_chains,
|
319
|
-
{ member.name => absolute_type(member.type, current:
|
364
|
+
{ member.name => absolute_type(member.type, current: namespace) })
|
320
365
|
when AST::Signature::Members::Attr
|
321
|
-
merge_attribute(sig, ivar_chains, methods,
|
366
|
+
merge_attribute(sig, ivar_chains, methods, module_name, member)
|
322
367
|
end
|
323
368
|
end
|
324
369
|
|
325
|
-
signatures.find_extensions(
|
370
|
+
signatures.find_extensions(module_name).each do |ext|
|
326
371
|
ext.members.each do |member|
|
327
372
|
case member
|
328
373
|
when AST::Signature::Members::Method
|
329
374
|
if member.module_method?
|
330
|
-
add_method(
|
375
|
+
add_method(module_name, member, methods: methods, current: namespace)
|
331
376
|
end
|
332
377
|
end
|
333
378
|
end
|
334
379
|
end
|
335
380
|
|
336
381
|
Abstract.new(
|
337
|
-
name:
|
382
|
+
name: module_name,
|
338
383
|
params: [],
|
339
384
|
methods: methods,
|
340
385
|
supers: supers,
|
@@ -343,7 +388,8 @@ module Steep
|
|
343
388
|
end
|
344
389
|
|
345
390
|
def instance_to_interface(sig, with_initialize:)
|
346
|
-
|
391
|
+
module_name = sig.name
|
392
|
+
namespace = module_name.namespace.append(module_name.name)
|
347
393
|
|
348
394
|
params = sig.params&.variables || []
|
349
395
|
supers = []
|
@@ -351,14 +397,18 @@ module Steep
|
|
351
397
|
ivar_chains = {}
|
352
398
|
|
353
399
|
if sig.is_a?(AST::Signature::Class)
|
354
|
-
unless sig.name ==
|
355
|
-
super_class_name = sig.super_class&.name ||
|
356
|
-
|
400
|
+
unless sig.name == AST::Builtin::BasicObject.module_name
|
401
|
+
super_class_name = sig.super_class&.name || AST::Builtin::Object.module_name
|
402
|
+
if super_class_name.relative?
|
403
|
+
super_class_name = signatures.find_class(super_class_name, current_module: namespace).name
|
404
|
+
end
|
405
|
+
super_class_interface = build_instance(super_class_name,
|
406
|
+
with_initialize: with_initialize)
|
357
407
|
|
358
408
|
supers.push(*super_class_interface.supers)
|
359
409
|
instantiated = super_class_interface.instantiate(
|
360
410
|
type: AST::Types::Self.new,
|
361
|
-
args: (sig.super_class&.args || []).map {|type| absolute_type(type, current:
|
411
|
+
args: (sig.super_class&.args || []).map {|type| absolute_type(type, current: namespace) },
|
362
412
|
instance_type: AST::Types::Instance.new,
|
363
413
|
module_type: AST::Types::Class.new
|
364
414
|
)
|
@@ -370,19 +420,22 @@ module Steep
|
|
370
420
|
|
371
421
|
if sig.is_a?(AST::Signature::Module)
|
372
422
|
if sig.self_type
|
373
|
-
supers << sig.self_type
|
423
|
+
supers << absolute_type(sig.self_type, current: namespace)
|
374
424
|
end
|
375
425
|
end
|
376
426
|
|
377
427
|
sig.members.each do |member|
|
378
428
|
case member
|
379
429
|
when AST::Signature::Members::Include
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
430
|
+
member_name = signatures.find_module(member.name, current_module: namespace).name
|
431
|
+
build_instance(member_name, with_initialize: false).yield_self do |module_interface|
|
432
|
+
merge_mixin(module_interface,
|
433
|
+
member.args.map {|type| absolute_type(type, current: namespace) },
|
434
|
+
methods: methods,
|
435
|
+
ivars: ivar_chains,
|
436
|
+
supers: supers,
|
437
|
+
current: namespace)
|
438
|
+
end
|
386
439
|
end
|
387
440
|
end
|
388
441
|
|
@@ -392,14 +445,14 @@ module Steep
|
|
392
445
|
if member.instance_method?
|
393
446
|
if with_initialize || member.name != :initialize
|
394
447
|
extra_attrs = member.name == :initialize ? [:incompatible] : []
|
395
|
-
add_method(
|
448
|
+
add_method(module_name, member, methods: methods, extra_attributes: extra_attrs, current: namespace)
|
396
449
|
end
|
397
450
|
end
|
398
451
|
when AST::Signature::Members::Ivar
|
399
452
|
merge_ivars(ivar_chains,
|
400
|
-
{ member.name => absolute_type(member.type, current:
|
453
|
+
{ member.name => absolute_type(member.type, current: namespace) })
|
401
454
|
when AST::Signature::Members::Attr
|
402
|
-
merge_attribute(sig, ivar_chains, methods,
|
455
|
+
merge_attribute(sig, ivar_chains, methods, module_name, member, current: namespace)
|
403
456
|
end
|
404
457
|
end
|
405
458
|
|
@@ -408,14 +461,14 @@ module Steep
|
|
408
461
|
case member
|
409
462
|
when AST::Signature::Members::Method
|
410
463
|
if member.instance_method?
|
411
|
-
add_method(
|
464
|
+
add_method(module_name, member, methods: methods, current: namespace)
|
412
465
|
end
|
413
466
|
end
|
414
467
|
end
|
415
468
|
end
|
416
469
|
|
417
470
|
Abstract.new(
|
418
|
-
name:
|
471
|
+
name: module_name,
|
419
472
|
params: params,
|
420
473
|
methods: methods,
|
421
474
|
supers: supers,
|
@@ -423,11 +476,11 @@ module Steep
|
|
423
476
|
)
|
424
477
|
end
|
425
478
|
|
426
|
-
def merge_attribute(sig, ivar_chains, methods, type_name, member)
|
479
|
+
def merge_attribute(sig, ivar_chains, methods, type_name, member, current:)
|
427
480
|
if member.ivar != false
|
428
481
|
ivar_name = member.ivar || "@#{member.name}".to_sym
|
429
482
|
merge_ivars(ivar_chains,
|
430
|
-
{ ivar_name => absolute_type(member.type, current:
|
483
|
+
{ ivar_name => absolute_type(member.type, current: current) })
|
431
484
|
end
|
432
485
|
|
433
486
|
reader_method = AST::Signature::Members::Method.new(
|
@@ -443,7 +496,7 @@ module Steep
|
|
443
496
|
],
|
444
497
|
attributes: []
|
445
498
|
)
|
446
|
-
add_method(type_name, reader_method, methods: methods)
|
499
|
+
add_method(type_name, reader_method, methods: methods, current: current)
|
447
500
|
|
448
501
|
if member.accessor?
|
449
502
|
writer_method = AST::Signature::Members::Method.new(
|
@@ -453,14 +506,16 @@ module Steep
|
|
453
506
|
types: [
|
454
507
|
AST::MethodType.new(location: member.type.location,
|
455
508
|
type_params: nil,
|
456
|
-
params: AST::MethodType::Params::Required.new(
|
457
|
-
|
509
|
+
params: AST::MethodType::Params::Required.new(
|
510
|
+
location: member.type.location,
|
511
|
+
type: member.type
|
512
|
+
),
|
458
513
|
block: nil,
|
459
514
|
return_type: member.type)
|
460
515
|
],
|
461
516
|
attributes: []
|
462
517
|
)
|
463
|
-
add_method(type_name, writer_method, methods: methods)
|
518
|
+
add_method(type_name, writer_method, methods: methods, current: current)
|
464
519
|
end
|
465
520
|
end
|
466
521
|
|
@@ -471,7 +526,7 @@ module Steep
|
|
471
526
|
end
|
472
527
|
|
473
528
|
def interface_to_interface(_, sig)
|
474
|
-
type_name =
|
529
|
+
type_name = sig.name
|
475
530
|
|
476
531
|
variables = sig.params&.variables || []
|
477
532
|
methods = sig.methods.each.with_object({}) do |method, methods|
|
@@ -479,7 +534,7 @@ module Steep
|
|
479
534
|
type_name: type_name,
|
480
535
|
name: method.name,
|
481
536
|
types: method.types.map do |method_type|
|
482
|
-
method_type_to_method_type(method_type, current:
|
537
|
+
method_type_to_method_type(method_type, current: type_name.namespace)
|
483
538
|
end,
|
484
539
|
super_method: nil,
|
485
540
|
attributes: []
|