katakata_irb 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 034055ed4a5fcf5bde6a1b86723c2963f82ace7c5b0411cd9a3e09fd734b10d2
4
- data.tar.gz: 3e04438496f0241815cf7b674db57f7b644360520d9d829d75d5be61b63b78e5
3
+ metadata.gz: ad93f43d988f169816f4e842bdb70eda5a866574664f6afb5c015ae60b2f2d3b
4
+ data.tar.gz: 700e29af39db9a73fb71f0f2e76cf4d87bcf801e31fddaef3514416e6d3699e1
5
5
  SHA512:
6
- metadata.gz: 4b406ecd5c611cdc86220efa506c403dff220db4be5fb1bc1fab10eeb70931f0d7eaee8a45a702a6addb5de793e0c219562975d769fe31616305cd87fe4cfa4a
7
- data.tar.gz: 147b09a36c68a66c917fff2157797d1124ec06e0333ee7cec26ef83b9d726c398bb83bbdce81f88c1706067ecc3f9bf99506d5706d3b22ccc3c8aa2ee6ce5cb1
6
+ metadata.gz: d53414d13852cd4d88a92b841fcd20d85a19efd7cb2dd15faac245e0cd944f10e12e5176ca6b03aa82ca3bd66981c56a0a6ad228a73f9e149b1a4ee9077c4f39
7
+ data.tar.gz: 734aa26486a262b1feaf059290d7526fb061a71cd584c8ec4fa4fdbeb3f8a2b1d29b9e5dd64549e33d87e9987e736aeb1be0ae366033af9533914ca38981c4a8
data/katakata_irb.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  # Uncomment to register a new dependency of your gem
32
32
  spec.add_dependency 'irb', '>= 1.4.0'
33
33
  spec.add_dependency 'reline', '>= 0.3.0'
34
- spec.add_dependency 'prism', '>= 0.14.0'
34
+ spec.add_dependency 'prism', '>= 0.16.0'
35
35
  spec.add_dependency 'rbs'
36
36
 
37
37
  # For more information and examples about making a new gem, check out our
@@ -102,8 +102,6 @@ module KatakataIrb::Completor
102
102
  return KatakataIrb::Types.class_name_of(t.module_or_class)
103
103
  when KatakataIrb::Types::InstanceType
104
104
  return KatakataIrb::Types.class_name_of(t.klass)
105
- when KatakataIrb::Types::ProcType
106
- return 'Proc'
107
105
  end
108
106
  end
109
107
  nil
@@ -224,15 +222,18 @@ module KatakataIrb::Completor
224
222
  calculate_scope = -> { KatakataIrb::TypeAnalyzer.calculate_target_type_scope(binding, parents, target_node).last }
225
223
  calculate_type_scope = ->(node) { KatakataIrb::TypeAnalyzer.calculate_target_type_scope binding, [*parents, target_node], node }
226
224
 
227
- if target_node.is_a?(Prism::StringNode) || target_node.is_a?(Prism::InterpolatedStringNode)
228
- args_node = parents[-1]
229
- call_node = parents[-2]
225
+ case target_node
226
+ when Prism::StringNode, Prism::InterpolatedStringNode
227
+ call_node, args_node = parents.last(2)
228
+ return unless call_node.is_a?(Prism::CallNode) && call_node.receiver.nil?
230
229
  return unless args_node.is_a?(Prism::ArgumentsNode) && args_node.arguments.size == 1
231
- return unless call_node.is_a?(Prism::CallNode) && call_node.receiver.nil? && (call_node.message == 'require' || call_node.message == 'require_relative')
232
- return [call_node.message.to_sym, name.rstrip]
233
- end
234
230
 
235
- case target_node
231
+ case call_node.name
232
+ when :require
233
+ [:require, name.rstrip]
234
+ when :require_relative
235
+ [:require_relative, name.rstrip]
236
+ end
236
237
  when Prism::SymbolNode
237
238
  if parents.last.is_a? Prism::BlockArgumentNode # method(&:target)
238
239
  receiver_type, _scope = calculate_type_scope.call target_node
@@ -287,8 +288,7 @@ module KatakataIrb::Completor
287
288
  )
288
289
  return [node] if location&.start_offset == position
289
290
 
290
- node.child_nodes.each do |n|
291
- next unless n.is_a? Prism::Node
291
+ node.compact_child_nodes.each do |n|
292
292
  match = find_target(n, position)
293
293
  next unless match
294
294
  match.unshift node
@@ -231,7 +231,7 @@ class KatakataIrb::TypeAnalyzer
231
231
 
232
232
 
233
233
  def evaluate_call_node(node, scope)
234
- # TODO: return type of []=, field= when operator_loc.nil?
234
+ is_field_assign = node.name.match?(/[^<>=!\]]=\z/) || (node.name == :[]= && !node.call_operator)
235
235
  receiver_type = node.receiver ? evaluate(node.receiver, scope) : scope.self_type
236
236
  evaluate_method = lambda do |scope|
237
237
  args_types, kwargs_types, block_sym_node, has_block = evaluate_call_node_arguments node, scope
@@ -280,7 +280,12 @@ class KatakataIrb::TypeAnalyzer
280
280
  elsif has_block
281
281
  call_block_proc = ->(_block_args, _self_type) { KatakataIrb::Types::OBJECT }
282
282
  end
283
- method_call receiver_type, node.name, args_types, kwargs_types, call_block_proc, scope
283
+ result = method_call receiver_type, node.name, args_types, kwargs_types, call_block_proc, scope
284
+ if is_field_assign
285
+ args_types.last || KatakataIrb::Types::NIL
286
+ else
287
+ result
288
+ end
284
289
  end
285
290
  if node.call_operator == '&.'
286
291
  result = scope.conditional { evaluate_method.call _1 }
@@ -314,8 +319,7 @@ class KatakataIrb::TypeAnalyzer
314
319
  def evaluate_index_or_write_node(node, scope) = evaluate_call_write(node, scope, :or, :[]=)
315
320
  def evaluate_call_write(node, scope, operator, write_name)
316
321
  receiver_type = evaluate node.receiver, scope
317
- if node.respond_to? :arguments
318
- # Prism >= 0.15.0, Call{Operator,And,Or}WriteNode does not have arguments
322
+ if write_name == :[]=
319
323
  args_types, kwargs_types, block_sym_node, has_block = evaluate_call_node_arguments node, scope
320
324
  else
321
325
  args_types = []
@@ -430,7 +434,7 @@ class KatakataIrb::TypeAnalyzer
430
434
  end
431
435
  block_scope.merge_jumps
432
436
  scope.update block_scope
433
- KatakataIrb::Types::ProcType.new
437
+ KatakataIrb::Types::PROC
434
438
  end
435
439
 
436
440
  def evaluate_reference_write(node, scope)
@@ -748,6 +752,12 @@ class KatakataIrb::TypeAnalyzer
748
752
  KatakataIrb::Types::NIL
749
753
  end
750
754
 
755
+ def evaluate_splat_node(node, scope)
756
+ # Raw SplatNode, incomplete code like `*a.`
757
+ evaluate_multi_write_receiver node.expression, scope, nil if node.expression
758
+ KatakataIrb::Types::NIL
759
+ end
760
+
751
761
  def evaluate_implicit_node(node, scope)
752
762
  evaluate node.value, scope
753
763
  end
@@ -784,7 +794,7 @@ class KatakataIrb::TypeAnalyzer
784
794
  def evaluate_call_node_arguments(call_node, scope)
785
795
  # call_node.arguments is Prism::ArgumentsNode
786
796
  arguments = call_node.arguments&.arguments&.dup || []
787
- block_arg = call_node.block.expression if call_node.respond_to?(:block) && call_node.block.is_a?(Prism::BlockArgumentNode)
797
+ block_arg = call_node.block.expression if call_node.block.is_a?(Prism::BlockArgumentNode)
788
798
  kwargs = arguments.pop.elements if arguments.last.is_a?(Prism::KeywordHashNode)
789
799
  args_types = arguments.map do |arg|
790
800
  case arg
@@ -792,7 +802,7 @@ class KatakataIrb::TypeAnalyzer
792
802
  # `f(a, ...)` treat like splat
793
803
  nil
794
804
  when Prism::SplatNode
795
- evaluate arg.expression, scope
805
+ evaluate arg.expression, scope if arg.expression
796
806
  nil # TODO: splat
797
807
  else
798
808
  evaluate arg, scope
@@ -810,7 +820,7 @@ class KatakataIrb::TypeAnalyzer
810
820
  nil
811
821
  end
812
822
  when Prism::AssocSplatNode
813
- evaluate arg.value, scope
823
+ evaluate arg.value, scope if arg.value
814
824
  nil
815
825
  end
816
826
  end.compact.to_h
@@ -833,15 +843,16 @@ class KatakataIrb::TypeAnalyzer
833
843
  end
834
844
 
835
845
  def assign_required_parameter(node, value, scope)
836
- case node
837
- when Prism::RequiredParameterNode
846
+ case node.type
847
+ when :required_parameter_node
838
848
  scope[node.name.to_s] = value || KatakataIrb::Types::OBJECT
839
- when Prism::RequiredDestructuredParameterNode
840
- values = value ? sized_splat(value, :to_ary, node.parameters.size) : []
841
- node.parameters.zip values do |n, v|
849
+ when :multi_target_node
850
+ parameters = [*node.lefts, *node.rest, *node.rights]
851
+ values = value ? sized_splat(value, :to_ary, parameters.size) : []
852
+ parameters.zip values do |n, v|
842
853
  assign_required_parameter n, v, scope
843
854
  end
844
- when Prism::SplatNode
855
+ when :splat_node
845
856
  splat_value = value ? KatakataIrb::Types.array_of(value) : KatakataIrb::Types::ARRAY
846
857
  assign_required_parameter node.expression, splat_value, scope
847
858
  end
@@ -881,7 +892,7 @@ class KatakataIrb::TypeAnalyzer
881
892
  args = sized_splat(args.first, :to_ary, size) if size >= 2 && args.size == 1
882
893
  reqs = args.shift node.requireds.size
883
894
  if node.rest
884
- # node.rest.class is Prism::RestParameterNode
895
+ # node.rest is Prism::RestParameterNode
885
896
  posts = []
886
897
  opts = args.shift node.optionals.size
887
898
  rest = args
@@ -927,13 +938,7 @@ class KatakataIrb::TypeAnalyzer
927
938
  return if numbered_parameters.empty?
928
939
  max_num = numbered_parameters.map { _1[1].to_i }.max
929
940
  if max_num == 1
930
- if args.size == 0
931
- scope['_1'] = KatakataIrb::Types::NIL
932
- elsif args.size == 1
933
- scope['_1'] = args.first
934
- else
935
- scope['_1'] = KatakataIrb::Types.array_of(*args)
936
- end
941
+ scope['_1'] = args.first || KatakataIrb::Types::NIL
937
942
  else
938
943
  args = sized_splat(args.first, :to_ary, max_num) if args.size == 1
939
944
  numbered_parameters.each do |name|
@@ -976,7 +981,10 @@ class KatakataIrb::TypeAnalyzer
976
981
  KatakataIrb::Types::ARRAY
977
982
  when Prism::HashPatternNode
978
983
  # TODO
979
- pattern.assocs.each { evaluate_match_pattern KatakataIrb::Types::OBJECT, _1, scope }
984
+ pattern.elements.each { evaluate_match_pattern KatakataIrb::Types::OBJECT, _1, scope }
985
+ if pattern.respond_to?(:rest) && pattern.rest
986
+ evaluate_match_pattern KatakataIrb::Types::OBJECT, pattern.rest, scope
987
+ end
980
988
  KatakataIrb::Types::HASH
981
989
  when Prism::AssocNode
982
990
  evaluate_match_pattern value, pattern.value, scope if pattern.value
@@ -1033,20 +1041,15 @@ class KatakataIrb::TypeAnalyzer
1033
1041
  end
1034
1042
 
1035
1043
  def evaluate_multi_write(node, values, scope, evaluated_receivers)
1036
- values = sized_splat values, :to_ary, node.targets.size unless values.is_a? Array
1037
- splat_index = node.targets.find_index { _1.is_a? Prism::SplatNode }
1038
- if splat_index
1039
- pre_targets = node.targets[0...splat_index]
1040
- splat_target = node.targets[splat_index]
1041
- post_targets = node.targets[splat_index + 1..]
1042
- pre_values = values.shift pre_targets.size
1043
- post_values = values.pop post_targets.size
1044
- splat_value = KatakataIrb::Types::UnionType[*values]
1045
- zips = pre_targets.zip(pre_values) + [[splat_target, splat_value]] + post_targets.zip(post_values)
1046
- else
1047
- zips = node.targets.zip(values)
1048
- end
1049
- zips.each do |target, value|
1044
+ pre_targets = node.lefts
1045
+ splat_target = node.rest
1046
+ post_targets = node.rights
1047
+ size = pre_targets.size + (splat_target ? 1 : 0) + post_targets.size
1048
+ values = values.is_a?(Array) ? values.dup : sized_splat(values, :to_ary, size)
1049
+ pre_pairs = pre_targets.zip(values.shift(pre_targets.size))
1050
+ post_pairs = post_targets.zip(values.pop(post_targets.size))
1051
+ splat_pairs = splat_target ? [[splat_target, KatakataIrb::Types::UnionType[*values]]] : []
1052
+ (pre_pairs + splat_pairs + post_pairs).each do |target, value|
1050
1053
  evaluate_write target, value || KatakataIrb::Types::NIL, scope, evaluated_receivers
1051
1054
  end
1052
1055
  end
@@ -1054,7 +1057,8 @@ class KatakataIrb::TypeAnalyzer
1054
1057
  def evaluate_multi_write_receiver(node, scope, evaluated_receivers)
1055
1058
  case node
1056
1059
  when Prism::MultiWriteNode, Prism::MultiTargetNode
1057
- node.targets.each { evaluate_multi_write_receiver _1, scope, evaluated_receivers }
1060
+ targets = [*node.lefts, *node.rest, *node.rights]
1061
+ targets.each { evaluate_multi_write_receiver _1, scope, evaluated_receivers }
1058
1062
  when Prism::CallNode
1059
1063
  if node.receiver
1060
1064
  receiver = evaluate(node.receiver, scope)
@@ -47,8 +47,6 @@ module KatakataIrb::Types
47
47
  def self.method_return_type(type, method_name)
48
48
  receivers = type.types.map do |t|
49
49
  case t
50
- in ProcType
51
- [t, Proc, false]
52
50
  in SingletonType
53
51
  [t, t.module_or_class, true]
54
52
  in InstanceType
@@ -70,8 +68,6 @@ module KatakataIrb::Types
70
68
 
71
69
  receivers = type.types.map do |t|
72
70
  case t
73
- in ProcType
74
- [t, Proc, false]
75
71
  in SingletonType
76
72
  [t, t.module_or_class, true]
77
73
  in InstanceType
@@ -125,7 +121,6 @@ module KatakataIrb::Types
125
121
  def self.intersect?(a, b)
126
122
  atypes = a.types.group_by(&:class)
127
123
  btypes = b.types.group_by(&:class)
128
- return true if atypes[ProcType] && btypes[ProcType]
129
124
  if atypes[SingletonType] && btypes[SingletonType]
130
125
  aa, bb = [atypes, btypes].map {|types| types[SingletonType].map(&:module_or_class) }
131
126
  return true if (aa & bb).any?
@@ -233,23 +228,6 @@ module KatakataIrb::Types
233
228
  end
234
229
  end
235
230
 
236
- class ProcType
237
- attr_reader :params, :kwparams, :return_type
238
- def initialize(params = [], kwparams = {}, return_type = NIL)
239
- @params = params
240
- @kwparams = kwparams
241
- @return_type = return_type
242
- end
243
- def transform() = yield(self)
244
- def methods() = Proc.instance_methods
245
- def all_methods() = Proc.instance_methods | Proc.private_instance_methods
246
- def constants() = []
247
- def types() = [self]
248
- def nillable?() = (@klass == NilClass)
249
- def nonnillable() = self
250
- def inspect() = 'Proc'
251
- end
252
-
253
231
  NIL = InstanceType.new NilClass
254
232
  OBJECT = InstanceType.new Object
255
233
  TRUE = InstanceType.new TrueClass
@@ -266,7 +244,7 @@ module KatakataIrb::Types
266
244
  HASH = InstanceType.new Hash
267
245
  CLASS = InstanceType.new Class
268
246
  MODULE = InstanceType.new Module
269
- PROC = ProcType.new
247
+ PROC = InstanceType.new Proc
270
248
 
271
249
  class UnionType
272
250
  attr_reader :types
@@ -275,7 +253,6 @@ module KatakataIrb::Types
275
253
  @types = []
276
254
  singletons = []
277
255
  instances = {}
278
- procs = []
279
256
  collect = -> type do
280
257
  case type
281
258
  in UnionType
@@ -287,12 +264,10 @@ module KatakataIrb::Types
287
264
  end
288
265
  in SingletonType
289
266
  singletons << type
290
- in ProcType
291
- procs << type
292
267
  end
293
268
  end
294
269
  types.each(&collect)
295
- @types = procs.uniq + singletons.uniq + instances.map do |klass, params|
270
+ @types = singletons.uniq + instances.map do |klass, params|
296
271
  InstanceType.new(klass, params.transform_values { |v| UnionType[*v] })
297
272
  end
298
273
  end
@@ -364,7 +339,7 @@ module KatakataIrb::Types
364
339
  when RBS::Types::Union
365
340
  UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }]
366
341
  when RBS::Types::Proc
367
- InstanceType.new Proc
342
+ PROC
368
343
  when RBS::Types::Tuple
369
344
  elem = UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }]
370
345
  InstanceType.new Array, Elem: elem
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KatakataIrb
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.2"
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.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - tompng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-18 00:00:00.000000000 Z
11
+ date: 2023-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: irb
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.14.0
47
+ version: 0.16.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.14.0
54
+ version: 0.16.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rbs
57
57
  requirement: !ruby/object:Gem::Requirement