steep 0.24.0 → 0.30.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 +48 -0
- data/bin/smoke_runner.rb +3 -4
- 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 +251 -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.rb +25 -0
- data/lib/steep/project/completion_provider.rb +48 -51
- data/lib/steep/project/file_loader.rb +7 -2
- data/lib/steep/project/hover_content.rb +4 -6
- 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 +36 -14
- data/lib/steep/server/base_worker.rb +5 -3
- data/lib/steep/server/code_worker.rb +31 -45
- 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 +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/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 +2 -2
- metadata +15 -11
- 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: b5293cbc87834cee36e50cb66bab84e466a5182c1e868732b7bd3e685b2bd954
|
4
|
+
data.tar.gz: 7794e42573b5ac04c74780824213cfbe1ca255f1feaa4465a1066377d2647e0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e723bf77a7452e0696c38d6d1797e71f246fb97d1b1f18082ba21b8eadb8174d6bcc4deda872898b5f39d162b91173c413cacfa28175018517170f8f2568bd70
|
7
|
+
data.tar.gz: 38dbe78df43706fe33d5350ad04524c25606955bcba5397ad18690717a60c59d361485ad2d5d3077787336d23902bd91ba9fa5b31e1933a93d1fe32747837688
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,54 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.30.0 (2020-10-03)
|
6
|
+
|
7
|
+
* Let top-level defs be methods of Object ([#227](https://github.com/soutaro/steep/pull/227))
|
8
|
+
* Fix error caused by attribute definitions ([#228](https://github.com/soutaro/steep/pull/228))
|
9
|
+
* 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))
|
10
|
+
|
11
|
+
## 0.29.0 (2020-09-28)
|
12
|
+
|
13
|
+
* Implement reasoning on `is_a?`, `nil?`, and `===` methods. ([#218](https://github.com/soutaro/steep/pull/218))
|
14
|
+
* Better completion based on interface ([#215](https://github.com/soutaro/steep/pull/215))
|
15
|
+
* Fix begin-rescue typing ([#221](https://github.com/soutaro/steep/pull/221))
|
16
|
+
|
17
|
+
## 0.28.0 (2020-09-17)
|
18
|
+
|
19
|
+
* Fix typing case-when with empty body ([#200](https://github.com/soutaro/steep/pull/200))
|
20
|
+
* Fix lvasgn typing with `void` type hint ([#200](https://github.com/soutaro/steep/pull/200))
|
21
|
+
* Fix subtype checking between type variables and union types ([#200](https://github.com/soutaro/steep/pull/200))
|
22
|
+
* Support endless range ([#200](https://github.com/soutaro/steep/pull/200))
|
23
|
+
* Fix optarg, kwoptarg typing ([#202](https://github.com/soutaro/steep/pull/202))
|
24
|
+
* Better union/intersection types ([#204](https://github.com/soutaro/steep/pull/204))
|
25
|
+
* Fix generic method instantiation ([#205](https://github.com/soutaro/steep/pull/205))
|
26
|
+
* Fix module typing ([#206](https://github.com/soutaro/steep/pull/206))
|
27
|
+
* Fix shutdown problem ([#209](https://github.com/soutaro/steep/pull/209))
|
28
|
+
* Update RBS to 0.12.0 ([#210](https://github.com/soutaro/steep/pull/210))
|
29
|
+
* Improve processing singleton class decls without RBS ([#211](https://github.com/soutaro/steep/pull/211))
|
30
|
+
* Improve processing block parameter with masgn ([#212](https://github.com/soutaro/steep/pull/212))
|
31
|
+
|
32
|
+
## 0.27.0 (2020-08-31)
|
33
|
+
|
34
|
+
* Make tuple types _covariant_ ([#195](https://github.com/soutaro/steep/pull/195))
|
35
|
+
* Support `or_asgn`/`and_asgn` with `send` node lhs ([#194](https://github.com/soutaro/steep/pull/194))
|
36
|
+
* Performance improvement ([#193](https://github.com/soutaro/steep/pull/193))
|
37
|
+
* Add specialized versions of `#first` and `#last` on tuples ([#191](https://github.com/soutaro/steep/pull/191))
|
38
|
+
* Typing bug fix on `[]` (empty array) ([#190](https://github.com/soutaro/steep/pull/190))
|
39
|
+
* Earlier shutdown with interruption while `steep watch` ([#173](https://github.com/soutaro/steep/pull/173))
|
40
|
+
|
41
|
+
## 0.26.0
|
42
|
+
|
43
|
+
* Skipped
|
44
|
+
|
45
|
+
## 0.25.0 (2020-08-18)
|
46
|
+
|
47
|
+
* Improve `op_send` typing ([#186](https://github.com/soutaro/steep/pull/186))
|
48
|
+
* Improve `op_asgn` typing ([#189](https://github.com/soutaro/steep/pull/189))
|
49
|
+
* Better multi-assignment support ([#183](https://github.com/soutaro/steep/pull/183), [#184](https://github.com/soutaro/steep/pull/184))
|
50
|
+
* Support for loop and class variables ([#182](https://github.com/soutaro/steep/pull/182))
|
51
|
+
* Fix tuple typing ([#181](https://github.com/soutaro/steep/pull/181))
|
52
|
+
|
5
53
|
## 0.24.0 (2020-08-11)
|
6
54
|
|
7
55
|
* Update RBS to 0.10 ([#180](https://github.com/soutaro/steep/pull/180))
|
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"
|
@@ -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,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,109 @@ 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
|
+
if member.is_a?(RBS::AST::Members::MethodDefinition)
|
348
|
+
case
|
349
|
+
when defined_in == RBS::BuiltinNames::Object.name && member.instance?
|
350
|
+
case method_name
|
351
|
+
when :is_a?, :kind_of?, :instance_of?
|
352
|
+
return method_type.with(
|
353
|
+
return_type: AST::Types::Logic::ReceiverIsArg.new(location: method_type.return_type.location)
|
354
|
+
)
|
355
|
+
when :nil?
|
356
|
+
return method_type.with(
|
357
|
+
return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.return_type.location)
|
358
|
+
)
|
359
|
+
end
|
360
|
+
|
361
|
+
when defined_in == AST::Builtin::NilClass.module_name && member.instance?
|
362
|
+
case method_name
|
363
|
+
when :nil?
|
364
|
+
return method_type.with(
|
365
|
+
return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.return_type.location)
|
366
|
+
)
|
367
|
+
end
|
368
|
+
|
369
|
+
when defined_in == RBS::BuiltinNames::BasicObject.name && member.instance?
|
370
|
+
case method_name
|
371
|
+
when :!
|
372
|
+
return method_type.with(
|
373
|
+
return_type: AST::Types::Logic::Not.new(location: method_type.return_type.location)
|
374
|
+
)
|
375
|
+
end
|
376
|
+
|
377
|
+
when defined_in == RBS::BuiltinNames::Module.name && member.instance?
|
378
|
+
case method_name
|
379
|
+
when :===
|
380
|
+
return method_type.with(
|
381
|
+
return_type: AST::Types::Logic::ArgIsReceiver.new(location: method_type.return_type.location)
|
382
|
+
)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
method_type
|
389
|
+
end
|
390
|
+
|
303
391
|
def interface(type, private:, self_type: type)
|
392
|
+
Steep.logger.debug { "Factory#interface: #{type}, private=#{private}, self_type=#{self_type}" }
|
304
393
|
type = expand_alias(type)
|
305
394
|
|
306
395
|
case type
|
@@ -312,7 +401,7 @@ module Steep
|
|
312
401
|
end
|
313
402
|
when Name::Instance
|
314
403
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
315
|
-
definition = definition_builder.build_instance(
|
404
|
+
definition = definition_builder.build_instance(type.name)
|
316
405
|
|
317
406
|
instance_type = Name::Instance.new(name: type.name,
|
318
407
|
args: type.args.map { Any.new(location: nil) },
|
@@ -328,20 +417,27 @@ module Steep
|
|
328
417
|
)
|
329
418
|
|
330
419
|
definition.methods.each do |name, method|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
420
|
+
Steep.logger.tagged "method = #{name}" do
|
421
|
+
next if method.private? && !private
|
422
|
+
|
423
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
424
|
+
method_types: method.defs.map do |type_def|
|
425
|
+
setup_primitives(
|
426
|
+
name,
|
427
|
+
method_type(type_def.type,
|
428
|
+
method_def: type_def,
|
429
|
+
self_type: self_type,
|
430
|
+
subst2: subst)
|
431
|
+
)
|
432
|
+
end
|
433
|
+
)
|
434
|
+
end
|
339
435
|
end
|
340
436
|
end
|
341
437
|
|
342
438
|
when Name::Interface
|
343
439
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
344
|
-
type_name =
|
440
|
+
type_name = type.name
|
345
441
|
definition = definition_builder.build_interface(type_name)
|
346
442
|
|
347
443
|
subst = Interface::Substitution.build(
|
@@ -351,18 +447,17 @@ module Steep
|
|
351
447
|
)
|
352
448
|
|
353
449
|
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)
|
450
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
451
|
+
method_types: method.defs.map do |type_def|
|
452
|
+
method_type(type_def.type, method_def: type_def, self_type: self_type, subst2: subst)
|
453
|
+
end
|
359
454
|
)
|
360
455
|
end
|
361
456
|
end
|
362
457
|
|
363
|
-
when Name::
|
458
|
+
when Name::Singleton
|
364
459
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
365
|
-
definition = definition_builder.build_singleton(
|
460
|
+
definition = definition_builder.build_singleton(type.name)
|
366
461
|
|
367
462
|
instance_type = Name::Instance.new(name: type.name,
|
368
463
|
args: definition.type_params.map {Any.new(location: nil)},
|
@@ -377,11 +472,16 @@ module Steep
|
|
377
472
|
definition.methods.each do |name, method|
|
378
473
|
next if !private && method.private?
|
379
474
|
|
380
|
-
interface.methods[name] = Interface::Interface::
|
381
|
-
method.
|
382
|
-
|
383
|
-
|
384
|
-
|
475
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
476
|
+
method_types: method.defs.map do |type_def|
|
477
|
+
setup_primitives(
|
478
|
+
name,
|
479
|
+
method_type(type_def.type,
|
480
|
+
method_def: type_def,
|
481
|
+
self_type: self_type,
|
482
|
+
subst2: subst)
|
483
|
+
)
|
484
|
+
end
|
385
485
|
)
|
386
486
|
end
|
387
487
|
end
|
@@ -404,7 +504,25 @@ module Steep
|
|
404
504
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
405
505
|
common_methods = Set.new(interface1.methods.keys) & Set.new(interface2.methods.keys)
|
406
506
|
common_methods.each do |name|
|
407
|
-
|
507
|
+
types1 = interface1.methods[name].method_types
|
508
|
+
types2 = interface2.methods[name].method_types
|
509
|
+
|
510
|
+
if types1 == types2
|
511
|
+
interface.methods[name] = interface1.methods[name]
|
512
|
+
else
|
513
|
+
method_types = {}
|
514
|
+
|
515
|
+
types1.each do |type1|
|
516
|
+
types2.each do |type2|
|
517
|
+
type = type1 | type2 or next
|
518
|
+
method_types[type] = true
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
unless method_types.empty?
|
523
|
+
interface.methods[name] = Interface::Interface::Entry.new(method_types: method_types.keys)
|
524
|
+
end
|
525
|
+
end
|
408
526
|
end
|
409
527
|
end
|
410
528
|
end
|
@@ -415,11 +533,8 @@ module Steep
|
|
415
533
|
interfaces = type.types.map {|ty| interface(ty, private: private, self_type: self_type) }
|
416
534
|
interfaces.inject do |interface1, interface2|
|
417
535
|
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
|
536
|
+
interface.methods.merge!(interface1.methods)
|
537
|
+
interface.methods.merge!(interface2.methods)
|
423
538
|
end
|
424
539
|
end
|
425
540
|
end
|
@@ -430,8 +545,8 @@ module Steep
|
|
430
545
|
array_type = Builtin::Array.instance_type(element_type)
|
431
546
|
interface(array_type, private: private, self_type: self_type).tap do |array_interface|
|
432
547
|
array_interface.methods[:[]] = array_interface.methods[:[]].yield_self do |aref|
|
433
|
-
Interface::Interface::
|
434
|
-
type.types.map.with_index {|elem_type, index|
|
548
|
+
Interface::Interface::Entry.new(
|
549
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
435
550
|
Interface::MethodType.new(
|
436
551
|
type_params: [],
|
437
552
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index)],
|
@@ -442,16 +557,16 @@ module Steep
|
|
442
557
|
rest_keywords: nil),
|
443
558
|
block: nil,
|
444
559
|
return_type: elem_type,
|
560
|
+
method_def: nil,
|
445
561
|
location: nil
|
446
562
|
)
|
447
|
-
} + aref.
|
448
|
-
incompatible: false
|
563
|
+
} + aref.method_types
|
449
564
|
)
|
450
565
|
end
|
451
566
|
|
452
567
|
array_interface.methods[:[]=] = array_interface.methods[:[]=].yield_self do |update|
|
453
|
-
Interface::Interface::
|
454
|
-
type.types.map.with_index {|elem_type, index|
|
568
|
+
Interface::Interface::Entry.new(
|
569
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
455
570
|
Interface::MethodType.new(
|
456
571
|
type_params: [],
|
457
572
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
|
@@ -462,10 +577,40 @@ module Steep
|
|
462
577
|
rest_keywords: nil),
|
463
578
|
block: nil,
|
464
579
|
return_type: elem_type,
|
580
|
+
method_def: nil,
|
581
|
+
location: nil
|
582
|
+
)
|
583
|
+
} + update.method_types
|
584
|
+
)
|
585
|
+
end
|
586
|
+
|
587
|
+
array_interface.methods[:first] = array_interface.methods[:first].yield_self do |first|
|
588
|
+
Interface::Interface::Entry.new(
|
589
|
+
method_types: [
|
590
|
+
Interface::MethodType.new(
|
591
|
+
type_params: [],
|
592
|
+
params: Interface::Params.empty,
|
593
|
+
block: nil,
|
594
|
+
return_type: type.types[0] || AST::Builtin.nil_type,
|
595
|
+
method_def: nil,
|
465
596
|
location: nil
|
466
597
|
)
|
467
|
-
|
468
|
-
|
598
|
+
]
|
599
|
+
)
|
600
|
+
end
|
601
|
+
|
602
|
+
array_interface.methods[:last] = array_interface.methods[:last].yield_self do |last|
|
603
|
+
Interface::Interface::Entry.new(
|
604
|
+
method_types: [
|
605
|
+
Interface::MethodType.new(
|
606
|
+
type_params: [],
|
607
|
+
params: Interface::Params.empty,
|
608
|
+
block: nil,
|
609
|
+
return_type: type.types.last || AST::Builtin.nil_type,
|
610
|
+
method_def: nil,
|
611
|
+
location: nil
|
612
|
+
)
|
613
|
+
]
|
469
614
|
)
|
470
615
|
end
|
471
616
|
end
|
@@ -481,8 +626,8 @@ module Steep
|
|
481
626
|
|
482
627
|
interface(hash_type, private: private, self_type: self_type).tap do |hash_interface|
|
483
628
|
hash_interface.methods[:[]] = hash_interface.methods[:[]].yield_self do |ref|
|
484
|
-
Interface::Interface::
|
485
|
-
type.elements.map {|key_value, value_type|
|
629
|
+
Interface::Interface::Entry.new(
|
630
|
+
method_types: type.elements.map {|key_value, value_type|
|
486
631
|
key_type = Literal.new(value: key_value, location: nil)
|
487
632
|
Interface::MethodType.new(
|
488
633
|
type_params: [],
|
@@ -494,16 +639,16 @@ module Steep
|
|
494
639
|
rest_keywords: nil),
|
495
640
|
block: nil,
|
496
641
|
return_type: value_type,
|
642
|
+
method_def: nil,
|
497
643
|
location: nil
|
498
644
|
)
|
499
|
-
} + ref.
|
500
|
-
incompatible: false
|
645
|
+
} + ref.method_types
|
501
646
|
)
|
502
647
|
end
|
503
648
|
|
504
649
|
hash_interface.methods[:[]=] = hash_interface.methods[:[]=].yield_self do |update|
|
505
|
-
Interface::Interface::
|
506
|
-
type.elements.map {|key_value, value_type|
|
650
|
+
Interface::Interface::Entry.new(
|
651
|
+
method_types: type.elements.map {|key_value, value_type|
|
507
652
|
key_type = Literal.new(value: key_value, location: nil)
|
508
653
|
Interface::MethodType.new(
|
509
654
|
type_params: [],
|
@@ -515,10 +660,10 @@ module Steep
|
|
515
660
|
rest_keywords: nil),
|
516
661
|
block: nil,
|
517
662
|
return_type: value_type,
|
663
|
+
method_def: nil,
|
518
664
|
location: nil
|
519
665
|
)
|
520
|
-
} + update.
|
521
|
-
incompatible: false
|
666
|
+
} + update.method_types
|
522
667
|
)
|
523
668
|
end
|
524
669
|
end
|
@@ -531,26 +676,28 @@ module Steep
|
|
531
676
|
params: type.params,
|
532
677
|
return_type: type.return_type,
|
533
678
|
block: nil,
|
679
|
+
method_def: nil,
|
534
680
|
location: nil
|
535
681
|
)
|
536
682
|
|
537
|
-
interface.methods[:[]] = Interface::Interface::
|
538
|
-
interface.methods[:call] = Interface::Interface::
|
683
|
+
interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type])
|
684
|
+
interface.methods[:call] = Interface::Interface::Entry.new(method_types: [method_type])
|
539
685
|
end
|
540
686
|
|
687
|
+
when Logic::Base
|
688
|
+
interface(AST::Builtin.bool_type, private: private, self_type: self_type)
|
689
|
+
|
541
690
|
else
|
542
691
|
raise "Unexpected type for interface: #{type}"
|
543
692
|
end
|
544
693
|
end
|
545
694
|
|
546
695
|
def module_name?(type_name)
|
547
|
-
|
548
|
-
entry = env.class_decls[name] and entry.is_a?(RBS::Environment::ModuleEntry)
|
696
|
+
entry = env.class_decls[type_name] and entry.is_a?(RBS::Environment::ModuleEntry)
|
549
697
|
end
|
550
698
|
|
551
699
|
def class_name?(type_name)
|
552
|
-
|
553
|
-
entry = env.class_decls[name] and entry.is_a?(RBS::Environment::ClassEntry)
|
700
|
+
entry = env.class_decls[type_name] and entry.is_a?(RBS::Environment::ClassEntry)
|
554
701
|
end
|
555
702
|
|
556
703
|
def env
|
@@ -565,7 +712,22 @@ module Steep
|
|
565
712
|
end
|
566
713
|
|
567
714
|
def absolute_type_name(type_name, namespace:)
|
568
|
-
type_name_resolver.resolve(type_name, context:
|
715
|
+
type_name_resolver.resolve(type_name, context: namespace.ascend)
|
716
|
+
end
|
717
|
+
|
718
|
+
def instance_type(type_name, args: nil, location: nil)
|
719
|
+
raise unless type_name.class?
|
720
|
+
|
721
|
+
definition = definition_builder.build_singleton(type_name)
|
722
|
+
def_args = definition.type_params.map { Any.new(location: nil) }
|
723
|
+
|
724
|
+
if args
|
725
|
+
raise if def_args.size != args.size
|
726
|
+
else
|
727
|
+
args = def_args
|
728
|
+
end
|
729
|
+
|
730
|
+
AST::Types::Name::Instance.new(location: location, name: type_name, args: args)
|
569
731
|
end
|
570
732
|
end
|
571
733
|
end
|