steep 0.23.0 → 0.29.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 +46 -0
- data/bin/smoke_runner.rb +3 -4
- data/lib/steep.rb +4 -3
- data/lib/steep/annotation_parser.rb +2 -4
- data/lib/steep/ast/builtin.rb +11 -21
- data/lib/steep/ast/types.rb +5 -3
- data/lib/steep/ast/types/any.rb +1 -3
- data/lib/steep/ast/types/boolean.rb +1 -3
- data/lib/steep/ast/types/bot.rb +1 -3
- data/lib/steep/ast/types/class.rb +2 -2
- data/lib/steep/ast/types/factory.rb +249 -89
- data/lib/steep/ast/types/helper.rb +6 -0
- data/lib/steep/ast/types/instance.rb +2 -2
- data/lib/steep/ast/types/intersection.rb +20 -13
- data/lib/steep/ast/types/literal.rb +1 -3
- data/lib/steep/ast/types/logic.rb +63 -0
- data/lib/steep/ast/types/name.rb +15 -67
- data/lib/steep/ast/types/nil.rb +1 -3
- data/lib/steep/ast/types/proc.rb +5 -2
- data/lib/steep/ast/types/record.rb +9 -4
- data/lib/steep/ast/types/self.rb +1 -1
- data/lib/steep/ast/types/top.rb +1 -3
- data/lib/steep/ast/types/tuple.rb +5 -3
- data/lib/steep/ast/types/union.rb +16 -9
- data/lib/steep/ast/types/var.rb +2 -2
- data/lib/steep/ast/types/void.rb +1 -3
- data/lib/steep/drivers/check.rb +4 -0
- data/lib/steep/errors.rb +14 -0
- data/lib/steep/interface/interface.rb +5 -62
- data/lib/steep/interface/method_type.rb +394 -93
- data/lib/steep/interface/substitution.rb +48 -6
- data/lib/steep/module_helper.rb +25 -0
- data/lib/steep/project/completion_provider.rb +48 -51
- data/lib/steep/project/file.rb +3 -3
- data/lib/steep/project/hover_content.rb +4 -6
- data/lib/steep/project/target.rb +5 -2
- data/lib/steep/server/base_worker.rb +5 -3
- data/lib/steep/server/code_worker.rb +2 -0
- data/lib/steep/server/master.rb +10 -1
- data/lib/steep/signature/validator.rb +3 -3
- data/lib/steep/source.rb +4 -3
- data/lib/steep/subtyping/check.rb +46 -59
- data/lib/steep/subtyping/constraints.rb +8 -0
- data/lib/steep/type_construction.rb +771 -513
- data/lib/steep/type_inference/block_params.rb +5 -0
- data/lib/steep/type_inference/constant_env.rb +3 -6
- data/lib/steep/type_inference/context.rb +8 -0
- data/lib/steep/type_inference/context_array.rb +4 -3
- data/lib/steep/type_inference/logic.rb +31 -0
- data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
- data/lib/steep/type_inference/type_env.rb +2 -2
- data/lib/steep/typing.rb +7 -0
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +1 -1
- data/smoke/case/a.rb +1 -1
- data/smoke/hash/d.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/type_case/a.rb +0 -7
- data/steep.gemspec +2 -2
- metadata +10 -10
- 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: 5d09c66d40509db4956625f6be82477c4cda1b375d4cc37ebc2b4fdfdfdd971f
|
4
|
+
data.tar.gz: bfe074e9fc6e833faa4442f718e2bade7e54a5b6921fd8cf63465972ec39ced5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05d54b1565ccf9189d335163d952d075bd6f7b3a08c26362efb815c3d19cfd2ffa2eb13e124a5dc7a4a5f1343a6fbbe5694ed3d6000a4fe37f3ace4cb2d7c1d5
|
7
|
+
data.tar.gz: 2661d5a8a5273e5c4341b27fd78a5f57c296c31663f16d46bf8de39ea1af40b827bfdf48f9266e071a37b1fe395a58ec716149d88656cf983587ecbe89fa24e6
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,52 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.29.0 (2020-09-28)
|
6
|
+
|
7
|
+
* Implement reasoning on `is_a?`, `nil?`, and `===` methods. ([#218](https://github.com/soutaro/steep/pull/218))
|
8
|
+
* Better completion based on interface ([#215](https://github.com/soutaro/steep/pull/215))
|
9
|
+
* Fix begin-rescue typing ([#221](https://github.com/soutaro/steep/pull/221))
|
10
|
+
|
11
|
+
## 0.28.0 (2020-09-17)
|
12
|
+
|
13
|
+
* Fix typing case-when with empty body ([#200](https://github.com/soutaro/steep/pull/200))
|
14
|
+
* Fix lvasgn typing with `void` type hint ([#200](https://github.com/soutaro/steep/pull/200))
|
15
|
+
* Fix subtype checking between type variables and union types ([#200](https://github.com/soutaro/steep/pull/200))
|
16
|
+
* Support endless range ([#200](https://github.com/soutaro/steep/pull/200))
|
17
|
+
* Fix optarg, kwoptarg typing ([#202](https://github.com/soutaro/steep/pull/202))
|
18
|
+
* Better union/intersection types ([#204](https://github.com/soutaro/steep/pull/204))
|
19
|
+
* Fix generic method instantiation ([#205](https://github.com/soutaro/steep/pull/205))
|
20
|
+
* Fix module typing ([#206](https://github.com/soutaro/steep/pull/206))
|
21
|
+
* Fix shutdown problem ([#209](https://github.com/soutaro/steep/pull/209))
|
22
|
+
* Update RBS to 0.12.0 ([#210](https://github.com/soutaro/steep/pull/210))
|
23
|
+
* Improve processing singleton class decls without RBS ([#211](https://github.com/soutaro/steep/pull/211))
|
24
|
+
* Improve processing block parameter with masgn ([#212](https://github.com/soutaro/steep/pull/212))
|
25
|
+
|
26
|
+
## 0.27.0 (2020-08-31)
|
27
|
+
|
28
|
+
* Make tuple types _covariant_ ([#195](https://github.com/soutaro/steep/pull/195))
|
29
|
+
* Support `or_asgn`/`and_asgn` with `send` node lhs ([#194](https://github.com/soutaro/steep/pull/194))
|
30
|
+
* Performance improvement ([#193](https://github.com/soutaro/steep/pull/193))
|
31
|
+
* Add specialized versions of `#first` and `#last` on tuples ([#191](https://github.com/soutaro/steep/pull/191))
|
32
|
+
* Typing bug fix on `[]` (empty array) ([#190](https://github.com/soutaro/steep/pull/190))
|
33
|
+
* Earlier shutdown with interruption while `steep watch` ([#173](https://github.com/soutaro/steep/pull/173))
|
34
|
+
|
35
|
+
## 0.26.0
|
36
|
+
|
37
|
+
* Skipped
|
38
|
+
|
39
|
+
## 0.25.0 (2020-08-18)
|
40
|
+
|
41
|
+
* Improve `op_send` typing ([#186](https://github.com/soutaro/steep/pull/186))
|
42
|
+
* Improve `op_asgn` typing ([#189](https://github.com/soutaro/steep/pull/189))
|
43
|
+
* Better multi-assignment support ([#183](https://github.com/soutaro/steep/pull/183), [#184](https://github.com/soutaro/steep/pull/184))
|
44
|
+
* Support for loop and class variables ([#182](https://github.com/soutaro/steep/pull/182))
|
45
|
+
* Fix tuple typing ([#181](https://github.com/soutaro/steep/pull/181))
|
46
|
+
|
47
|
+
## 0.24.0 (2020-08-11)
|
48
|
+
|
49
|
+
* Update RBS to 0.10 ([#180](https://github.com/soutaro/steep/pull/180))
|
50
|
+
|
5
51
|
## 0.23.0 (2020-08-06)
|
6
52
|
|
7
53
|
* Fix literal typing with hint ([#179](https://github.com/soutaro/steep/pull/179))
|
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/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"
|
@@ -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
|
data/lib/steep/ast/types.rb
CHANGED
@@ -35,9 +35,11 @@ module Steep
|
|
35
35
|
"masked(#{type}|#{mask})"
|
36
36
|
end
|
37
37
|
|
38
|
-
def free_variables
|
39
|
-
|
40
|
-
|
38
|
+
def free_variables
|
39
|
+
@fvs ||= Set.new.tap do |set|
|
40
|
+
set.merge(type.free_variables)
|
41
|
+
set.merge(mask.free_variables)
|
42
|
+
end
|
41
43
|
end
|
42
44
|
|
43
45
|
def each_type(&block)
|
data/lib/steep/ast/types/any.rb
CHANGED
data/lib/steep/ast/types/bot.rb
CHANGED
@@ -4,8 +4,14 @@ module Steep
|
|
4
4
|
class Factory
|
5
5
|
attr_reader :definition_builder
|
6
6
|
|
7
|
+
attr_reader :type_name_cache
|
8
|
+
attr_reader :type_cache
|
9
|
+
|
7
10
|
def initialize(builder:)
|
8
11
|
@definition_builder = builder
|
12
|
+
|
13
|
+
@type_name_cache = {}
|
14
|
+
@type_cache = {}
|
9
15
|
end
|
10
16
|
|
11
17
|
def type_name_resolver
|
@@ -13,7 +19,9 @@ module Steep
|
|
13
19
|
end
|
14
20
|
|
15
21
|
def type(type)
|
16
|
-
|
22
|
+
ty = type_cache[type] and return ty
|
23
|
+
|
24
|
+
type_cache[type] = case type
|
17
25
|
when RBS::Types::Bases::Any
|
18
26
|
Any.new(location: nil)
|
19
27
|
when RBS::Types::Bases::Class
|
@@ -35,18 +43,18 @@ module Steep
|
|
35
43
|
when RBS::Types::Variable
|
36
44
|
Var.new(name: type.name, location: nil)
|
37
45
|
when RBS::Types::ClassSingleton
|
38
|
-
type_name =
|
39
|
-
Name::
|
46
|
+
type_name = type.name
|
47
|
+
Name::Singleton.new(name: type_name, location: nil)
|
40
48
|
when RBS::Types::ClassInstance
|
41
|
-
type_name =
|
49
|
+
type_name = type.name
|
42
50
|
args = type.args.map {|arg| type(arg) }
|
43
51
|
Name::Instance.new(name: type_name, args: args, location: nil)
|
44
52
|
when RBS::Types::Interface
|
45
|
-
type_name =
|
53
|
+
type_name = type.name
|
46
54
|
args = type.args.map {|arg| type(arg) }
|
47
55
|
Name::Interface.new(name: type_name, args: args, location: nil)
|
48
56
|
when RBS::Types::Alias
|
49
|
-
type_name =
|
57
|
+
type_name = type.name
|
50
58
|
Name::Alias.new(name: type_name, args: [], location: nil)
|
51
59
|
when RBS::Types::Union
|
52
60
|
Union.build(types: type.types.map {|ty| type(ty) }, location: nil)
|
@@ -94,23 +102,23 @@ module Steep
|
|
94
102
|
RBS::Types::Bases::Nil.new(location: nil)
|
95
103
|
when Var
|
96
104
|
RBS::Types::Variable.new(name: type.name, location: nil)
|
97
|
-
when Name::
|
98
|
-
RBS::Types::ClassSingleton.new(name:
|
105
|
+
when Name::Singleton
|
106
|
+
RBS::Types::ClassSingleton.new(name: type.name, location: nil)
|
99
107
|
when Name::Instance
|
100
108
|
RBS::Types::ClassInstance.new(
|
101
|
-
name:
|
109
|
+
name: type.name,
|
102
110
|
args: type.args.map {|arg| type_1(arg) },
|
103
111
|
location: nil
|
104
112
|
)
|
105
113
|
when Name::Interface
|
106
114
|
RBS::Types::Interface.new(
|
107
|
-
name:
|
115
|
+
name: type.name,
|
108
116
|
args: type.args.map {|arg| type_1(arg) },
|
109
117
|
location: nil
|
110
118
|
)
|
111
119
|
when Name::Alias
|
112
120
|
type.args.empty? or raise "alias type with args is not supported"
|
113
|
-
RBS::Types::Alias.new(name:
|
121
|
+
RBS::Types::Alias.new(name: type.name, location: nil)
|
114
122
|
when Union
|
115
123
|
RBS::Types::Union.new(
|
116
124
|
types: type.types.map {|ty| type_1(ty) },
|
@@ -143,29 +151,6 @@ module Steep
|
|
143
151
|
end
|
144
152
|
end
|
145
153
|
|
146
|
-
def type_name(name)
|
147
|
-
case
|
148
|
-
when name.class?
|
149
|
-
Names::Module.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
150
|
-
when name.interface?
|
151
|
-
Names::Interface.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
152
|
-
when name.alias?
|
153
|
-
Names::Alias.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def type_name_1(name)
|
158
|
-
RBS::TypeName.new(name: name.name, namespace: namespace_1(name.namespace))
|
159
|
-
end
|
160
|
-
|
161
|
-
def namespace(namespace)
|
162
|
-
Namespace.parse(namespace.to_s)
|
163
|
-
end
|
164
|
-
|
165
|
-
def namespace_1(namespace)
|
166
|
-
RBS::Namespace.parse(namespace.to_s)
|
167
|
-
end
|
168
|
-
|
169
154
|
def function_1(params, return_type)
|
170
155
|
RBS::Types::Function.new(
|
171
156
|
required_positionals: params.required.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
@@ -190,7 +175,7 @@ module Steep
|
|
190
175
|
)
|
191
176
|
end
|
192
177
|
|
193
|
-
def method_type(method_type, self_type:)
|
178
|
+
def method_type(method_type, self_type:, subst2: nil, method_def: nil)
|
194
179
|
fvs = self_type.free_variables()
|
195
180
|
|
196
181
|
type_params = []
|
@@ -208,19 +193,21 @@ module Steep
|
|
208
193
|
end
|
209
194
|
end
|
210
195
|
subst = Interface::Substitution.build(alpha_vars, alpha_types)
|
196
|
+
subst.merge!(subst2, overwrite: true) if subst2
|
211
197
|
|
212
198
|
type = Interface::MethodType.new(
|
213
199
|
type_params: type_params,
|
214
200
|
return_type: type(method_type.type.return_type).subst(subst),
|
215
201
|
params: params(method_type.type).subst(subst),
|
216
|
-
location: nil,
|
217
202
|
block: method_type.block&.yield_self do |block|
|
218
203
|
Interface::Block.new(
|
219
204
|
optional: !block.required,
|
220
205
|
type: Proc.new(params: params(block.type).subst(subst),
|
221
206
|
return_type: type(block.type.return_type).subst(subst), location: nil)
|
222
207
|
)
|
223
|
-
end
|
208
|
+
end,
|
209
|
+
method_def: method_def,
|
210
|
+
location: method_def&.member&.location
|
224
211
|
)
|
225
212
|
|
226
213
|
if block_given?
|
@@ -280,7 +267,7 @@ module Steep
|
|
280
267
|
end
|
281
268
|
|
282
269
|
def unfold(type_name)
|
283
|
-
|
270
|
+
type_name.yield_self do |type_name|
|
284
271
|
type(definition_builder.expand_alias(type_name))
|
285
272
|
end
|
286
273
|
end
|
@@ -300,7 +287,107 @@ module Steep
|
|
300
287
|
end
|
301
288
|
end
|
302
289
|
|
290
|
+
def deep_expand_alias(type, recursive: Set.new, &block)
|
291
|
+
raise "Recursive type definition: #{type}" if recursive.member?(type)
|
292
|
+
|
293
|
+
ty = case type
|
294
|
+
when AST::Types::Name::Alias
|
295
|
+
deep_expand_alias(expand_alias(type), recursive: recursive.union([type]))
|
296
|
+
when AST::Types::Union
|
297
|
+
AST::Types::Union.build(
|
298
|
+
types: type.types.map {|ty| deep_expand_alias(ty, recursive: recursive, &block) },
|
299
|
+
location: type.location
|
300
|
+
)
|
301
|
+
else
|
302
|
+
type
|
303
|
+
end
|
304
|
+
|
305
|
+
if block_given?
|
306
|
+
yield ty
|
307
|
+
else
|
308
|
+
ty
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def flatten_union(type, acc = [])
|
313
|
+
case type
|
314
|
+
when AST::Types::Union
|
315
|
+
type.types.each {|ty| flatten_union(ty, acc) }
|
316
|
+
else
|
317
|
+
acc << type
|
318
|
+
end
|
319
|
+
|
320
|
+
acc
|
321
|
+
end
|
322
|
+
|
323
|
+
def unwrap_optional(type)
|
324
|
+
case type
|
325
|
+
when AST::Types::Union
|
326
|
+
falsy_types, truthy_types = type.types.partition do |type|
|
327
|
+
(type.is_a?(AST::Types::Literal) && type.value == false) ||
|
328
|
+
type.is_a?(AST::Types::Nil)
|
329
|
+
end
|
330
|
+
|
331
|
+
[
|
332
|
+
AST::Types::Union.build(types: truthy_types),
|
333
|
+
AST::Types::Union.build(types: falsy_types)
|
334
|
+
]
|
335
|
+
when AST::Types::Name::Alias
|
336
|
+
unwrap_optional(expand_alias(type))
|
337
|
+
else
|
338
|
+
[type, nil]
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def setup_primitives(method_name, method_type)
|
343
|
+
if method_def = method_type.method_def
|
344
|
+
defined_in = method_def.defined_in
|
345
|
+
member = method_def.member
|
346
|
+
|
347
|
+
case
|
348
|
+
when defined_in == RBS::BuiltinNames::Object.name && member.instance?
|
349
|
+
case method_name
|
350
|
+
when :is_a?, :kind_of?, :instance_of?
|
351
|
+
return method_type.with(
|
352
|
+
return_type: AST::Types::Logic::ReceiverIsArg.new(location: method_type.return_type.location)
|
353
|
+
)
|
354
|
+
when :nil?
|
355
|
+
return method_type.with(
|
356
|
+
return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.return_type.location)
|
357
|
+
)
|
358
|
+
end
|
359
|
+
|
360
|
+
when defined_in == AST::Builtin::NilClass.module_name && member.instance?
|
361
|
+
case method_name
|
362
|
+
when :nil?
|
363
|
+
return method_type.with(
|
364
|
+
return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.return_type.location)
|
365
|
+
)
|
366
|
+
end
|
367
|
+
|
368
|
+
when defined_in == RBS::BuiltinNames::BasicObject.name && member.instance?
|
369
|
+
case method_name
|
370
|
+
when :!
|
371
|
+
return method_type.with(
|
372
|
+
return_type: AST::Types::Logic::Not.new(location: method_type.return_type.location)
|
373
|
+
)
|
374
|
+
end
|
375
|
+
|
376
|
+
when defined_in == RBS::BuiltinNames::Module.name && member.instance?
|
377
|
+
case method_name
|
378
|
+
when :===
|
379
|
+
return method_type.with(
|
380
|
+
return_type: AST::Types::Logic::ArgIsReceiver.new(location: method_type.return_type.location)
|
381
|
+
)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
method_type
|
387
|
+
end
|
388
|
+
|
303
389
|
def interface(type, private:, self_type: type)
|
390
|
+
Steep.logger.debug { "Factory#interface: #{type}, private=#{private}, self_type=#{self_type}" }
|
304
391
|
type = expand_alias(type)
|
305
392
|
|
306
393
|
case type
|
@@ -312,7 +399,7 @@ module Steep
|
|
312
399
|
end
|
313
400
|
when Name::Instance
|
314
401
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
315
|
-
definition = definition_builder.build_instance(
|
402
|
+
definition = definition_builder.build_instance(type.name)
|
316
403
|
|
317
404
|
instance_type = Name::Instance.new(name: type.name,
|
318
405
|
args: type.args.map { Any.new(location: nil) },
|
@@ -328,20 +415,27 @@ module Steep
|
|
328
415
|
)
|
329
416
|
|
330
417
|
definition.methods.each do |name, method|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
418
|
+
Steep.logger.tagged "method = #{name}" do
|
419
|
+
next if method.private? && !private
|
420
|
+
|
421
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
422
|
+
method_types: method.defs.map do |type_def|
|
423
|
+
setup_primitives(
|
424
|
+
name,
|
425
|
+
method_type(type_def.type,
|
426
|
+
method_def: type_def,
|
427
|
+
self_type: self_type,
|
428
|
+
subst2: subst)
|
429
|
+
)
|
430
|
+
end
|
431
|
+
)
|
432
|
+
end
|
339
433
|
end
|
340
434
|
end
|
341
435
|
|
342
436
|
when Name::Interface
|
343
437
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
344
|
-
type_name =
|
438
|
+
type_name = type.name
|
345
439
|
definition = definition_builder.build_interface(type_name)
|
346
440
|
|
347
441
|
subst = Interface::Substitution.build(
|
@@ -351,18 +445,17 @@ module Steep
|
|
351
445
|
)
|
352
446
|
|
353
447
|
definition.methods.each do |name, method|
|
354
|
-
interface.methods[name] = Interface::Interface::
|
355
|
-
method.
|
356
|
-
method_type(type, self_type: self_type
|
357
|
-
end
|
358
|
-
incompatible: method.attributes.include?(:incompatible)
|
448
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
449
|
+
method_types: method.defs.map do |type_def|
|
450
|
+
method_type(type_def.type, method_def: type_def, self_type: self_type, subst2: subst)
|
451
|
+
end
|
359
452
|
)
|
360
453
|
end
|
361
454
|
end
|
362
455
|
|
363
|
-
when Name::
|
456
|
+
when Name::Singleton
|
364
457
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
365
|
-
definition = definition_builder.build_singleton(
|
458
|
+
definition = definition_builder.build_singleton(type.name)
|
366
459
|
|
367
460
|
instance_type = Name::Instance.new(name: type.name,
|
368
461
|
args: definition.type_params.map {Any.new(location: nil)},
|
@@ -377,11 +470,16 @@ module Steep
|
|
377
470
|
definition.methods.each do |name, method|
|
378
471
|
next if !private && method.private?
|
379
472
|
|
380
|
-
interface.methods[name] = Interface::Interface::
|
381
|
-
method.
|
382
|
-
|
383
|
-
|
384
|
-
|
473
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
474
|
+
method_types: method.defs.map do |type_def|
|
475
|
+
setup_primitives(
|
476
|
+
name,
|
477
|
+
method_type(type_def.type,
|
478
|
+
method_def: type_def,
|
479
|
+
self_type: self_type,
|
480
|
+
subst2: subst)
|
481
|
+
)
|
482
|
+
end
|
385
483
|
)
|
386
484
|
end
|
387
485
|
end
|
@@ -404,7 +502,25 @@ module Steep
|
|
404
502
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
405
503
|
common_methods = Set.new(interface1.methods.keys) & Set.new(interface2.methods.keys)
|
406
504
|
common_methods.each do |name|
|
407
|
-
|
505
|
+
types1 = interface1.methods[name].method_types
|
506
|
+
types2 = interface2.methods[name].method_types
|
507
|
+
|
508
|
+
if types1 == types2
|
509
|
+
interface.methods[name] = interface1.methods[name]
|
510
|
+
else
|
511
|
+
method_types = {}
|
512
|
+
|
513
|
+
types1.each do |type1|
|
514
|
+
types2.each do |type2|
|
515
|
+
type = type1 | type2 or next
|
516
|
+
method_types[type] = true
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
unless method_types.empty?
|
521
|
+
interface.methods[name] = Interface::Interface::Entry.new(method_types: method_types.keys)
|
522
|
+
end
|
523
|
+
end
|
408
524
|
end
|
409
525
|
end
|
410
526
|
end
|
@@ -415,11 +531,8 @@ module Steep
|
|
415
531
|
interfaces = type.types.map {|ty| interface(ty, private: private, self_type: self_type) }
|
416
532
|
interfaces.inject do |interface1, interface2|
|
417
533
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
418
|
-
|
419
|
-
|
420
|
-
methods = [interface1.methods[name], interface2.methods[name]].compact
|
421
|
-
interface.methods[name] = Interface::Interface::Combination.intersection(methods)
|
422
|
-
end
|
534
|
+
interface.methods.merge!(interface1.methods)
|
535
|
+
interface.methods.merge!(interface2.methods)
|
423
536
|
end
|
424
537
|
end
|
425
538
|
end
|
@@ -430,8 +543,8 @@ module Steep
|
|
430
543
|
array_type = Builtin::Array.instance_type(element_type)
|
431
544
|
interface(array_type, private: private, self_type: self_type).tap do |array_interface|
|
432
545
|
array_interface.methods[:[]] = array_interface.methods[:[]].yield_self do |aref|
|
433
|
-
Interface::Interface::
|
434
|
-
type.types.map.with_index {|elem_type, index|
|
546
|
+
Interface::Interface::Entry.new(
|
547
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
435
548
|
Interface::MethodType.new(
|
436
549
|
type_params: [],
|
437
550
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index)],
|
@@ -442,16 +555,16 @@ module Steep
|
|
442
555
|
rest_keywords: nil),
|
443
556
|
block: nil,
|
444
557
|
return_type: elem_type,
|
558
|
+
method_def: nil,
|
445
559
|
location: nil
|
446
560
|
)
|
447
|
-
} + aref.
|
448
|
-
incompatible: false
|
561
|
+
} + aref.method_types
|
449
562
|
)
|
450
563
|
end
|
451
564
|
|
452
565
|
array_interface.methods[:[]=] = array_interface.methods[:[]=].yield_self do |update|
|
453
|
-
Interface::Interface::
|
454
|
-
type.types.map.with_index {|elem_type, index|
|
566
|
+
Interface::Interface::Entry.new(
|
567
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
455
568
|
Interface::MethodType.new(
|
456
569
|
type_params: [],
|
457
570
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
|
@@ -462,10 +575,40 @@ module Steep
|
|
462
575
|
rest_keywords: nil),
|
463
576
|
block: nil,
|
464
577
|
return_type: elem_type,
|
578
|
+
method_def: nil,
|
465
579
|
location: nil
|
466
580
|
)
|
467
|
-
} + update.
|
468
|
-
|
581
|
+
} + update.method_types
|
582
|
+
)
|
583
|
+
end
|
584
|
+
|
585
|
+
array_interface.methods[:first] = array_interface.methods[:first].yield_self do |first|
|
586
|
+
Interface::Interface::Entry.new(
|
587
|
+
method_types: [
|
588
|
+
Interface::MethodType.new(
|
589
|
+
type_params: [],
|
590
|
+
params: Interface::Params.empty,
|
591
|
+
block: nil,
|
592
|
+
return_type: type.types[0] || AST::Builtin.nil_type,
|
593
|
+
method_def: nil,
|
594
|
+
location: nil
|
595
|
+
)
|
596
|
+
]
|
597
|
+
)
|
598
|
+
end
|
599
|
+
|
600
|
+
array_interface.methods[:last] = array_interface.methods[:last].yield_self do |last|
|
601
|
+
Interface::Interface::Entry.new(
|
602
|
+
method_types: [
|
603
|
+
Interface::MethodType.new(
|
604
|
+
type_params: [],
|
605
|
+
params: Interface::Params.empty,
|
606
|
+
block: nil,
|
607
|
+
return_type: type.types.last || AST::Builtin.nil_type,
|
608
|
+
method_def: nil,
|
609
|
+
location: nil
|
610
|
+
)
|
611
|
+
]
|
469
612
|
)
|
470
613
|
end
|
471
614
|
end
|
@@ -481,8 +624,8 @@ module Steep
|
|
481
624
|
|
482
625
|
interface(hash_type, private: private, self_type: self_type).tap do |hash_interface|
|
483
626
|
hash_interface.methods[:[]] = hash_interface.methods[:[]].yield_self do |ref|
|
484
|
-
Interface::Interface::
|
485
|
-
type.elements.map {|key_value, value_type|
|
627
|
+
Interface::Interface::Entry.new(
|
628
|
+
method_types: type.elements.map {|key_value, value_type|
|
486
629
|
key_type = Literal.new(value: key_value, location: nil)
|
487
630
|
Interface::MethodType.new(
|
488
631
|
type_params: [],
|
@@ -494,16 +637,16 @@ module Steep
|
|
494
637
|
rest_keywords: nil),
|
495
638
|
block: nil,
|
496
639
|
return_type: value_type,
|
640
|
+
method_def: nil,
|
497
641
|
location: nil
|
498
642
|
)
|
499
|
-
} + ref.
|
500
|
-
incompatible: false
|
643
|
+
} + ref.method_types
|
501
644
|
)
|
502
645
|
end
|
503
646
|
|
504
647
|
hash_interface.methods[:[]=] = hash_interface.methods[:[]=].yield_self do |update|
|
505
|
-
Interface::Interface::
|
506
|
-
type.elements.map {|key_value, value_type|
|
648
|
+
Interface::Interface::Entry.new(
|
649
|
+
method_types: type.elements.map {|key_value, value_type|
|
507
650
|
key_type = Literal.new(value: key_value, location: nil)
|
508
651
|
Interface::MethodType.new(
|
509
652
|
type_params: [],
|
@@ -515,10 +658,10 @@ module Steep
|
|
515
658
|
rest_keywords: nil),
|
516
659
|
block: nil,
|
517
660
|
return_type: value_type,
|
661
|
+
method_def: nil,
|
518
662
|
location: nil
|
519
663
|
)
|
520
|
-
} + update.
|
521
|
-
incompatible: false
|
664
|
+
} + update.method_types
|
522
665
|
)
|
523
666
|
end
|
524
667
|
end
|
@@ -531,26 +674,28 @@ module Steep
|
|
531
674
|
params: type.params,
|
532
675
|
return_type: type.return_type,
|
533
676
|
block: nil,
|
677
|
+
method_def: nil,
|
534
678
|
location: nil
|
535
679
|
)
|
536
680
|
|
537
|
-
interface.methods[:[]] = Interface::Interface::
|
538
|
-
interface.methods[:call] = Interface::Interface::
|
681
|
+
interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type])
|
682
|
+
interface.methods[:call] = Interface::Interface::Entry.new(method_types: [method_type])
|
539
683
|
end
|
540
684
|
|
685
|
+
when Logic::Base
|
686
|
+
interface(AST::Builtin.bool_type, private: private, self_type: self_type)
|
687
|
+
|
541
688
|
else
|
542
689
|
raise "Unexpected type for interface: #{type}"
|
543
690
|
end
|
544
691
|
end
|
545
692
|
|
546
693
|
def module_name?(type_name)
|
547
|
-
|
548
|
-
entry = env.class_decls[name] and entry.is_a?(RBS::Environment::ModuleEntry)
|
694
|
+
entry = env.class_decls[type_name] and entry.is_a?(RBS::Environment::ModuleEntry)
|
549
695
|
end
|
550
696
|
|
551
697
|
def class_name?(type_name)
|
552
|
-
|
553
|
-
entry = env.class_decls[name] and entry.is_a?(RBS::Environment::ClassEntry)
|
698
|
+
entry = env.class_decls[type_name] and entry.is_a?(RBS::Environment::ClassEntry)
|
554
699
|
end
|
555
700
|
|
556
701
|
def env
|
@@ -565,7 +710,22 @@ module Steep
|
|
565
710
|
end
|
566
711
|
|
567
712
|
def absolute_type_name(type_name, namespace:)
|
568
|
-
type_name_resolver.resolve(type_name, context:
|
713
|
+
type_name_resolver.resolve(type_name, context: namespace.ascend)
|
714
|
+
end
|
715
|
+
|
716
|
+
def instance_type(type_name, args: nil, location: nil)
|
717
|
+
raise unless type_name.class?
|
718
|
+
|
719
|
+
definition = definition_builder.build_singleton(type_name)
|
720
|
+
def_args = definition.type_params.map { Any.new(location: nil) }
|
721
|
+
|
722
|
+
if args
|
723
|
+
raise if def_args.size != args.size
|
724
|
+
else
|
725
|
+
args = def_args
|
726
|
+
end
|
727
|
+
|
728
|
+
AST::Types::Name::Instance.new(location: location, name: type_name, args: args)
|
569
729
|
end
|
570
730
|
end
|
571
731
|
end
|