katakata_irb 0.2.1 → 0.2.3

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: aceac4c5bece32a19a242c927326fa87814f34524368a90d1742ce9f66a055d4
4
+ data.tar.gz: 0c66cdde7506e1bace2fe342dae2104434ab0622cff5578c099e6e0f9179845c
5
5
  SHA512:
6
- metadata.gz: 4b406ecd5c611cdc86220efa506c403dff220db4be5fb1bc1fab10eeb70931f0d7eaee8a45a702a6addb5de793e0c219562975d769fe31616305cd87fe4cfa4a
7
- data.tar.gz: 147b09a36c68a66c917fff2157797d1124ec06e0333ee7cec26ef83b9d726c398bb83bbdce81f88c1706067ecc3f9bf99506d5706d3b22ccc3c8aa2ee6ce5cb1
6
+ metadata.gz: c806348785e27e8cd604ba978c18762826f087ed1406d0fc608d8334becb7b1b6d45f7e7a275cfef94455169719ab4e6ccfb0f4aa648c518a7f34915ed81961c
7
+ data.tar.gz: 26324135a3b7b153f093da98e0b3d7824aa6969b6135b26eb85da0eecdb4a3f04b8026946f898d2b1852315102d3101104f2fadc8bb0dbdd840b7856d10cd7fc
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
@@ -172,6 +172,8 @@ class KatakataIrb::TypeAnalyzer
172
172
  keys << evaluate(assoc.key, scope)
173
173
  values << evaluate(assoc.value, scope)
174
174
  when Prism::AssocSplatNode
175
+ next unless assoc.value # def f(**); {**}
176
+
175
177
  hash = evaluate assoc.value, scope
176
178
  unless hash.is_a?(KatakataIrb::Types::InstanceType) && hash.klass == Hash
177
179
  hash = method_call hash, :to_hash, [], nil, nil, scope
@@ -231,7 +233,7 @@ class KatakataIrb::TypeAnalyzer
231
233
 
232
234
 
233
235
  def evaluate_call_node(node, scope)
234
- # TODO: return type of []=, field= when operator_loc.nil?
236
+ is_field_assign = node.name.match?(/[^<>=!\]]=\z/) || (node.name == :[]= && !node.call_operator)
235
237
  receiver_type = node.receiver ? evaluate(node.receiver, scope) : scope.self_type
236
238
  evaluate_method = lambda do |scope|
237
239
  args_types, kwargs_types, block_sym_node, has_block = evaluate_call_node_arguments node, scope
@@ -280,7 +282,12 @@ class KatakataIrb::TypeAnalyzer
280
282
  elsif has_block
281
283
  call_block_proc = ->(_block_args, _self_type) { KatakataIrb::Types::OBJECT }
282
284
  end
283
- method_call receiver_type, node.name, args_types, kwargs_types, call_block_proc, scope
285
+ result = method_call receiver_type, node.name, args_types, kwargs_types, call_block_proc, scope
286
+ if is_field_assign
287
+ args_types.last || KatakataIrb::Types::NIL
288
+ else
289
+ result
290
+ end
284
291
  end
285
292
  if node.call_operator == '&.'
286
293
  result = scope.conditional { evaluate_method.call _1 }
@@ -314,8 +321,7 @@ class KatakataIrb::TypeAnalyzer
314
321
  def evaluate_index_or_write_node(node, scope) = evaluate_call_write(node, scope, :or, :[]=)
315
322
  def evaluate_call_write(node, scope, operator, write_name)
316
323
  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
324
+ if write_name == :[]=
319
325
  args_types, kwargs_types, block_sym_node, has_block = evaluate_call_node_arguments node, scope
320
326
  else
321
327
  args_types = []
@@ -430,7 +436,7 @@ class KatakataIrb::TypeAnalyzer
430
436
  end
431
437
  block_scope.merge_jumps
432
438
  scope.update block_scope
433
- KatakataIrb::Types::ProcType.new
439
+ KatakataIrb::Types::PROC
434
440
  end
435
441
 
436
442
  def evaluate_reference_write(node, scope)
@@ -457,7 +463,6 @@ class KatakataIrb::TypeAnalyzer
457
463
  elsif node.value
458
464
  evaluate node.value, scope
459
465
  else
460
- # For syntax invalid code like `(*a).b`
461
466
  KatakataIrb::Types::NIL
462
467
  end
463
468
  )
@@ -748,6 +753,12 @@ class KatakataIrb::TypeAnalyzer
748
753
  KatakataIrb::Types::NIL
749
754
  end
750
755
 
756
+ def evaluate_splat_node(node, scope)
757
+ # Raw SplatNode, incomplete code like `*a.`
758
+ evaluate_multi_write_receiver node.expression, scope, nil if node.expression
759
+ KatakataIrb::Types::NIL
760
+ end
761
+
751
762
  def evaluate_implicit_node(node, scope)
752
763
  evaluate node.value, scope
753
764
  end
@@ -784,7 +795,7 @@ class KatakataIrb::TypeAnalyzer
784
795
  def evaluate_call_node_arguments(call_node, scope)
785
796
  # call_node.arguments is Prism::ArgumentsNode
786
797
  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)
798
+ block_arg = call_node.block.expression if call_node.block.is_a?(Prism::BlockArgumentNode)
788
799
  kwargs = arguments.pop.elements if arguments.last.is_a?(Prism::KeywordHashNode)
789
800
  args_types = arguments.map do |arg|
790
801
  case arg
@@ -792,7 +803,7 @@ class KatakataIrb::TypeAnalyzer
792
803
  # `f(a, ...)` treat like splat
793
804
  nil
794
805
  when Prism::SplatNode
795
- evaluate arg.expression, scope
806
+ evaluate arg.expression, scope if arg.expression
796
807
  nil # TODO: splat
797
808
  else
798
809
  evaluate arg, scope
@@ -810,7 +821,7 @@ class KatakataIrb::TypeAnalyzer
810
821
  nil
811
822
  end
812
823
  when Prism::AssocSplatNode
813
- evaluate arg.value, scope
824
+ evaluate arg.value, scope if arg.value
814
825
  nil
815
826
  end
816
827
  end.compact.to_h
@@ -833,17 +844,18 @@ class KatakataIrb::TypeAnalyzer
833
844
  end
834
845
 
835
846
  def assign_required_parameter(node, value, scope)
836
- case node
837
- when Prism::RequiredParameterNode
847
+ case node.type
848
+ when :required_parameter_node
838
849
  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|
850
+ when :multi_target_node
851
+ parameters = [*node.lefts, *node.rest, *node.rights]
852
+ values = value ? sized_splat(value, :to_ary, parameters.size) : []
853
+ parameters.zip values do |n, v|
842
854
  assign_required_parameter n, v, scope
843
855
  end
844
- when Prism::SplatNode
856
+ when :splat_node
845
857
  splat_value = value ? KatakataIrb::Types.array_of(value) : KatakataIrb::Types::ARRAY
846
- assign_required_parameter node.expression, splat_value, scope
858
+ assign_required_parameter node.expression, splat_value, scope if node.expression
847
859
  end
848
860
  end
849
861
 
@@ -881,7 +893,7 @@ class KatakataIrb::TypeAnalyzer
881
893
  args = sized_splat(args.first, :to_ary, size) if size >= 2 && args.size == 1
882
894
  reqs = args.shift node.requireds.size
883
895
  if node.rest
884
- # node.rest.class is Prism::RestParameterNode
896
+ # node.rest is Prism::RestParameterNode
885
897
  posts = []
886
898
  opts = args.shift node.optionals.size
887
899
  rest = args
@@ -907,10 +919,12 @@ class KatakataIrb::TypeAnalyzer
907
919
  scope[node.rest.name.to_s] = KatakataIrb::Types.array_of(*rest)
908
920
  end
909
921
  node.keywords.each do |n|
910
- # n is Prism::KeywordParameterNode
922
+ # n is Prism::KeywordParameterNode (prism = 0.16.0)
923
+ # n is Prism::RequiredKeywordParameterNode | Prism::OptionalKeywordParameterNode (prism > 0.16.0)
911
924
  name = n.name.to_s.delete(':')
912
925
  values = [kwargs.delete(name)]
913
- values << evaluate(n.value, scope) if n.value
926
+ # `respond_to?` is for prism > 0.16.0, `&& n.value` is for prism = 0.16.0
927
+ values << evaluate(n.value, scope) if n.respond_to?(:value) && n.value
914
928
  scope[name] = KatakataIrb::Types::UnionType[*values.compact]
915
929
  end
916
930
  # node.keyword_rest is Prism::KeywordRestParameterNode or Prism::ForwardingParameterNode or Prism::NoKeywordsParameterNode
@@ -927,13 +941,7 @@ class KatakataIrb::TypeAnalyzer
927
941
  return if numbered_parameters.empty?
928
942
  max_num = numbered_parameters.map { _1[1].to_i }.max
929
943
  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
944
+ scope['_1'] = args.first || KatakataIrb::Types::NIL
937
945
  else
938
946
  args = sized_splat(args.first, :to_ary, max_num) if args.size == 1
939
947
  numbered_parameters.each do |name|
@@ -976,7 +984,10 @@ class KatakataIrb::TypeAnalyzer
976
984
  KatakataIrb::Types::ARRAY
977
985
  when Prism::HashPatternNode
978
986
  # TODO
979
- pattern.assocs.each { evaluate_match_pattern KatakataIrb::Types::OBJECT, _1, scope }
987
+ pattern.elements.each { evaluate_match_pattern KatakataIrb::Types::OBJECT, _1, scope }
988
+ if pattern.respond_to?(:rest) && pattern.rest
989
+ evaluate_match_pattern KatakataIrb::Types::OBJECT, pattern.rest, scope
990
+ end
980
991
  KatakataIrb::Types::HASH
981
992
  when Prism::AssocNode
982
993
  evaluate_match_pattern value, pattern.value, scope if pattern.value
@@ -1022,7 +1033,7 @@ class KatakataIrb::TypeAnalyzer
1022
1033
  when Prism::CallNode
1023
1034
  evaluated_receivers&.[](node.receiver) || evaluate(node.receiver, scope) if node.receiver
1024
1035
  when Prism::SplatNode
1025
- evaluate_write node.expression, KatakataIrb::Types.array_of(value), scope, evaluated_receivers
1036
+ evaluate_write node.expression, KatakataIrb::Types.array_of(value), scope, evaluated_receivers if node.expression
1026
1037
  when Prism::LocalVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::ConstantTargetNode
1027
1038
  scope[node.name.to_s] = value
1028
1039
  when Prism::ConstantPathTargetNode
@@ -1033,20 +1044,15 @@ class KatakataIrb::TypeAnalyzer
1033
1044
  end
1034
1045
 
1035
1046
  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|
1047
+ pre_targets = node.lefts
1048
+ splat_target = node.rest
1049
+ post_targets = node.rights
1050
+ size = pre_targets.size + (splat_target ? 1 : 0) + post_targets.size
1051
+ values = values.is_a?(Array) ? values.dup : sized_splat(values, :to_ary, size)
1052
+ pre_pairs = pre_targets.zip(values.shift(pre_targets.size))
1053
+ post_pairs = post_targets.zip(values.pop(post_targets.size))
1054
+ splat_pairs = splat_target ? [[splat_target, KatakataIrb::Types::UnionType[*values]]] : []
1055
+ (pre_pairs + splat_pairs + post_pairs).each do |target, value|
1050
1056
  evaluate_write target, value || KatakataIrb::Types::NIL, scope, evaluated_receivers
1051
1057
  end
1052
1058
  end
@@ -1054,7 +1060,8 @@ class KatakataIrb::TypeAnalyzer
1054
1060
  def evaluate_multi_write_receiver(node, scope, evaluated_receivers)
1055
1061
  case node
1056
1062
  when Prism::MultiWriteNode, Prism::MultiTargetNode
1057
- node.targets.each { evaluate_multi_write_receiver _1, scope, evaluated_receivers }
1063
+ targets = [*node.lefts, *node.rest, *node.rights]
1064
+ targets.each { evaluate_multi_write_receiver _1, scope, evaluated_receivers }
1058
1065
  when Prism::CallNode
1059
1066
  if node.receiver
1060
1067
  receiver = evaluate(node.receiver, scope)
@@ -1077,13 +1084,15 @@ class KatakataIrb::TypeAnalyzer
1077
1084
  def evaluate_list_splat_items(list, scope)
1078
1085
  items = list.flat_map do |node|
1079
1086
  if node.is_a? Prism::SplatNode
1087
+ next unless node.expression # def f(*); [*]
1088
+
1080
1089
  splat = evaluate node.expression, scope
1081
1090
  array_elem, non_array = partition_to_array splat.nonnillable, :to_a
1082
1091
  [*array_elem, *non_array]
1083
1092
  else
1084
1093
  evaluate node, scope
1085
1094
  end
1086
- end.uniq
1095
+ end.compact.uniq
1087
1096
  KatakataIrb::Types::UnionType[*items]
1088
1097
  end
1089
1098
 
@@ -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.3"
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.3
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-11-03 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