katakata_irb 0.2.1 → 0.2.2

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: 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