katakata_irb 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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