steep 0.27.0 → 0.31.1
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 +38 -0
- data/bin/smoke_runner.rb +3 -4
- data/bin/steep-prof +1 -2
- data/lib/steep.rb +6 -4
- data/lib/steep/annotation_parser.rb +2 -4
- data/lib/steep/ast/builtin.rb +11 -21
- data/lib/steep/ast/types/factory.rb +234 -101
- data/lib/steep/ast/types/intersection.rb +12 -9
- data/lib/steep/ast/types/logic.rb +63 -0
- data/lib/steep/ast/types/name.rb +2 -58
- data/lib/steep/ast/types/union.rb +5 -6
- data/lib/steep/errors.rb +14 -0
- data/lib/steep/interface/interface.rb +5 -62
- data/lib/steep/interface/method_type.rb +346 -75
- data/lib/steep/interface/substitution.rb +16 -4
- data/lib/steep/module_helper.rb +25 -0
- data/lib/steep/project.rb +25 -0
- data/lib/steep/project/completion_provider.rb +57 -58
- data/lib/steep/project/file_loader.rb +7 -2
- data/lib/steep/project/hover_content.rb +92 -83
- data/lib/steep/project/signature_file.rb +33 -0
- data/lib/steep/project/{file.rb → source_file.rb} +24 -54
- data/lib/steep/project/target.rb +31 -12
- data/lib/steep/server/base_worker.rb +1 -0
- data/lib/steep/server/code_worker.rb +31 -45
- data/lib/steep/server/interaction_worker.rb +42 -38
- data/lib/steep/server/master.rb +23 -33
- data/lib/steep/server/utils.rb +46 -13
- data/lib/steep/server/worker_process.rb +4 -2
- data/lib/steep/signature/validator.rb +3 -3
- data/lib/steep/source.rb +60 -3
- data/lib/steep/subtyping/check.rb +34 -47
- data/lib/steep/subtyping/constraints.rb +8 -0
- data/lib/steep/type_construction.rb +366 -365
- data/lib/steep/type_inference/block_params.rb +5 -0
- data/lib/steep/type_inference/constant_env.rb +2 -5
- data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
- data/lib/steep/type_inference/type_env.rb +2 -2
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +1 -1
- data/smoke/case/a.rb +1 -1
- data/smoke/if/a.rb +1 -1
- data/smoke/module/a.rb +1 -1
- data/smoke/rescue/a.rb +4 -13
- data/smoke/toplevel/Steepfile +5 -0
- data/smoke/toplevel/a.rb +4 -0
- data/smoke/toplevel/a.rbs +3 -0
- data/smoke/type_case/a.rb +0 -7
- data/steep.gemspec +3 -3
- metadata +20 -16
- data/lib/steep/ast/method_type.rb +0 -126
- data/lib/steep/ast/namespace.rb +0 -80
- data/lib/steep/names.rb +0 -86
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fa95738ddb4d770cdba53deb56b05f2ad86523729852ac16823bfb433470a19
|
4
|
+
data.tar.gz: 9c295a1c5f1d28c1b9ae76b0693c582911770185828e18ce114f062a05fd4d24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 709a0883a3c698f8ca2246763a9c18e8af04072aa6edf7ca5e339a5c6d6e079693e1405c543fe8690276d4eebdcc35e5b65077dcba4c3dca2e1f102e84906e9b
|
7
|
+
data.tar.gz: 3eeef0c3d9cfd34a7678ab8b4f5f125e949d56706510aa1619f018c1346242e10452045b00a09b117bdbec9b5aa27f577ba6ec01c4f732335e9f69dfcf88e228
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,44 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.31.1 (2020-10-07)
|
6
|
+
|
7
|
+
* Fix `if-then-else` parsing ([#236](https://github.com/soutaro/steep/pull/236))
|
8
|
+
|
9
|
+
## 0.31.0 (2020-10-04)
|
10
|
+
|
11
|
+
* Fix type checking performance ([#230](https://github.com/soutaro/steep/pull/230))
|
12
|
+
* Improve LSP completion/hover performance ([#232](https://github.com/soutaro/steep/pull/232))
|
13
|
+
* Fix instance variable completion ([#234](https://github.com/soutaro/steep/pull/234))
|
14
|
+
* Relax version requirements on Listen to allow installing on Ruby 3 ([#235](https://github.com/soutaro/steep/pull/235))
|
15
|
+
|
16
|
+
## 0.30.0 (2020-10-03)
|
17
|
+
|
18
|
+
* Let top-level defs be methods of Object ([#227](https://github.com/soutaro/steep/pull/227))
|
19
|
+
* Fix error caused by attribute definitions ([#228](https://github.com/soutaro/steep/pull/228))
|
20
|
+
* LSP worker improvements ([#222](https://github.com/soutaro/steep/pull/222), [#223](https://github.com/soutaro/steep/pull/223), [#226](https://github.com/soutaro/steep/pull/226), [#229](https://github.com/soutaro/steep/pull/229))
|
21
|
+
|
22
|
+
## 0.29.0 (2020-09-28)
|
23
|
+
|
24
|
+
* Implement reasoning on `is_a?`, `nil?`, and `===` methods. ([#218](https://github.com/soutaro/steep/pull/218))
|
25
|
+
* Better completion based on interface ([#215](https://github.com/soutaro/steep/pull/215))
|
26
|
+
* Fix begin-rescue typing ([#221](https://github.com/soutaro/steep/pull/221))
|
27
|
+
|
28
|
+
## 0.28.0 (2020-09-17)
|
29
|
+
|
30
|
+
* Fix typing case-when with empty body ([#200](https://github.com/soutaro/steep/pull/200))
|
31
|
+
* Fix lvasgn typing with `void` type hint ([#200](https://github.com/soutaro/steep/pull/200))
|
32
|
+
* Fix subtype checking between type variables and union types ([#200](https://github.com/soutaro/steep/pull/200))
|
33
|
+
* Support endless range ([#200](https://github.com/soutaro/steep/pull/200))
|
34
|
+
* Fix optarg, kwoptarg typing ([#202](https://github.com/soutaro/steep/pull/202))
|
35
|
+
* Better union/intersection types ([#204](https://github.com/soutaro/steep/pull/204))
|
36
|
+
* Fix generic method instantiation ([#205](https://github.com/soutaro/steep/pull/205))
|
37
|
+
* Fix module typing ([#206](https://github.com/soutaro/steep/pull/206))
|
38
|
+
* Fix shutdown problem ([#209](https://github.com/soutaro/steep/pull/209))
|
39
|
+
* Update RBS to 0.12.0 ([#210](https://github.com/soutaro/steep/pull/210))
|
40
|
+
* Improve processing singleton class decls without RBS ([#211](https://github.com/soutaro/steep/pull/211))
|
41
|
+
* Improve processing block parameter with masgn ([#212](https://github.com/soutaro/steep/pull/212))
|
42
|
+
|
5
43
|
## 0.27.0 (2020-08-31)
|
6
44
|
|
7
45
|
* Make tuple types _covariant_ ([#195](https://github.com/soutaro/steep/pull/195))
|
data/bin/smoke_runner.rb
CHANGED
@@ -19,8 +19,6 @@ Expectation = Struct.new(:line, :message, :path, :starts) do
|
|
19
19
|
attr_accessor :prefix_test
|
20
20
|
end
|
21
21
|
|
22
|
-
allowed_paths = []
|
23
|
-
|
24
22
|
failed = false
|
25
23
|
|
26
24
|
ARGV.each do |arg|
|
@@ -29,12 +27,13 @@ ARGV.each do |arg|
|
|
29
27
|
|
30
28
|
rb_files = []
|
31
29
|
expectations = []
|
32
|
-
|
30
|
+
allowed_paths = []
|
31
|
+
|
33
32
|
dir.children.each do |file|
|
34
33
|
if file.extname == ".rb"
|
35
34
|
buffer = ::Parser::Source::Buffer.new(file.to_s)
|
36
35
|
buffer.source = file.read
|
37
|
-
parser = ::Parser::
|
36
|
+
parser = ::Parser::Ruby27.new
|
38
37
|
|
39
38
|
_, comments, _ = parser.tokenize(buffer)
|
40
39
|
comments.each do |comment|
|
data/bin/steep-prof
CHANGED
data/lib/steep.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "steep/version"
|
2
2
|
|
3
3
|
require "pathname"
|
4
|
-
require "parser/
|
4
|
+
require "parser/ruby27"
|
5
5
|
require "ast_utils"
|
6
6
|
require "active_support/core_ext/object/try"
|
7
7
|
require "logger"
|
@@ -16,8 +16,6 @@ require 'uri'
|
|
16
16
|
|
17
17
|
require "rbs"
|
18
18
|
|
19
|
-
require "steep/ast/namespace"
|
20
|
-
require "steep/names"
|
21
19
|
require "steep/ast/location"
|
22
20
|
require "steep/ast/types/helper"
|
23
21
|
require "steep/ast/types/any"
|
@@ -37,6 +35,7 @@ require "steep/ast/types/boolean"
|
|
37
35
|
require "steep/ast/types/tuple"
|
38
36
|
require "steep/ast/types/proc"
|
39
37
|
require "steep/ast/types/record"
|
38
|
+
require "steep/ast/types/logic"
|
40
39
|
require "steep/ast/type_params"
|
41
40
|
require "steep/ast/annotation"
|
42
41
|
require "steep/ast/annotation/collection"
|
@@ -62,6 +61,7 @@ require "steep/source"
|
|
62
61
|
require "steep/annotation_parser"
|
63
62
|
require "steep/typing"
|
64
63
|
require "steep/errors"
|
64
|
+
require "steep/module_helper"
|
65
65
|
require "steep/type_construction"
|
66
66
|
require "steep/type_inference/context"
|
67
67
|
require "steep/type_inference/context_array"
|
@@ -71,6 +71,7 @@ require "steep/type_inference/constant_env"
|
|
71
71
|
require "steep/type_inference/type_env"
|
72
72
|
require "steep/type_inference/local_variable_type_env"
|
73
73
|
require "steep/type_inference/logic"
|
74
|
+
require "steep/type_inference/logic_type_interpreter"
|
74
75
|
require "steep/ast/types"
|
75
76
|
|
76
77
|
require "steep/server/utils"
|
@@ -82,7 +83,8 @@ require "steep/server/interaction_worker"
|
|
82
83
|
require "steep/server/master"
|
83
84
|
|
84
85
|
require "steep/project"
|
85
|
-
require "steep/project/
|
86
|
+
require "steep/project/signature_file"
|
87
|
+
require "steep/project/source_file"
|
86
88
|
require "steep/project/options"
|
87
89
|
require "steep/project/target"
|
88
90
|
require "steep/project/dsl"
|
@@ -80,9 +80,7 @@ module Steep
|
|
80
80
|
name = match[:name]
|
81
81
|
type = parse_type(match[:type])
|
82
82
|
|
83
|
-
AST::Annotation::ConstType.new(name:
|
84
|
-
type: type,
|
85
|
-
location: location)
|
83
|
+
AST::Annotation::ConstType.new(name: TypeName(name), type: type, location: location)
|
86
84
|
end
|
87
85
|
|
88
86
|
when keyword_subject_type("ivar", IVAR_NAME)
|
@@ -152,7 +150,7 @@ module Steep
|
|
152
150
|
|
153
151
|
when /@implements\s+(?<name>#{CONST_NAME})#{TYPE_PARAMS}$/
|
154
152
|
Regexp.last_match.yield_self do |match|
|
155
|
-
type_name =
|
153
|
+
type_name = TypeName(match[:name])
|
156
154
|
params = match[:params]&.yield_self {|params| params.split(/,/).map {|param| param.strip.to_sym } } || []
|
157
155
|
|
158
156
|
name = AST::Annotation::Implements::Module.new(name: type_name, args: params)
|
data/lib/steep/ast/builtin.rb
CHANGED
@@ -6,7 +6,7 @@ module Steep
|
|
6
6
|
attr_reader :arity
|
7
7
|
|
8
8
|
def initialize(module_name, arity: 0)
|
9
|
-
@module_name =
|
9
|
+
@module_name = TypeName(module_name)
|
10
10
|
@arity = arity
|
11
11
|
end
|
12
12
|
|
@@ -15,12 +15,8 @@ module Steep
|
|
15
15
|
Types::Name::Instance.new(name: module_name, args: args)
|
16
16
|
end
|
17
17
|
|
18
|
-
def class_type(constructor: nil)
|
19
|
-
Types::Name::Class.new(name: module_name, constructor: constructor)
|
20
|
-
end
|
21
|
-
|
22
18
|
def module_type
|
23
|
-
Types::Name::
|
19
|
+
Types::Name::Singleton.new(name: module_name)
|
24
20
|
end
|
25
21
|
|
26
22
|
def instance_type?(type, args: nil)
|
@@ -36,22 +32,8 @@ module Steep
|
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
39
|
-
NONE = ::Object.new
|
40
|
-
|
41
|
-
def class_type?(type, constructor: NONE)
|
42
|
-
if type.is_a?(Types::Name::Class)
|
43
|
-
unless constructor.equal?(NONE)
|
44
|
-
type.name == module_name && type.name.constructor == constructor
|
45
|
-
else
|
46
|
-
type.name == module_name
|
47
|
-
end
|
48
|
-
else
|
49
|
-
false
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
35
|
def module_type?(type)
|
54
|
-
if type.is_a?(Types::Name::
|
36
|
+
if type.is_a?(Types::Name::Singleton)
|
55
37
|
type.name == module_name
|
56
38
|
else
|
57
39
|
false
|
@@ -99,6 +81,14 @@ module Steep
|
|
99
81
|
def self.optional(type)
|
100
82
|
AST::Types::Union.build(types: [type, nil_type])
|
101
83
|
end
|
84
|
+
|
85
|
+
def self.true_type
|
86
|
+
AST::Types::Literal.new(value: true)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.false_type
|
90
|
+
AST::Types::Literal.new(value: false)
|
91
|
+
end
|
102
92
|
end
|
103
93
|
end
|
104
94
|
end
|
@@ -7,11 +7,14 @@ module Steep
|
|
7
7
|
attr_reader :type_name_cache
|
8
8
|
attr_reader :type_cache
|
9
9
|
|
10
|
+
attr_reader :type_interface_cache
|
11
|
+
|
10
12
|
def initialize(builder:)
|
11
13
|
@definition_builder = builder
|
12
14
|
|
13
15
|
@type_name_cache = {}
|
14
16
|
@type_cache = {}
|
17
|
+
@type_interface_cache = {}
|
15
18
|
end
|
16
19
|
|
17
20
|
def type_name_resolver
|
@@ -43,18 +46,18 @@ module Steep
|
|
43
46
|
when RBS::Types::Variable
|
44
47
|
Var.new(name: type.name, location: nil)
|
45
48
|
when RBS::Types::ClassSingleton
|
46
|
-
type_name =
|
47
|
-
Name::
|
49
|
+
type_name = type.name
|
50
|
+
Name::Singleton.new(name: type_name, location: nil)
|
48
51
|
when RBS::Types::ClassInstance
|
49
|
-
type_name =
|
52
|
+
type_name = type.name
|
50
53
|
args = type.args.map {|arg| type(arg) }
|
51
54
|
Name::Instance.new(name: type_name, args: args, location: nil)
|
52
55
|
when RBS::Types::Interface
|
53
|
-
type_name =
|
56
|
+
type_name = type.name
|
54
57
|
args = type.args.map {|arg| type(arg) }
|
55
58
|
Name::Interface.new(name: type_name, args: args, location: nil)
|
56
59
|
when RBS::Types::Alias
|
57
|
-
type_name =
|
60
|
+
type_name = type.name
|
58
61
|
Name::Alias.new(name: type_name, args: [], location: nil)
|
59
62
|
when RBS::Types::Union
|
60
63
|
Union.build(types: type.types.map {|ty| type(ty) }, location: nil)
|
@@ -102,23 +105,23 @@ module Steep
|
|
102
105
|
RBS::Types::Bases::Nil.new(location: nil)
|
103
106
|
when Var
|
104
107
|
RBS::Types::Variable.new(name: type.name, location: nil)
|
105
|
-
when Name::
|
106
|
-
RBS::Types::ClassSingleton.new(name:
|
108
|
+
when Name::Singleton
|
109
|
+
RBS::Types::ClassSingleton.new(name: type.name, location: nil)
|
107
110
|
when Name::Instance
|
108
111
|
RBS::Types::ClassInstance.new(
|
109
|
-
name:
|
112
|
+
name: type.name,
|
110
113
|
args: type.args.map {|arg| type_1(arg) },
|
111
114
|
location: nil
|
112
115
|
)
|
113
116
|
when Name::Interface
|
114
117
|
RBS::Types::Interface.new(
|
115
|
-
name:
|
118
|
+
name: type.name,
|
116
119
|
args: type.args.map {|arg| type_1(arg) },
|
117
120
|
location: nil
|
118
121
|
)
|
119
122
|
when Name::Alias
|
120
123
|
type.args.empty? or raise "alias type with args is not supported"
|
121
|
-
RBS::Types::Alias.new(name:
|
124
|
+
RBS::Types::Alias.new(name: type.name, location: nil)
|
122
125
|
when Union
|
123
126
|
RBS::Types::Union.new(
|
124
127
|
types: type.types.map {|ty| type_1(ty) },
|
@@ -151,32 +154,6 @@ module Steep
|
|
151
154
|
end
|
152
155
|
end
|
153
156
|
|
154
|
-
def type_name(name)
|
155
|
-
n = type_name_cache[name] and return n
|
156
|
-
|
157
|
-
type_name_cache[name] =
|
158
|
-
(case
|
159
|
-
when name.class?
|
160
|
-
Names::Module.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
161
|
-
when name.interface?
|
162
|
-
Names::Interface.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
163
|
-
when name.alias?
|
164
|
-
Names::Alias.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
165
|
-
end)
|
166
|
-
end
|
167
|
-
|
168
|
-
def type_name_1(name)
|
169
|
-
RBS::TypeName.new(name: name.name, namespace: namespace_1(name.namespace))
|
170
|
-
end
|
171
|
-
|
172
|
-
def namespace(namespace)
|
173
|
-
Namespace.parse(namespace.to_s)
|
174
|
-
end
|
175
|
-
|
176
|
-
def namespace_1(namespace)
|
177
|
-
RBS::Namespace.parse(namespace.to_s)
|
178
|
-
end
|
179
|
-
|
180
157
|
def function_1(params, return_type)
|
181
158
|
RBS::Types::Function.new(
|
182
159
|
required_positionals: params.required.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
@@ -201,7 +178,7 @@ module Steep
|
|
201
178
|
)
|
202
179
|
end
|
203
180
|
|
204
|
-
def method_type(method_type, self_type:, subst2: nil)
|
181
|
+
def method_type(method_type, self_type:, subst2: nil, method_def: nil)
|
205
182
|
fvs = self_type.free_variables()
|
206
183
|
|
207
184
|
type_params = []
|
@@ -219,20 +196,21 @@ module Steep
|
|
219
196
|
end
|
220
197
|
end
|
221
198
|
subst = Interface::Substitution.build(alpha_vars, alpha_types)
|
222
|
-
subst.merge!(subst2) if subst2
|
199
|
+
subst.merge!(subst2, overwrite: true) if subst2
|
223
200
|
|
224
201
|
type = Interface::MethodType.new(
|
225
202
|
type_params: type_params,
|
226
203
|
return_type: type(method_type.type.return_type).subst(subst),
|
227
204
|
params: params(method_type.type).subst(subst),
|
228
|
-
location: nil,
|
229
205
|
block: method_type.block&.yield_self do |block|
|
230
206
|
Interface::Block.new(
|
231
207
|
optional: !block.required,
|
232
208
|
type: Proc.new(params: params(block.type).subst(subst),
|
233
209
|
return_type: type(block.type.return_type).subst(subst), location: nil)
|
234
210
|
)
|
235
|
-
end
|
211
|
+
end,
|
212
|
+
method_def: method_def,
|
213
|
+
location: method_def&.member&.location
|
236
214
|
)
|
237
215
|
|
238
216
|
if block_given?
|
@@ -292,7 +270,7 @@ module Steep
|
|
292
270
|
end
|
293
271
|
|
294
272
|
def unfold(type_name)
|
295
|
-
|
273
|
+
type_name.yield_self do |type_name|
|
296
274
|
type(definition_builder.expand_alias(type_name))
|
297
275
|
end
|
298
276
|
end
|
@@ -312,19 +290,129 @@ module Steep
|
|
312
290
|
end
|
313
291
|
end
|
314
292
|
|
293
|
+
def deep_expand_alias(type, recursive: Set.new, &block)
|
294
|
+
raise "Recursive type definition: #{type}" if recursive.member?(type)
|
295
|
+
|
296
|
+
ty = case type
|
297
|
+
when AST::Types::Name::Alias
|
298
|
+
deep_expand_alias(expand_alias(type), recursive: recursive.union([type]))
|
299
|
+
when AST::Types::Union
|
300
|
+
AST::Types::Union.build(
|
301
|
+
types: type.types.map {|ty| deep_expand_alias(ty, recursive: recursive, &block) },
|
302
|
+
location: type.location
|
303
|
+
)
|
304
|
+
else
|
305
|
+
type
|
306
|
+
end
|
307
|
+
|
308
|
+
if block_given?
|
309
|
+
yield ty
|
310
|
+
else
|
311
|
+
ty
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def flatten_union(type, acc = [])
|
316
|
+
case type
|
317
|
+
when AST::Types::Union
|
318
|
+
type.types.each {|ty| flatten_union(ty, acc) }
|
319
|
+
else
|
320
|
+
acc << type
|
321
|
+
end
|
322
|
+
|
323
|
+
acc
|
324
|
+
end
|
325
|
+
|
326
|
+
def unwrap_optional(type)
|
327
|
+
case type
|
328
|
+
when AST::Types::Union
|
329
|
+
falsy_types, truthy_types = type.types.partition do |type|
|
330
|
+
(type.is_a?(AST::Types::Literal) && type.value == false) ||
|
331
|
+
type.is_a?(AST::Types::Nil)
|
332
|
+
end
|
333
|
+
|
334
|
+
[
|
335
|
+
AST::Types::Union.build(types: truthy_types),
|
336
|
+
AST::Types::Union.build(types: falsy_types)
|
337
|
+
]
|
338
|
+
when AST::Types::Name::Alias
|
339
|
+
unwrap_optional(expand_alias(type))
|
340
|
+
else
|
341
|
+
[type, nil]
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def setup_primitives(method_name, method_type)
|
346
|
+
if method_def = method_type.method_def
|
347
|
+
defined_in = method_def.defined_in
|
348
|
+
member = method_def.member
|
349
|
+
|
350
|
+
if member.is_a?(RBS::AST::Members::MethodDefinition)
|
351
|
+
case
|
352
|
+
when defined_in == RBS::BuiltinNames::Object.name && member.instance?
|
353
|
+
case method_name
|
354
|
+
when :is_a?, :kind_of?, :instance_of?
|
355
|
+
return method_type.with(
|
356
|
+
return_type: AST::Types::Logic::ReceiverIsArg.new(location: method_type.return_type.location)
|
357
|
+
)
|
358
|
+
when :nil?
|
359
|
+
return method_type.with(
|
360
|
+
return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.return_type.location)
|
361
|
+
)
|
362
|
+
end
|
363
|
+
|
364
|
+
when defined_in == AST::Builtin::NilClass.module_name && member.instance?
|
365
|
+
case method_name
|
366
|
+
when :nil?
|
367
|
+
return method_type.with(
|
368
|
+
return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.return_type.location)
|
369
|
+
)
|
370
|
+
end
|
371
|
+
|
372
|
+
when defined_in == RBS::BuiltinNames::BasicObject.name && member.instance?
|
373
|
+
case method_name
|
374
|
+
when :!
|
375
|
+
return method_type.with(
|
376
|
+
return_type: AST::Types::Logic::Not.new(location: method_type.return_type.location)
|
377
|
+
)
|
378
|
+
end
|
379
|
+
|
380
|
+
when defined_in == RBS::BuiltinNames::Module.name && member.instance?
|
381
|
+
case method_name
|
382
|
+
when :===
|
383
|
+
return method_type.with(
|
384
|
+
return_type: AST::Types::Logic::ArgIsReceiver.new(location: method_type.return_type.location)
|
385
|
+
)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
method_type
|
392
|
+
end
|
393
|
+
|
315
394
|
def interface(type, private:, self_type: type)
|
316
|
-
type
|
395
|
+
Steep.logger.debug { "Factory#interface: #{type}, private=#{private}, self_type=#{self_type}" }
|
396
|
+
|
397
|
+
cache_key = [type, self_type, private]
|
398
|
+
if type_interface_cache.key?(cache_key)
|
399
|
+
return type_interface_cache[cache_key]
|
400
|
+
end
|
317
401
|
|
318
402
|
case type
|
403
|
+
when Name::Alias
|
404
|
+
interface(expand_alias(type), private: private, self_type: self_type)
|
405
|
+
|
319
406
|
when Self
|
320
407
|
if self_type != type
|
321
408
|
interface self_type, private: private, self_type: Self.new
|
322
409
|
else
|
323
410
|
raise "Unexpected `self` type interface"
|
324
411
|
end
|
412
|
+
|
325
413
|
when Name::Instance
|
326
414
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
327
|
-
definition = definition_builder.build_instance(
|
415
|
+
definition = definition_builder.build_instance(type.name)
|
328
416
|
|
329
417
|
instance_type = Name::Instance.new(name: type.name,
|
330
418
|
args: type.args.map { Any.new(location: nil) },
|
@@ -340,20 +428,27 @@ module Steep
|
|
340
428
|
)
|
341
429
|
|
342
430
|
definition.methods.each do |name, method|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
431
|
+
Steep.logger.tagged "method = #{name}" do
|
432
|
+
next if method.private? && !private
|
433
|
+
|
434
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
435
|
+
method_types: method.defs.map do |type_def|
|
436
|
+
setup_primitives(
|
437
|
+
name,
|
438
|
+
method_type(type_def.type,
|
439
|
+
method_def: type_def,
|
440
|
+
self_type: self_type,
|
441
|
+
subst2: subst)
|
442
|
+
)
|
443
|
+
end
|
444
|
+
)
|
445
|
+
end
|
351
446
|
end
|
352
447
|
end
|
353
448
|
|
354
449
|
when Name::Interface
|
355
450
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
356
|
-
type_name =
|
451
|
+
type_name = type.name
|
357
452
|
definition = definition_builder.build_interface(type_name)
|
358
453
|
|
359
454
|
subst = Interface::Substitution.build(
|
@@ -363,18 +458,17 @@ module Steep
|
|
363
458
|
)
|
364
459
|
|
365
460
|
definition.methods.each do |name, method|
|
366
|
-
interface.methods[name] = Interface::Interface::
|
367
|
-
method.
|
368
|
-
method_type(type, self_type: self_type, subst2: subst)
|
369
|
-
end
|
370
|
-
incompatible: false
|
461
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
462
|
+
method_types: method.defs.map do |type_def|
|
463
|
+
method_type(type_def.type, method_def: type_def, self_type: self_type, subst2: subst)
|
464
|
+
end
|
371
465
|
)
|
372
466
|
end
|
373
467
|
end
|
374
468
|
|
375
|
-
when Name::
|
469
|
+
when Name::Singleton
|
376
470
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
377
|
-
definition = definition_builder.build_singleton(
|
471
|
+
definition = definition_builder.build_singleton(type.name)
|
378
472
|
|
379
473
|
instance_type = Name::Instance.new(name: type.name,
|
380
474
|
args: definition.type_params.map {Any.new(location: nil)},
|
@@ -389,11 +483,16 @@ module Steep
|
|
389
483
|
definition.methods.each do |name, method|
|
390
484
|
next if !private && method.private?
|
391
485
|
|
392
|
-
interface.methods[name] = Interface::Interface::
|
393
|
-
method.
|
394
|
-
|
395
|
-
|
396
|
-
|
486
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
487
|
+
method_types: method.defs.map do |type_def|
|
488
|
+
setup_primitives(
|
489
|
+
name,
|
490
|
+
method_type(type_def.type,
|
491
|
+
method_def: type_def,
|
492
|
+
self_type: self_type,
|
493
|
+
subst2: subst)
|
494
|
+
)
|
495
|
+
end
|
397
496
|
)
|
398
497
|
end
|
399
498
|
end
|
@@ -416,7 +515,25 @@ module Steep
|
|
416
515
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
417
516
|
common_methods = Set.new(interface1.methods.keys) & Set.new(interface2.methods.keys)
|
418
517
|
common_methods.each do |name|
|
419
|
-
|
518
|
+
types1 = interface1.methods[name].method_types
|
519
|
+
types2 = interface2.methods[name].method_types
|
520
|
+
|
521
|
+
if types1 == types2
|
522
|
+
interface.methods[name] = interface1.methods[name]
|
523
|
+
else
|
524
|
+
method_types = {}
|
525
|
+
|
526
|
+
types1.each do |type1|
|
527
|
+
types2.each do |type2|
|
528
|
+
type = type1 | type2 or next
|
529
|
+
method_types[type] = true
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
unless method_types.empty?
|
534
|
+
interface.methods[name] = Interface::Interface::Entry.new(method_types: method_types.keys)
|
535
|
+
end
|
536
|
+
end
|
420
537
|
end
|
421
538
|
end
|
422
539
|
end
|
@@ -427,11 +544,8 @@ module Steep
|
|
427
544
|
interfaces = type.types.map {|ty| interface(ty, private: private, self_type: self_type) }
|
428
545
|
interfaces.inject do |interface1, interface2|
|
429
546
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
430
|
-
|
431
|
-
|
432
|
-
methods = [interface1.methods[name], interface2.methods[name]].compact
|
433
|
-
interface.methods[name] = Interface::Interface::Combination.intersection(methods)
|
434
|
-
end
|
547
|
+
interface.methods.merge!(interface1.methods)
|
548
|
+
interface.methods.merge!(interface2.methods)
|
435
549
|
end
|
436
550
|
end
|
437
551
|
end
|
@@ -442,8 +556,8 @@ module Steep
|
|
442
556
|
array_type = Builtin::Array.instance_type(element_type)
|
443
557
|
interface(array_type, private: private, self_type: self_type).tap do |array_interface|
|
444
558
|
array_interface.methods[:[]] = array_interface.methods[:[]].yield_self do |aref|
|
445
|
-
Interface::Interface::
|
446
|
-
type.types.map.with_index {|elem_type, index|
|
559
|
+
Interface::Interface::Entry.new(
|
560
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
447
561
|
Interface::MethodType.new(
|
448
562
|
type_params: [],
|
449
563
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index)],
|
@@ -454,16 +568,16 @@ module Steep
|
|
454
568
|
rest_keywords: nil),
|
455
569
|
block: nil,
|
456
570
|
return_type: elem_type,
|
571
|
+
method_def: nil,
|
457
572
|
location: nil
|
458
573
|
)
|
459
|
-
} + aref.
|
460
|
-
incompatible: false
|
574
|
+
} + aref.method_types
|
461
575
|
)
|
462
576
|
end
|
463
577
|
|
464
578
|
array_interface.methods[:[]=] = array_interface.methods[:[]=].yield_self do |update|
|
465
|
-
Interface::Interface::
|
466
|
-
type.types.map.with_index {|elem_type, index|
|
579
|
+
Interface::Interface::Entry.new(
|
580
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
467
581
|
Interface::MethodType.new(
|
468
582
|
type_params: [],
|
469
583
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
|
@@ -474,40 +588,40 @@ module Steep
|
|
474
588
|
rest_keywords: nil),
|
475
589
|
block: nil,
|
476
590
|
return_type: elem_type,
|
591
|
+
method_def: nil,
|
477
592
|
location: nil
|
478
593
|
)
|
479
|
-
} + update.
|
480
|
-
incompatible: false
|
594
|
+
} + update.method_types
|
481
595
|
)
|
482
596
|
end
|
483
597
|
|
484
598
|
array_interface.methods[:first] = array_interface.methods[:first].yield_self do |first|
|
485
|
-
Interface::Interface::
|
486
|
-
[
|
599
|
+
Interface::Interface::Entry.new(
|
600
|
+
method_types: [
|
487
601
|
Interface::MethodType.new(
|
488
602
|
type_params: [],
|
489
603
|
params: Interface::Params.empty,
|
490
604
|
block: nil,
|
491
605
|
return_type: type.types[0] || AST::Builtin.nil_type,
|
606
|
+
method_def: nil,
|
492
607
|
location: nil
|
493
608
|
)
|
494
|
-
]
|
495
|
-
incompatible: false
|
609
|
+
]
|
496
610
|
)
|
497
611
|
end
|
498
612
|
|
499
613
|
array_interface.methods[:last] = array_interface.methods[:last].yield_self do |last|
|
500
|
-
Interface::Interface::
|
501
|
-
[
|
614
|
+
Interface::Interface::Entry.new(
|
615
|
+
method_types: [
|
502
616
|
Interface::MethodType.new(
|
503
617
|
type_params: [],
|
504
618
|
params: Interface::Params.empty,
|
505
619
|
block: nil,
|
506
620
|
return_type: type.types.last || AST::Builtin.nil_type,
|
621
|
+
method_def: nil,
|
507
622
|
location: nil
|
508
623
|
)
|
509
|
-
]
|
510
|
-
incompatible: false
|
624
|
+
]
|
511
625
|
)
|
512
626
|
end
|
513
627
|
end
|
@@ -523,8 +637,8 @@ module Steep
|
|
523
637
|
|
524
638
|
interface(hash_type, private: private, self_type: self_type).tap do |hash_interface|
|
525
639
|
hash_interface.methods[:[]] = hash_interface.methods[:[]].yield_self do |ref|
|
526
|
-
Interface::Interface::
|
527
|
-
type.elements.map {|key_value, value_type|
|
640
|
+
Interface::Interface::Entry.new(
|
641
|
+
method_types: type.elements.map {|key_value, value_type|
|
528
642
|
key_type = Literal.new(value: key_value, location: nil)
|
529
643
|
Interface::MethodType.new(
|
530
644
|
type_params: [],
|
@@ -536,16 +650,16 @@ module Steep
|
|
536
650
|
rest_keywords: nil),
|
537
651
|
block: nil,
|
538
652
|
return_type: value_type,
|
653
|
+
method_def: nil,
|
539
654
|
location: nil
|
540
655
|
)
|
541
|
-
} + ref.
|
542
|
-
incompatible: false
|
656
|
+
} + ref.method_types
|
543
657
|
)
|
544
658
|
end
|
545
659
|
|
546
660
|
hash_interface.methods[:[]=] = hash_interface.methods[:[]=].yield_self do |update|
|
547
|
-
Interface::Interface::
|
548
|
-
type.elements.map {|key_value, value_type|
|
661
|
+
Interface::Interface::Entry.new(
|
662
|
+
method_types: type.elements.map {|key_value, value_type|
|
549
663
|
key_type = Literal.new(value: key_value, location: nil)
|
550
664
|
Interface::MethodType.new(
|
551
665
|
type_params: [],
|
@@ -557,10 +671,10 @@ module Steep
|
|
557
671
|
rest_keywords: nil),
|
558
672
|
block: nil,
|
559
673
|
return_type: value_type,
|
674
|
+
method_def: nil,
|
560
675
|
location: nil
|
561
676
|
)
|
562
|
-
} + update.
|
563
|
-
incompatible: false
|
677
|
+
} + update.method_types
|
564
678
|
)
|
565
679
|
end
|
566
680
|
end
|
@@ -573,26 +687,30 @@ module Steep
|
|
573
687
|
params: type.params,
|
574
688
|
return_type: type.return_type,
|
575
689
|
block: nil,
|
690
|
+
method_def: nil,
|
576
691
|
location: nil
|
577
692
|
)
|
578
693
|
|
579
|
-
interface.methods[:[]] = Interface::Interface::
|
580
|
-
interface.methods[:call] = Interface::Interface::
|
694
|
+
interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type])
|
695
|
+
interface.methods[:call] = Interface::Interface::Entry.new(method_types: [method_type])
|
581
696
|
end
|
582
697
|
|
698
|
+
when Logic::Base
|
699
|
+
interface(AST::Builtin.bool_type, private: private, self_type: self_type)
|
700
|
+
|
583
701
|
else
|
584
702
|
raise "Unexpected type for interface: #{type}"
|
703
|
+
end.tap do |interface|
|
704
|
+
type_interface_cache[cache_key] = interface
|
585
705
|
end
|
586
706
|
end
|
587
707
|
|
588
708
|
def module_name?(type_name)
|
589
|
-
|
590
|
-
entry = env.class_decls[name] and entry.is_a?(RBS::Environment::ModuleEntry)
|
709
|
+
entry = env.class_decls[type_name] and entry.is_a?(RBS::Environment::ModuleEntry)
|
591
710
|
end
|
592
711
|
|
593
712
|
def class_name?(type_name)
|
594
|
-
|
595
|
-
entry = env.class_decls[name] and entry.is_a?(RBS::Environment::ClassEntry)
|
713
|
+
entry = env.class_decls[type_name] and entry.is_a?(RBS::Environment::ClassEntry)
|
596
714
|
end
|
597
715
|
|
598
716
|
def env
|
@@ -607,7 +725,22 @@ module Steep
|
|
607
725
|
end
|
608
726
|
|
609
727
|
def absolute_type_name(type_name, namespace:)
|
610
|
-
type_name_resolver.resolve(type_name, context:
|
728
|
+
type_name_resolver.resolve(type_name, context: namespace.ascend)
|
729
|
+
end
|
730
|
+
|
731
|
+
def instance_type(type_name, args: nil, location: nil)
|
732
|
+
raise unless type_name.class?
|
733
|
+
|
734
|
+
definition = definition_builder.build_singleton(type_name)
|
735
|
+
def_args = definition.type_params.map { Any.new(location: nil) }
|
736
|
+
|
737
|
+
if args
|
738
|
+
raise if def_args.size != args.size
|
739
|
+
else
|
740
|
+
args = def_args
|
741
|
+
end
|
742
|
+
|
743
|
+
AST::Types::Name::Instance.new(location: location, name: type_name, args: args)
|
611
744
|
end
|
612
745
|
end
|
613
746
|
end
|