steep 0.23.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +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
|