katakata_irb 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,10 +11,18 @@ module KatakataIrb::Types
11
11
 
12
12
  Splat = Struct.new :item
13
13
 
14
+ MODULE_NAME_METHOD = Module.instance_method(:name)
15
+
16
+ def self.class_name_of(klass)
17
+ klass = klass.superclass if klass.singleton_class?
18
+ MODULE_NAME_METHOD.bind_call klass
19
+ end
20
+
14
21
  def self.rbs_search_method(klass, method_name, singleton)
15
22
  klass.ancestors.each do |ancestor|
16
- next unless ancestor.name
17
- type_name = RBS::TypeName(ancestor.name).absolute!
23
+ name = class_name_of ancestor
24
+ next unless name
25
+ type_name = RBS::TypeName(name).absolute!
18
26
  definition = (singleton ? rbs_builder.build_singleton(type_name) : rbs_builder.build_instance(type_name)) rescue nil
19
27
  method = definition&.methods&.[](method_name)
20
28
  return method if method
@@ -22,9 +30,29 @@ module KatakataIrb::Types
22
30
  nil
23
31
  end
24
32
 
33
+ def self.method_return_type(type, method_name)
34
+ receivers = type.types.map do |t|
35
+ case t
36
+ in ProcType
37
+ [t, Proc, false]
38
+ in SingletonType
39
+ [t, t.module_or_class, true]
40
+ in InstanceType
41
+ [t, t.klass, false]
42
+ end
43
+ end
44
+ types = receivers.flat_map do |receiver_type, klass, singleton|
45
+ method = rbs_search_method klass, method_name, singleton
46
+ next [] unless method
47
+ method.method_types.map do |method|
48
+ from_rbs_type(method.type.return_type, receiver_type, {})
49
+ end
50
+ end
51
+ UnionType[*types]
52
+ end
53
+
25
54
  def self.rbs_methods(type, method_name, args_types, kwargs_type, has_block)
26
- types = (type in UnionType) ? type.types : [type]
27
- receivers = types.map do |t|
55
+ receivers = type.types.map do |t|
28
56
  case t
29
57
  in ProcType
30
58
  [t, Proc, false]
@@ -60,8 +88,15 @@ module KatakataIrb::Types
60
88
  given << UnionType[*centers.drop(opts.size)]
61
89
  expected << rest.type
62
90
  end
63
- score += given.zip(expected).count do |t, e|
64
- intersect? t, from_rbs_type(e, receiver_type)
91
+ score += given.zip(expected).sum do |t, e|
92
+ e = from_rbs_type e, receiver_type
93
+ if intersect? t, e
94
+ 1
95
+ elsif (intersect?(STRING, e) && t.methods.include?(:to_str)) || (intersect?(INTEGER, e) && t.methods.include?(:to_int)) || (intersect?(ARRAY, e) && t.methods.include?(:to_ary))
96
+ 0.5
97
+ else
98
+ 0
99
+ end
65
100
  end
66
101
  end
67
102
  [[method_type, given || [], expected || []], score]
@@ -83,14 +118,24 @@ module KatakataIrb::Types
83
118
  intersect.call(InstanceType, &:klass)
84
119
  end
85
120
 
86
- def self.type_from_object(object, max_level: 4)
121
+ def self.type_from_object(object)
122
+ case object
123
+ when Array, Hash, Module
124
+ type_from_object_recursive(object, max_level: 4)
125
+ else
126
+ klass = object.singleton_class rescue object.class
127
+ InstanceType.new klass
128
+ end
129
+ end
130
+
131
+ def self.type_from_object_recursive(object, max_level:)
87
132
  max_level -= 1
88
133
  sample_size = 1000
89
134
  case object
90
135
  when Array
91
136
  values = object.size > sample_size ? object.sample(sample_size) : object
92
137
  if max_level > 0
93
- InstanceType.new Array, { Elem: UnionType[*values.map { type_from_object(_1, max_level: max_level) }] }
138
+ InstanceType.new Array, { Elem: UnionType[*values.map { type_from_object_recursive(_1, max_level: max_level) }] }
94
139
  else
95
140
  InstanceType.new Array, { Elem: UnionType[*values.map(&:class).uniq.map { InstanceType.new _1 }] }
96
141
  end
@@ -98,8 +143,8 @@ module KatakataIrb::Types
98
143
  keys = object.size > sample_size ? object.keys.sample(sample_size) : object.keys
99
144
  values = object.size > sample_size ? object.values.sample(sample_size) : object.values
100
145
  if max_level > 0
101
- key_types = keys.map { type_from_object(_1, max_level: max_level) }
102
- value_types = values.map { type_from_object(_1, max_level: max_level) }
146
+ key_types = keys.map { type_from_object_recursive(_1, max_level: max_level) }
147
+ value_types = values.map { type_from_object_recursive(_1, max_level: max_level) }
103
148
  InstanceType.new Hash, { K: UnionType[*key_types], V: UnionType[*value_types] }
104
149
  else
105
150
  key_types = keys.map(&:class).uniq.map { InstanceType.new _1 }
@@ -123,6 +168,8 @@ module KatakataIrb::Types
123
168
  def all_methods() = methods | Kernel.methods
124
169
  def constants() = @module_or_class.constants
125
170
  def types() = [self]
171
+ def nillable?() = false
172
+ def nonnillable() = self
126
173
  end
127
174
 
128
175
  class InstanceType
@@ -136,6 +183,8 @@ module KatakataIrb::Types
136
183
  def all_methods() = @klass.instance_methods | @klass.private_instance_methods
137
184
  def constants() = []
138
185
  def types() = [self]
186
+ def nillable?() = (@klass == NilClass)
187
+ def nonnillable() = self
139
188
  end
140
189
 
141
190
  class ProcType
@@ -150,11 +199,13 @@ module KatakataIrb::Types
150
199
  def all_methods() = Proc.instance_methods | Proc.private_instance_methods
151
200
  def constants() = []
152
201
  def types() = [self]
202
+ def nillable?() = (@klass == NilClass)
203
+ def nonnillable() = self
153
204
  end
154
205
 
155
206
  NIL = InstanceType.new NilClass
156
207
  OBJECT = InstanceType.new Object
157
- TRUE = InstanceType.new FalseClass
208
+ TRUE = InstanceType.new TrueClass
158
209
  FALSE = InstanceType.new FalseClass
159
210
  SYMBOL = InstanceType.new Symbol
160
211
  STRING = InstanceType.new String
@@ -203,6 +254,14 @@ module KatakataIrb::Types
203
254
  UnionType[*types.map(&block)]
204
255
  end
205
256
 
257
+ def nillable?
258
+ types.any?(&:nillable?)
259
+ end
260
+
261
+ def nonnillable
262
+ UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }]
263
+ end
264
+
206
265
  def self.[](*types)
207
266
  type = new(*types)
208
267
  if type.types.empty?
@@ -219,6 +278,8 @@ module KatakataIrb::Types
219
278
  def constants() = @types.flat_map(&:constants).uniq
220
279
  end
221
280
 
281
+ BOOLEAN = UnionType[TRUE, FALSE]
282
+
222
283
  def self.from_rbs_type(return_type, self_type, extra_vars = {})
223
284
  case return_type
224
285
  when RBS::Types::Bases::Self
@@ -238,7 +299,7 @@ module KatakataIrb::Types
238
299
  end
239
300
  UnionType[*types]
240
301
  when RBS::Types::Bases::Bool
241
- UnionType[TRUE, FALSE]
302
+ BOOLEAN
242
303
  when RBS::Types::Bases::Instance
243
304
  self_type.transform do |type|
244
305
  case type
@@ -286,7 +347,7 @@ module KatakataIrb::Types
286
347
  when :int
287
348
  INTEGER
288
349
  when :boolish
289
- UnionType[TRUE, FALSE]
350
+ BOOLEAN
290
351
  when :string
291
352
  STRING
292
353
  else
@@ -332,6 +393,25 @@ module KatakataIrb::Types
332
393
  end
333
394
  in [RBS::Types::Record, InstanceType] if value.klass == Hash
334
395
  # TODO
396
+ in [RBS::Types::Interface,]
397
+ definition = rbs_builder.build_interface rbs_type.name
398
+ convert = {}
399
+ definition.type_params.zip(rbs_type.args).each do |from, arg|
400
+ convert[from] = arg.name if arg.is_a? RBS::Types::Variable
401
+ end
402
+ return if convert.empty?
403
+ ac = {}
404
+ definition.methods.each do |method_name, method|
405
+ return_type = method_return_type value, method_name
406
+ method.defs.each do |method_def|
407
+ interface_return_type = method_def.type.type.return_type
408
+ _match_free_variable convert, interface_return_type, return_type, ac
409
+ end
410
+ end
411
+ convert.each do |from, to|
412
+ values = ac[from]
413
+ (accumulator[to] ||= []).concat values if values
414
+ end
335
415
  else
336
416
  end
337
417
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KatakataIrb
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katakata_irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - tompng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-26 00:00:00.000000000 Z
11
+ date: 2023-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: irb
@@ -56,6 +56,7 @@ files:
56
56
  - lib/katakata_irb.rb
57
57
  - lib/katakata_irb/completor.rb
58
58
  - lib/katakata_irb/nesting_parser.rb
59
+ - lib/katakata_irb/scope.rb
59
60
  - lib/katakata_irb/type_simulator.rb
60
61
  - lib/katakata_irb/types.rb
61
62
  - lib/katakata_irb/version.rb
@@ -81,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
82
  - !ruby/object:Gem::Version
82
83
  version: '0'
83
84
  requirements: []
84
- rubygems_version: 3.4.5
85
+ rubygems_version: 3.4.6
85
86
  signing_key:
86
87
  specification_version: 4
87
88
  summary: IRB with Typed Completion