steep 0.27.0 → 0.31.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|