steep 0.25.0 → 0.31.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 +47 -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.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 +265 -90
- 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 +13 -9
- data/lib/steep/ast/types/var.rb +2 -2
- data/lib/steep/ast/types/void.rb +1 -3
- 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.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 +5 -3
- 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 -31
- 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 +59 -2
- data/lib/steep/subtyping/check.rb +36 -50
- data/lib/steep/subtyping/constraints.rb +8 -0
- data/lib/steep/type_construction.rb +388 -366
- 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/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/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 +17 -13
- 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: e315b0a9541b0289ae3c9dd3acb19c2112e990a321176f94ed44f25d4190acb4
|
4
|
+
data.tar.gz: 9ce6e2024e81e5a2452fc5d7ca381decd1d91ed917d385dc280133652af51e06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd8db01573d1a2e31b362fb893bfad1325969b8343415d1bfd82428a76f0a6c8f8fe2875f7e474ab94244476e9901b1dda186f57cb90a49602638453826534a8
|
7
|
+
data.tar.gz: f1f30e2afc48265917468a4c5dd040fff3e226f92cb17441c3f3fcbba7f95aaa1002172ece399410d567358d9caf7bd80c1f1c27b9083c81a39e1abe61b74a68
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,53 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.31.0 (2020-10-04)
|
6
|
+
|
7
|
+
* Fix type checking performance ([#230](https://github.com/soutaro/steep/pull/230))
|
8
|
+
* Improve LSP completion/hover performance ([#232](https://github.com/soutaro/steep/pull/232))
|
9
|
+
* Fix instance variable completion ([#234](https://github.com/soutaro/steep/pull/234))
|
10
|
+
* Relax version requirements on Listen to allow installing on Ruby 3 ([#235](https://github.com/soutaro/steep/pull/235))
|
11
|
+
|
12
|
+
## 0.30.0 (2020-10-03)
|
13
|
+
|
14
|
+
* Let top-level defs be methods of Object ([#227](https://github.com/soutaro/steep/pull/227))
|
15
|
+
* Fix error caused by attribute definitions ([#228](https://github.com/soutaro/steep/pull/228))
|
16
|
+
* 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))
|
17
|
+
|
18
|
+
## 0.29.0 (2020-09-28)
|
19
|
+
|
20
|
+
* Implement reasoning on `is_a?`, `nil?`, and `===` methods. ([#218](https://github.com/soutaro/steep/pull/218))
|
21
|
+
* Better completion based on interface ([#215](https://github.com/soutaro/steep/pull/215))
|
22
|
+
* Fix begin-rescue typing ([#221](https://github.com/soutaro/steep/pull/221))
|
23
|
+
|
24
|
+
## 0.28.0 (2020-09-17)
|
25
|
+
|
26
|
+
* Fix typing case-when with empty body ([#200](https://github.com/soutaro/steep/pull/200))
|
27
|
+
* Fix lvasgn typing with `void` type hint ([#200](https://github.com/soutaro/steep/pull/200))
|
28
|
+
* Fix subtype checking between type variables and union types ([#200](https://github.com/soutaro/steep/pull/200))
|
29
|
+
* Support endless range ([#200](https://github.com/soutaro/steep/pull/200))
|
30
|
+
* Fix optarg, kwoptarg typing ([#202](https://github.com/soutaro/steep/pull/202))
|
31
|
+
* Better union/intersection types ([#204](https://github.com/soutaro/steep/pull/204))
|
32
|
+
* Fix generic method instantiation ([#205](https://github.com/soutaro/steep/pull/205))
|
33
|
+
* Fix module typing ([#206](https://github.com/soutaro/steep/pull/206))
|
34
|
+
* Fix shutdown problem ([#209](https://github.com/soutaro/steep/pull/209))
|
35
|
+
* Update RBS to 0.12.0 ([#210](https://github.com/soutaro/steep/pull/210))
|
36
|
+
* Improve processing singleton class decls without RBS ([#211](https://github.com/soutaro/steep/pull/211))
|
37
|
+
* Improve processing block parameter with masgn ([#212](https://github.com/soutaro/steep/pull/212))
|
38
|
+
|
39
|
+
## 0.27.0 (2020-08-31)
|
40
|
+
|
41
|
+
* Make tuple types _covariant_ ([#195](https://github.com/soutaro/steep/pull/195))
|
42
|
+
* Support `or_asgn`/`and_asgn` with `send` node lhs ([#194](https://github.com/soutaro/steep/pull/194))
|
43
|
+
* Performance improvement ([#193](https://github.com/soutaro/steep/pull/193))
|
44
|
+
* Add specialized versions of `#first` and `#last` on tuples ([#191](https://github.com/soutaro/steep/pull/191))
|
45
|
+
* Typing bug fix on `[]` (empty array) ([#190](https://github.com/soutaro/steep/pull/190))
|
46
|
+
* Earlier shutdown with interruption while `steep watch` ([#173](https://github.com/soutaro/steep/pull/173))
|
47
|
+
|
48
|
+
## 0.26.0
|
49
|
+
|
50
|
+
* Skipped
|
51
|
+
|
5
52
|
## 0.25.0 (2020-08-18)
|
6
53
|
|
7
54
|
* Improve `op_send` typing ([#186](https://github.com/soutaro/steep/pull/186))
|
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
|
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,17 @@ 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
|
+
|
10
|
+
attr_reader :type_interface_cache
|
11
|
+
|
7
12
|
def initialize(builder:)
|
8
13
|
@definition_builder = builder
|
14
|
+
|
15
|
+
@type_name_cache = {}
|
16
|
+
@type_cache = {}
|
17
|
+
@type_interface_cache = {}
|
9
18
|
end
|
10
19
|
|
11
20
|
def type_name_resolver
|
@@ -13,7 +22,9 @@ module Steep
|
|
13
22
|
end
|
14
23
|
|
15
24
|
def type(type)
|
16
|
-
|
25
|
+
ty = type_cache[type] and return ty
|
26
|
+
|
27
|
+
type_cache[type] = case type
|
17
28
|
when RBS::Types::Bases::Any
|
18
29
|
Any.new(location: nil)
|
19
30
|
when RBS::Types::Bases::Class
|
@@ -35,18 +46,18 @@ module Steep
|
|
35
46
|
when RBS::Types::Variable
|
36
47
|
Var.new(name: type.name, location: nil)
|
37
48
|
when RBS::Types::ClassSingleton
|
38
|
-
type_name =
|
39
|
-
Name::
|
49
|
+
type_name = type.name
|
50
|
+
Name::Singleton.new(name: type_name, location: nil)
|
40
51
|
when RBS::Types::ClassInstance
|
41
|
-
type_name =
|
52
|
+
type_name = type.name
|
42
53
|
args = type.args.map {|arg| type(arg) }
|
43
54
|
Name::Instance.new(name: type_name, args: args, location: nil)
|
44
55
|
when RBS::Types::Interface
|
45
|
-
type_name =
|
56
|
+
type_name = type.name
|
46
57
|
args = type.args.map {|arg| type(arg) }
|
47
58
|
Name::Interface.new(name: type_name, args: args, location: nil)
|
48
59
|
when RBS::Types::Alias
|
49
|
-
type_name =
|
60
|
+
type_name = type.name
|
50
61
|
Name::Alias.new(name: type_name, args: [], location: nil)
|
51
62
|
when RBS::Types::Union
|
52
63
|
Union.build(types: type.types.map {|ty| type(ty) }, location: nil)
|
@@ -94,23 +105,23 @@ module Steep
|
|
94
105
|
RBS::Types::Bases::Nil.new(location: nil)
|
95
106
|
when Var
|
96
107
|
RBS::Types::Variable.new(name: type.name, location: nil)
|
97
|
-
when Name::
|
98
|
-
RBS::Types::ClassSingleton.new(name:
|
108
|
+
when Name::Singleton
|
109
|
+
RBS::Types::ClassSingleton.new(name: type.name, location: nil)
|
99
110
|
when Name::Instance
|
100
111
|
RBS::Types::ClassInstance.new(
|
101
|
-
name:
|
112
|
+
name: type.name,
|
102
113
|
args: type.args.map {|arg| type_1(arg) },
|
103
114
|
location: nil
|
104
115
|
)
|
105
116
|
when Name::Interface
|
106
117
|
RBS::Types::Interface.new(
|
107
|
-
name:
|
118
|
+
name: type.name,
|
108
119
|
args: type.args.map {|arg| type_1(arg) },
|
109
120
|
location: nil
|
110
121
|
)
|
111
122
|
when Name::Alias
|
112
123
|
type.args.empty? or raise "alias type with args is not supported"
|
113
|
-
RBS::Types::Alias.new(name:
|
124
|
+
RBS::Types::Alias.new(name: type.name, location: nil)
|
114
125
|
when Union
|
115
126
|
RBS::Types::Union.new(
|
116
127
|
types: type.types.map {|ty| type_1(ty) },
|
@@ -143,29 +154,6 @@ module Steep
|
|
143
154
|
end
|
144
155
|
end
|
145
156
|
|
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
157
|
def function_1(params, return_type)
|
170
158
|
RBS::Types::Function.new(
|
171
159
|
required_positionals: params.required.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
@@ -190,7 +178,7 @@ module Steep
|
|
190
178
|
)
|
191
179
|
end
|
192
180
|
|
193
|
-
def method_type(method_type, self_type:)
|
181
|
+
def method_type(method_type, self_type:, subst2: nil, method_def: nil)
|
194
182
|
fvs = self_type.free_variables()
|
195
183
|
|
196
184
|
type_params = []
|
@@ -208,19 +196,21 @@ module Steep
|
|
208
196
|
end
|
209
197
|
end
|
210
198
|
subst = Interface::Substitution.build(alpha_vars, alpha_types)
|
199
|
+
subst.merge!(subst2, overwrite: true) if subst2
|
211
200
|
|
212
201
|
type = Interface::MethodType.new(
|
213
202
|
type_params: type_params,
|
214
203
|
return_type: type(method_type.type.return_type).subst(subst),
|
215
204
|
params: params(method_type.type).subst(subst),
|
216
|
-
location: nil,
|
217
205
|
block: method_type.block&.yield_self do |block|
|
218
206
|
Interface::Block.new(
|
219
207
|
optional: !block.required,
|
220
208
|
type: Proc.new(params: params(block.type).subst(subst),
|
221
209
|
return_type: type(block.type.return_type).subst(subst), location: nil)
|
222
210
|
)
|
223
|
-
end
|
211
|
+
end,
|
212
|
+
method_def: method_def,
|
213
|
+
location: method_def&.member&.location
|
224
214
|
)
|
225
215
|
|
226
216
|
if block_given?
|
@@ -280,7 +270,7 @@ module Steep
|
|
280
270
|
end
|
281
271
|
|
282
272
|
def unfold(type_name)
|
283
|
-
|
273
|
+
type_name.yield_self do |type_name|
|
284
274
|
type(definition_builder.expand_alias(type_name))
|
285
275
|
end
|
286
276
|
end
|
@@ -300,19 +290,129 @@ module Steep
|
|
300
290
|
end
|
301
291
|
end
|
302
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
|
+
|
303
394
|
def interface(type, private:, self_type: type)
|
304
|
-
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
|
305
401
|
|
306
402
|
case type
|
403
|
+
when Name::Alias
|
404
|
+
interface(expand_alias(type), private: private, self_type: self_type)
|
405
|
+
|
307
406
|
when Self
|
308
407
|
if self_type != type
|
309
408
|
interface self_type, private: private, self_type: Self.new
|
310
409
|
else
|
311
410
|
raise "Unexpected `self` type interface"
|
312
411
|
end
|
412
|
+
|
313
413
|
when Name::Instance
|
314
414
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
315
|
-
definition = definition_builder.build_instance(
|
415
|
+
definition = definition_builder.build_instance(type.name)
|
316
416
|
|
317
417
|
instance_type = Name::Instance.new(name: type.name,
|
318
418
|
args: type.args.map { Any.new(location: nil) },
|
@@ -328,20 +428,27 @@ module Steep
|
|
328
428
|
)
|
329
429
|
|
330
430
|
definition.methods.each do |name, method|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
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
|
339
446
|
end
|
340
447
|
end
|
341
448
|
|
342
449
|
when Name::Interface
|
343
450
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
344
|
-
type_name =
|
451
|
+
type_name = type.name
|
345
452
|
definition = definition_builder.build_interface(type_name)
|
346
453
|
|
347
454
|
subst = Interface::Substitution.build(
|
@@ -351,18 +458,17 @@ module Steep
|
|
351
458
|
)
|
352
459
|
|
353
460
|
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)
|
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
|
359
465
|
)
|
360
466
|
end
|
361
467
|
end
|
362
468
|
|
363
|
-
when Name::
|
469
|
+
when Name::Singleton
|
364
470
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
365
|
-
definition = definition_builder.build_singleton(
|
471
|
+
definition = definition_builder.build_singleton(type.name)
|
366
472
|
|
367
473
|
instance_type = Name::Instance.new(name: type.name,
|
368
474
|
args: definition.type_params.map {Any.new(location: nil)},
|
@@ -377,11 +483,16 @@ module Steep
|
|
377
483
|
definition.methods.each do |name, method|
|
378
484
|
next if !private && method.private?
|
379
485
|
|
380
|
-
interface.methods[name] = Interface::Interface::
|
381
|
-
method.
|
382
|
-
|
383
|
-
|
384
|
-
|
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
|
385
496
|
)
|
386
497
|
end
|
387
498
|
end
|
@@ -404,7 +515,25 @@ module Steep
|
|
404
515
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
405
516
|
common_methods = Set.new(interface1.methods.keys) & Set.new(interface2.methods.keys)
|
406
517
|
common_methods.each do |name|
|
407
|
-
|
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
|
408
537
|
end
|
409
538
|
end
|
410
539
|
end
|
@@ -415,11 +544,8 @@ module Steep
|
|
415
544
|
interfaces = type.types.map {|ty| interface(ty, private: private, self_type: self_type) }
|
416
545
|
interfaces.inject do |interface1, interface2|
|
417
546
|
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
|
547
|
+
interface.methods.merge!(interface1.methods)
|
548
|
+
interface.methods.merge!(interface2.methods)
|
423
549
|
end
|
424
550
|
end
|
425
551
|
end
|
@@ -430,8 +556,8 @@ module Steep
|
|
430
556
|
array_type = Builtin::Array.instance_type(element_type)
|
431
557
|
interface(array_type, private: private, self_type: self_type).tap do |array_interface|
|
432
558
|
array_interface.methods[:[]] = array_interface.methods[:[]].yield_self do |aref|
|
433
|
-
Interface::Interface::
|
434
|
-
type.types.map.with_index {|elem_type, index|
|
559
|
+
Interface::Interface::Entry.new(
|
560
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
435
561
|
Interface::MethodType.new(
|
436
562
|
type_params: [],
|
437
563
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index)],
|
@@ -442,16 +568,16 @@ module Steep
|
|
442
568
|
rest_keywords: nil),
|
443
569
|
block: nil,
|
444
570
|
return_type: elem_type,
|
571
|
+
method_def: nil,
|
445
572
|
location: nil
|
446
573
|
)
|
447
|
-
} + aref.
|
448
|
-
incompatible: false
|
574
|
+
} + aref.method_types
|
449
575
|
)
|
450
576
|
end
|
451
577
|
|
452
578
|
array_interface.methods[:[]=] = array_interface.methods[:[]=].yield_self do |update|
|
453
|
-
Interface::Interface::
|
454
|
-
type.types.map.with_index {|elem_type, index|
|
579
|
+
Interface::Interface::Entry.new(
|
580
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
455
581
|
Interface::MethodType.new(
|
456
582
|
type_params: [],
|
457
583
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
|
@@ -462,10 +588,40 @@ module Steep
|
|
462
588
|
rest_keywords: nil),
|
463
589
|
block: nil,
|
464
590
|
return_type: elem_type,
|
591
|
+
method_def: nil,
|
592
|
+
location: nil
|
593
|
+
)
|
594
|
+
} + update.method_types
|
595
|
+
)
|
596
|
+
end
|
597
|
+
|
598
|
+
array_interface.methods[:first] = array_interface.methods[:first].yield_self do |first|
|
599
|
+
Interface::Interface::Entry.new(
|
600
|
+
method_types: [
|
601
|
+
Interface::MethodType.new(
|
602
|
+
type_params: [],
|
603
|
+
params: Interface::Params.empty,
|
604
|
+
block: nil,
|
605
|
+
return_type: type.types[0] || AST::Builtin.nil_type,
|
606
|
+
method_def: nil,
|
607
|
+
location: nil
|
608
|
+
)
|
609
|
+
]
|
610
|
+
)
|
611
|
+
end
|
612
|
+
|
613
|
+
array_interface.methods[:last] = array_interface.methods[:last].yield_self do |last|
|
614
|
+
Interface::Interface::Entry.new(
|
615
|
+
method_types: [
|
616
|
+
Interface::MethodType.new(
|
617
|
+
type_params: [],
|
618
|
+
params: Interface::Params.empty,
|
619
|
+
block: nil,
|
620
|
+
return_type: type.types.last || AST::Builtin.nil_type,
|
621
|
+
method_def: nil,
|
465
622
|
location: nil
|
466
623
|
)
|
467
|
-
|
468
|
-
incompatible: false
|
624
|
+
]
|
469
625
|
)
|
470
626
|
end
|
471
627
|
end
|
@@ -481,8 +637,8 @@ module Steep
|
|
481
637
|
|
482
638
|
interface(hash_type, private: private, self_type: self_type).tap do |hash_interface|
|
483
639
|
hash_interface.methods[:[]] = hash_interface.methods[:[]].yield_self do |ref|
|
484
|
-
Interface::Interface::
|
485
|
-
type.elements.map {|key_value, value_type|
|
640
|
+
Interface::Interface::Entry.new(
|
641
|
+
method_types: type.elements.map {|key_value, value_type|
|
486
642
|
key_type = Literal.new(value: key_value, location: nil)
|
487
643
|
Interface::MethodType.new(
|
488
644
|
type_params: [],
|
@@ -494,16 +650,16 @@ module Steep
|
|
494
650
|
rest_keywords: nil),
|
495
651
|
block: nil,
|
496
652
|
return_type: value_type,
|
653
|
+
method_def: nil,
|
497
654
|
location: nil
|
498
655
|
)
|
499
|
-
} + ref.
|
500
|
-
incompatible: false
|
656
|
+
} + ref.method_types
|
501
657
|
)
|
502
658
|
end
|
503
659
|
|
504
660
|
hash_interface.methods[:[]=] = hash_interface.methods[:[]=].yield_self do |update|
|
505
|
-
Interface::Interface::
|
506
|
-
type.elements.map {|key_value, value_type|
|
661
|
+
Interface::Interface::Entry.new(
|
662
|
+
method_types: type.elements.map {|key_value, value_type|
|
507
663
|
key_type = Literal.new(value: key_value, location: nil)
|
508
664
|
Interface::MethodType.new(
|
509
665
|
type_params: [],
|
@@ -515,10 +671,10 @@ module Steep
|
|
515
671
|
rest_keywords: nil),
|
516
672
|
block: nil,
|
517
673
|
return_type: value_type,
|
674
|
+
method_def: nil,
|
518
675
|
location: nil
|
519
676
|
)
|
520
|
-
} + update.
|
521
|
-
incompatible: false
|
677
|
+
} + update.method_types
|
522
678
|
)
|
523
679
|
end
|
524
680
|
end
|
@@ -531,26 +687,30 @@ module Steep
|
|
531
687
|
params: type.params,
|
532
688
|
return_type: type.return_type,
|
533
689
|
block: nil,
|
690
|
+
method_def: nil,
|
534
691
|
location: nil
|
535
692
|
)
|
536
693
|
|
537
|
-
interface.methods[:[]] = Interface::Interface::
|
538
|
-
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])
|
539
696
|
end
|
540
697
|
|
698
|
+
when Logic::Base
|
699
|
+
interface(AST::Builtin.bool_type, private: private, self_type: self_type)
|
700
|
+
|
541
701
|
else
|
542
702
|
raise "Unexpected type for interface: #{type}"
|
703
|
+
end.tap do |interface|
|
704
|
+
type_interface_cache[cache_key] = interface
|
543
705
|
end
|
544
706
|
end
|
545
707
|
|
546
708
|
def module_name?(type_name)
|
547
|
-
|
548
|
-
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)
|
549
710
|
end
|
550
711
|
|
551
712
|
def class_name?(type_name)
|
552
|
-
|
553
|
-
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)
|
554
714
|
end
|
555
715
|
|
556
716
|
def env
|
@@ -565,7 +725,22 @@ module Steep
|
|
565
725
|
end
|
566
726
|
|
567
727
|
def absolute_type_name(type_name, namespace:)
|
568
|
-
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)
|
569
744
|
end
|
570
745
|
end
|
571
746
|
end
|