steep 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|