steep 0.25.0 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -0
  3. data/bin/smoke_runner.rb +3 -4
  4. data/bin/steep-prof +1 -2
  5. data/lib/steep.rb +6 -4
  6. data/lib/steep/annotation_parser.rb +2 -4
  7. data/lib/steep/ast/builtin.rb +11 -21
  8. data/lib/steep/ast/types.rb +5 -3
  9. data/lib/steep/ast/types/any.rb +1 -3
  10. data/lib/steep/ast/types/boolean.rb +1 -3
  11. data/lib/steep/ast/types/bot.rb +1 -3
  12. data/lib/steep/ast/types/class.rb +2 -2
  13. data/lib/steep/ast/types/factory.rb +265 -90
  14. data/lib/steep/ast/types/helper.rb +6 -0
  15. data/lib/steep/ast/types/instance.rb +2 -2
  16. data/lib/steep/ast/types/intersection.rb +20 -13
  17. data/lib/steep/ast/types/literal.rb +1 -3
  18. data/lib/steep/ast/types/logic.rb +63 -0
  19. data/lib/steep/ast/types/name.rb +15 -67
  20. data/lib/steep/ast/types/nil.rb +1 -3
  21. data/lib/steep/ast/types/proc.rb +5 -2
  22. data/lib/steep/ast/types/record.rb +9 -4
  23. data/lib/steep/ast/types/self.rb +1 -1
  24. data/lib/steep/ast/types/top.rb +1 -3
  25. data/lib/steep/ast/types/tuple.rb +5 -3
  26. data/lib/steep/ast/types/union.rb +13 -9
  27. data/lib/steep/ast/types/var.rb +2 -2
  28. data/lib/steep/ast/types/void.rb +1 -3
  29. data/lib/steep/errors.rb +14 -0
  30. data/lib/steep/interface/interface.rb +5 -62
  31. data/lib/steep/interface/method_type.rb +394 -93
  32. data/lib/steep/interface/substitution.rb +48 -6
  33. data/lib/steep/module_helper.rb +25 -0
  34. data/lib/steep/project.rb +25 -0
  35. data/lib/steep/project/completion_provider.rb +57 -58
  36. data/lib/steep/project/file_loader.rb +7 -2
  37. data/lib/steep/project/hover_content.rb +92 -83
  38. data/lib/steep/project/signature_file.rb +33 -0
  39. data/lib/steep/project/{file.rb → source_file.rb} +24 -54
  40. data/lib/steep/project/target.rb +31 -12
  41. data/lib/steep/server/base_worker.rb +5 -3
  42. data/lib/steep/server/code_worker.rb +31 -45
  43. data/lib/steep/server/interaction_worker.rb +42 -38
  44. data/lib/steep/server/master.rb +23 -31
  45. data/lib/steep/server/utils.rb +46 -13
  46. data/lib/steep/server/worker_process.rb +4 -2
  47. data/lib/steep/signature/validator.rb +3 -3
  48. data/lib/steep/source.rb +59 -2
  49. data/lib/steep/subtyping/check.rb +36 -50
  50. data/lib/steep/subtyping/constraints.rb +8 -0
  51. data/lib/steep/type_construction.rb +388 -366
  52. data/lib/steep/type_inference/block_params.rb +5 -0
  53. data/lib/steep/type_inference/constant_env.rb +2 -5
  54. data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
  55. data/lib/steep/type_inference/type_env.rb +2 -2
  56. data/lib/steep/version.rb +1 -1
  57. data/smoke/alias/a.rb +1 -1
  58. data/smoke/case/a.rb +1 -1
  59. data/smoke/hash/d.rb +1 -1
  60. data/smoke/if/a.rb +1 -1
  61. data/smoke/module/a.rb +1 -1
  62. data/smoke/rescue/a.rb +4 -13
  63. data/smoke/toplevel/Steepfile +5 -0
  64. data/smoke/toplevel/a.rb +4 -0
  65. data/smoke/toplevel/a.rbs +3 -0
  66. data/smoke/type_case/a.rb +0 -7
  67. data/steep.gemspec +3 -3
  68. metadata +17 -13
  69. data/lib/steep/ast/method_type.rb +0 -126
  70. data/lib/steep/ast/namespace.rb +0 -80
  71. data/lib/steep/names.rb +0 -86
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c290301da65ed473b092cd6c2ea39eebe02f566124a1fa32e0f420d290513cbf
4
- data.tar.gz: ca4fca20e9f3f0b19c57b98d6cdfce0023aeeff8cd0fcd2ee0fc91346e5e0816
3
+ metadata.gz: e315b0a9541b0289ae3c9dd3acb19c2112e990a321176f94ed44f25d4190acb4
4
+ data.tar.gz: 9ce6e2024e81e5a2452fc5d7ca381decd1d91ed917d385dc280133652af51e06
5
5
  SHA512:
6
- metadata.gz: 76c3b0c76e303bcc558bf20efeebe3ddaa3caef432f5d325261261f6d8431f5bbd36bc44af9a4a4dd6a90f2db30ac35ca044181b25063890c0e68c5499d7792c
7
- data.tar.gz: a5fa8fba718f599806d9d0ad62a66c138261469d41694bb39ebafe1b8736ad255e890c55f0e3b4f180f4e0212f0b65b31b5957b5c337cba42d1129b9e935e577
6
+ metadata.gz: bd8db01573d1a2e31b362fb893bfad1325969b8343415d1bfd82428a76f0a6c8f8fe2875f7e474ab94244476e9901b1dda186f57cb90a49602638453826534a8
7
+ data.tar.gz: f1f30e2afc48265917468a4c5dd040fff3e226f92cb17441c3f3fcbba7f95aaa1002172ece399410d567358d9caf7bd80c1f1c27b9083c81a39e1abe61b74a68
@@ -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))
@@ -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::Ruby25.new
36
+ parser = ::Parser::Ruby27.new
38
37
 
39
38
  _, comments, _ = parser.tokenize(buffer)
40
39
  comments.each do |comment|
@@ -9,8 +9,7 @@ def exit(*)
9
9
 
10
10
  end
11
11
 
12
-
13
12
  STDERR.puts "Running profiler: mode=#{mode}, out=#{out}"
14
- StackProf.run(mode: mode, out: out) do
13
+ StackProf.run(mode: mode, out: out, raw: true) do
15
14
  load File.join(__dir__, "../exe/steep")
16
15
  end
@@ -1,7 +1,7 @@
1
1
  require "steep/version"
2
2
 
3
3
  require "pathname"
4
- require "parser/ruby25"
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/file"
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: Names::Module.parse(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 = Names::Module.parse(match[: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)
@@ -6,7 +6,7 @@ module Steep
6
6
  attr_reader :arity
7
7
 
8
8
  def initialize(module_name, arity: 0)
9
- @module_name = Names::Module.parse(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::Module.new(name: module_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::Module)
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
@@ -35,9 +35,11 @@ module Steep
35
35
  "masked(#{type}|#{mask})"
36
36
  end
37
37
 
38
- def free_variables(set = Set.new)
39
- type.free_variables(set)
40
- mask.free_variables(set)
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)
@@ -26,9 +26,7 @@ module Steep
26
26
  "untyped"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [1]
@@ -26,9 +26,7 @@ module Steep
26
26
  "bool"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [0]
@@ -26,9 +26,7 @@ module Steep
26
26
  "⟘"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [2]
@@ -22,8 +22,8 @@ module Steep
22
22
  s.module_type or raise "Unexpected substitution: #{inspect}"
23
23
  end
24
24
 
25
- def free_variables
26
- Set.new
25
+ def free_variables()
26
+ @fvs = Set.new([self])
27
27
  end
28
28
 
29
29
  def level
@@ -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
- case type
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 = type_name(type.name)
39
- Name::Class.new(name: type_name, location: nil, constructor: nil)
49
+ type_name = type.name
50
+ Name::Singleton.new(name: type_name, location: nil)
40
51
  when RBS::Types::ClassInstance
41
- type_name = type_name(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 = type_name(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 = type_name(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::Class, Name::Module
98
- RBS::Types::ClassSingleton.new(name: type_name_1(type.name), location: nil)
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: type_name_1(type.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: type_name_1(type.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: type_name_1(type.name), location: nil)
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
- type_name_1(type_name).yield_self do |type_name|
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 = expand_alias(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(type_name_1(type.name))
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
- next if method.private? && !private
332
-
333
- interface.methods[name] = Interface::Interface::Combination.overload(
334
- method.method_types.map do |type|
335
- method_type(type, self_type: self_type) {|ty| ty.subst(subst) }
336
- end,
337
- incompatible: name == :initialize || name == :new
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 = type_name_1(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::Combination.overload(
355
- method.method_types.map do |type|
356
- method_type(type, self_type: self_type) {|type| type.subst(subst) }
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::Class, Name::Module
469
+ when Name::Singleton
364
470
  Interface::Interface.new(type: self_type, private: private).tap do |interface|
365
- definition = definition_builder.build_singleton(type_name_1(type.name))
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::Combination.overload(
381
- method.method_types.map do |type|
382
- method_type(type, self_type: self_type) {|type| type.subst(subst) }
383
- end,
384
- incompatible: method.attributes.include?(:incompatible)
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
- interface.methods[name] = Interface::Interface::Combination.union([interface1.methods[name], interface2.methods[name]])
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
- all_methods = Set.new(interface1.methods.keys) + Set.new(interface2.methods.keys)
419
- all_methods.each do |name|
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::Combination.overload(
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.types,
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::Combination.overload(
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
- } + update.types,
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::Combination.overload(
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.types,
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::Combination.overload(
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.types,
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::Combination.overload([method_type], incompatible: false)
538
- interface.methods[:call] = Interface::Interface::Combination.overload([method_type], incompatible: false)
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
- name = type_name_1(type_name)
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
- name = type_name_1(type_name)
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: namespace_1(namespace).ascend)
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