steep 0.24.0 → 0.30.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 +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
|