katakata_irb 0.1.5 → 0.1.6

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: 882c0834b6d52916911b26b82083e1100491dd24cafdb1c948c4c1795fe03d7e
4
- data.tar.gz: 2250eaec5d0b1cabc236f238249e132206b62e70ada1c16429567b680ace2093
3
+ metadata.gz: df817c7e7806e6ea21aa82e14a694130b0db5dd68c74ea84790b90ad3b895fb7
4
+ data.tar.gz: 9faa1d72b27f35bccc5b4d2dcc5c9f50b4dd9946ba5d63374d3083e933e62c38
5
5
  SHA512:
6
- metadata.gz: 60f3c4de13636f2948e740b3a57b6091c1f193ae7fa259d665c69a404833ef413b90aca3da7360f97be2d7a669e9a0d5fc101ff172890c4f0714c9eb63db8dd4
7
- data.tar.gz: eb496c54819de4f1e035e261a6afffcc13d2809b316428602567614dbc5671df5ead97fb4a0696afbb34a7ade9ce8a2b3e9579ebad4ddd006d9a32b120b3e05d
6
+ metadata.gz: 9bec77d0fd1f9484278541e48a964c683ef2546b8a5b107e731d7979b634c4c8fb9ce2b68261603fc5f4ad8eb83cfb3018e11881a2ecd4096d268e7be0e97405
7
+ data.tar.gz: b6520a88ad8644423f24e7c02e783bf1cb388b3a00d2c16151b97e08598f1fd80f55f8346562d00c9d2ec0e2b619d4f4db23eeba5834c39b9ebfc72ce765cbdb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- katakata_irb (0.1.5)
4
+ katakata_irb (0.1.6)
5
5
  irb (>= 1.4.0)
6
6
  rbs
7
7
 
@@ -87,7 +87,7 @@ module KatakataIrb
87
87
  end
88
88
 
89
89
  class Scope < BaseScope
90
- attr_reader :parent, :jump_branches, :mergeable_changes, :level
90
+ attr_reader :parent, :jump_branches, :mergeable_changes, :level, :lvars
91
91
 
92
92
  def self.from_binding(binding) = new(BaseScope.new(binding, binding.eval('self')))
93
93
 
@@ -101,6 +101,7 @@ module KatakataIrb
101
101
  @passthrough = passthrough
102
102
  @terminated = false
103
103
  @jump_branches = []
104
+ @lvars = Set.new
104
105
  @mergeable_changes = @changes = table.transform_values { [level, _1] }
105
106
  end
106
107
 
@@ -156,6 +157,7 @@ module KatakataIrb
156
157
 
157
158
  def []=(name, value)
158
159
  variable_level = level_of(name) || level
160
+ @lvars << name if level == variable_level && BaseScope.type_by_name(name) == :lvar
159
161
  @changes[name] = [variable_level, value]
160
162
  end
161
163
 
@@ -197,12 +199,17 @@ module KatakataIrb
197
199
  update scope
198
200
  end
199
201
 
202
+ def touch_lvars(lvars)
203
+ lvars.each { self[_1] = self[_1] || KatakataIrb::Types::NIL }
204
+ end
205
+
200
206
  def run_branches(*blocks)
201
207
  results = []
202
208
  branches = []
203
209
  blocks.each do |block|
204
210
  scope = Scope.new self, passthrough: true
205
211
  result = block.call scope
212
+ touch_lvars scope.lvars if scope.level == level
206
213
  next if scope.terminated?
207
214
  results << result
208
215
  branches << scope.mergeable_changes
@@ -222,6 +229,7 @@ module KatakataIrb
222
229
 
223
230
  def update(child_scope)
224
231
  current_level = level
232
+ touch_lvars child_scope.lvars if child_scope.level == current_level
225
233
  child_scope.mergeable_changes.each do |name, (level, value)|
226
234
  self[name] = value if level <= current_level
227
235
  end
@@ -70,7 +70,7 @@ class KatakataIrb::TypeSimulator
70
70
  else
71
71
  current_self_types = scope.self_type.types
72
72
  self_types = current_self_types.map do |type|
73
- if (type in KatakataIrb::Types::SingletonType) && type.module_or_class.is_a?(Class)
73
+ if type.is_a?(KatakataIrb::Types::SingletonType) && type.module_or_class.is_a?(Class)
74
74
  KatakataIrb::Types::InstanceType.new type.module_or_class
75
75
  else
76
76
  type
@@ -129,10 +129,10 @@ class KatakataIrb::TypeSimulator
129
129
  in [:array, [:args_add_star,] => star]
130
130
  args, kwargs = retrieve_method_args star
131
131
  types = args.flat_map do |elem|
132
- if elem in KatakataIrb::Types::Splat
132
+ if elem.is_a? KatakataIrb::Types::Splat
133
133
  splat = simulate_evaluate elem.item, scope
134
- array_value = to_array splat, :to_a
135
- array_value ? (array_value.params[:Elem] || []) : splat
134
+ array_elem, non_array = partition_to_array splat.nonnillable, :to_a
135
+ KatakataIrb::Types::UnionType[*array_elem, *non_array]
136
136
  else
137
137
  simulate_evaluate elem, scope
138
138
  end
@@ -173,10 +173,10 @@ class KatakataIrb::TypeSimulator
173
173
  values << simulate_evaluate(value, scope)
174
174
  in [:assoc_splat, value]
175
175
  hash = simulate_evaluate value, scope
176
- unless (hash in KatakataIrb::Types::InstanceType) && hash.klass == Hash
176
+ unless hash.is_a?(KatakataIrb::Types::InstanceType) && hash.klass == Hash
177
177
  hash = simulate_call hash, :to_hash, [], nil, nil
178
178
  end
179
- if (hash in KatakataIrb::Types::InstanceType) && hash.klass == Hash
179
+ if hash.is_a?(KatakataIrb::Types::InstanceType) && hash.klass == Hash
180
180
  keys << hash.params[:K] if hash.params[:K]
181
181
  values << hash.params[:V] if hash.params[:V]
182
182
  end
@@ -192,7 +192,7 @@ class KatakataIrb::TypeSimulator
192
192
  statements.map { simulate_evaluate _1, scope }.last
193
193
  in [:const_path_ref, receiver, [:@const, name,]]
194
194
  r = simulate_evaluate receiver, scope
195
- (r in KatakataIrb::Types::SingletonType) ? KatakataIrb::BaseScope.type_of { r.module_or_class.const_get name } : KatakataIrb::Types::NIL
195
+ r.is_a?(KatakataIrb::Types::SingletonType) ? KatakataIrb::BaseScope.type_of { r.module_or_class.const_get name } : KatakataIrb::Types::NIL
196
196
  in [:__var_ref_or_call, [type, name, pos]]
197
197
  sexp = scope.has?(name) ? [:var_ref, [type, name, pos]] : [:vcall, [:@ident, name, pos]]
198
198
  simulate_evaluate sexp, scope
@@ -221,7 +221,7 @@ class KatakataIrb::TypeSimulator
221
221
  receiver_type = simulate_evaluate receiver, scope if receiver
222
222
  args, kwargs, _block = retrieve_method_args args
223
223
  args_type = args.map do |arg|
224
- if arg in KatakataIrb::Types::Splat
224
+ if arg.is_a? KatakataIrb::Types::Splat
225
225
  simulate_evaluate arg.item, scope
226
226
  nil # TODO: splat
227
227
  else
@@ -242,7 +242,7 @@ class KatakataIrb::TypeSimulator
242
242
  receiver_type = receiver ? simulate_evaluate(receiver, scope) : scope.self_type
243
243
  evaluate_method = lambda do |scope|
244
244
  args_type = args.map do |arg|
245
- if arg in KatakataIrb::Types::Splat
245
+ if arg.is_a? KatakataIrb::Types::Splat
246
246
  simulate_evaluate arg.item, scope
247
247
  nil # TODO: splat
248
248
  else
@@ -342,7 +342,7 @@ class KatakataIrb::TypeSimulator
342
342
  simulate_evaluate receiver, scope
343
343
  args, kwargs, _block = retrieve_method_args key
344
344
  args.each do |arg|
345
- item = ((arg in KatakataIrb::Types::Splat) ? arg.item : arg)
345
+ item = arg.is_a?(KatakataIrb::Types::Splat) ? arg.item : arg
346
346
  simulate_evaluate item, scope
347
347
  end
348
348
  kwargs_type kwargs, scope
@@ -435,7 +435,7 @@ class KatakataIrb::TypeSimulator
435
435
  in [:super, args]
436
436
  args, kwargs, _block = retrieve_method_args args
437
437
  args.each do |arg|
438
- item = ((arg in KatakataIrb::Types::Splat) ? arg.item : arg)
438
+ item = arg.is_a?(KatakataIrb::Types::Splat) ? arg.item : arg
439
439
  simulate_evaluate item, scope
440
440
  end
441
441
  kwargs_type kwargs, scope
@@ -460,7 +460,7 @@ class KatakataIrb::TypeSimulator
460
460
  error_class_stmts = [*stmts, stmt]
461
461
  end
462
462
  error_classes = (error_class_stmts || []).flat_map { simulate_evaluate _1, s }.uniq
463
- error_types = error_classes.filter_map { KatakataIrb::Types::InstanceType.new _1.module_or_class if _1 in KatakataIrb::Types::SingletonType }
463
+ error_types = error_classes.filter_map { KatakataIrb::Types::InstanceType.new _1.module_or_class if _1.is_a?(KatakataIrb::Types::SingletonType) }
464
464
  error_types << KatakataIrb::Types::InstanceType.new(StandardError) if error_types.empty?
465
465
  s[error_var] = KatakataIrb::Types::UnionType[*error_types]
466
466
  end
@@ -486,7 +486,7 @@ class KatakataIrb::TypeSimulator
486
486
  result
487
487
  in [:sclass, klass_stmt, body_stmt]
488
488
  klass_types = simulate_evaluate(klass_stmt, scope).types.filter_map do |type|
489
- KatakataIrb::Types::SingletonType.new type.klass if type in KatakataIrb::Types::InstanceType
489
+ KatakataIrb::Types::SingletonType.new type.klass if type.is_a? KatakataIrb::Types::InstanceType
490
490
  end
491
491
  klass_types = [KatakataIrb::Types::CLASS] if klass_types.empty?
492
492
  sclass_scope = KatakataIrb::Scope.new(scope, { KatakataIrb::Scope::SELF => KatakataIrb::Types::UnionType[*klass_types], KatakataIrb::Scope::BREAK_RESULT => nil, KatakataIrb::Scope::NEXT_RESULT => nil, KatakataIrb::Scope::RETURN_RESULT => nil }, trace_cvar: false, trace_ivar: false, trace_lvar: false)
@@ -497,7 +497,7 @@ class KatakataIrb::TypeSimulator
497
497
  klass_types = simulate_evaluate(klass_stmt, scope).types
498
498
  klass_types += simulate_evaluate(superclass_stmt, scope).types if superclass_stmt
499
499
  klass_types = klass_types.select do |type|
500
- (type in KatakataIrb::Types::SingletonType) && type.module_or_class.is_a?(Class)
500
+ type.is_a?(KatakataIrb::Types::SingletonType) && type.module_or_class.is_a?(Class)
501
501
  end
502
502
  klass_types << KatakataIrb::Types::CLASS if klass_types.empty?
503
503
  klass_scope = KatakataIrb::Scope.new(scope, { KatakataIrb::Scope::SELF => KatakataIrb::Types::UnionType[*klass_types], KatakataIrb::Scope::BREAK_RESULT => nil, KatakataIrb::Scope::NEXT_RESULT => nil, KatakataIrb::Scope::RETURN_RESULT => nil }, trace_cvar: false, trace_ivar: false, trace_lvar: false)
@@ -571,6 +571,9 @@ class KatakataIrb::TypeSimulator
571
571
  simulate_evaluate a, scope
572
572
  simulate_evaluate b, scope
573
573
  KatakataIrb::Types::STRING
574
+ in [:defined, expression]
575
+ scope.conditional { simulate_evaluate expression, _1 }
576
+ KatakataIrb::Types::UnionType[KatakataIrb::Types::STRING, KatakataIrb::Types::NIL]
574
577
  else
575
578
  KatakataIrb.log_puts
576
579
  KatakataIrb.log_puts :NOMATCH
@@ -597,7 +600,7 @@ class KatakataIrb::TypeSimulator
597
600
  in [:binary, lpattern, :'=>', [:var_field, [:@ident, name,]] => rpattern]
598
601
  if lpattern in [:var_ref, [:@const, _const_name,]]
599
602
  const_value = simulate_evaluate lpattern, scope
600
- if (const_value in KatakataIrb::Types::SingletonType) && const_value.module_or_class.is_a?(Class)
603
+ if const_value.is_a?(KatakataIrb::Types::SingletonType) && const_value.module_or_class.is_a?(Class)
601
604
  scope[name] = KatakataIrb::Types::InstanceType.new const_value.module_or_class
602
605
  else
603
606
  scope[name] = KatakataIrb::Types::OBJECT
@@ -609,7 +612,7 @@ class KatakataIrb::TypeSimulator
609
612
  end
610
613
  in [:aryptn, _unknown, items, splat, post_items]
611
614
  # TODO: deconstruct keys
612
- array_types = types.select { (_1 in KatakataIrb::Types::InstanceType) && _1.klass == Array }
615
+ array_types = types.select { _1.is_a?(KatakataIrb::Types::InstanceType) && _1.klass == Array }
613
616
  elem = KatakataIrb::Types::UnionType[*array_types.filter_map { _1.params[:Elem] }]
614
617
  items&.each do |item|
615
618
  match_pattern elem, item, scope
@@ -623,7 +626,7 @@ class KatakataIrb::TypeSimulator
623
626
  end
624
627
  in [:hshptn, _unknown, items, splat]
625
628
  # TODO: deconstruct keys
626
- hash_types = types.select { (_1 in KatakataIrb::Types::InstanceType) && _1.klass == Hash }
629
+ hash_types = types.select { _1.is_a?(KatakataIrb::Types::InstanceType) && _1.klass == Hash }
627
630
  key_type = KatakataIrb::Types::UnionType[*hash_types.filter_map { _1.params[:K] }]
628
631
  value_type = KatakataIrb::Types::UnionType[*hash_types.filter_map { _1.params[:V] }]
629
632
  items&.each do |key_pattern, value_pattern|
@@ -652,7 +655,7 @@ class KatakataIrb::TypeSimulator
652
655
  def evaluate_mrhs(sexp, scope)
653
656
  args, kwargs, = retrieve_method_args sexp
654
657
  values = args.filter_map do |t|
655
- if t in KatakataIrb::Types::Splat
658
+ if t.is_a? KatakataIrb::Types::Splat
656
659
  simulate_evaluate t.item, scope
657
660
  # TODO
658
661
  nil
@@ -679,17 +682,31 @@ class KatakataIrb::TypeSimulator
679
682
  [values, kw]
680
683
  end
681
684
 
682
- def to_array(value, method)
683
- return value if (value in KatakataIrb::Types::InstanceType) && value.klass == Array
684
- to_array_result = simulate_call value, method, [], nil, nil, name_match: false
685
- return to_array_result if (to_array_result in KatakataIrb::Types::InstanceType) && to_array_result.klass == Array
685
+ def sized_splat(value, method, size)
686
+ array_elem, non_array = partition_to_array value, method
687
+ values = [KatakataIrb::Types::UnionType[*array_elem, *non_array]]
688
+ values += [array_elem] * (size - 1) if array_elem && size >= 1
689
+ values
686
690
  end
687
691
 
688
- def evaluate_massign(sexp, values, scope)
689
- unless values in Array
690
- array_value = to_array values, :to_ary
691
- values = array_value ? [array_value.params[:Elem] || KatakataIrb::Types::OBJECT] * sexp.size : [values]
692
+ def partition_to_array(value, method)
693
+ arrays, non_arrays = value.types.partition { _1.is_a?(KatakataIrb::Types::InstanceType) && _1.klass == Array }
694
+ non_arrays.select! do |type|
695
+ to_array_result = simulate_call type, method, [], nil, nil, name_match: false
696
+ if to_array_result.is_a?(KatakataIrb::Types::InstanceType) && to_array_result.klass == Array
697
+ arrays << to_array_result
698
+ false
699
+ else
700
+ true
701
+ end
692
702
  end
703
+ array_elem = arrays.empty? ? nil : KatakataIrb::Types::UnionType[*arrays.map { _1.params[:Elem] || KatakataIrb::Types::OBJECT }]
704
+ non_array = non_arrays.empty? ? nil : KatakataIrb::Types::UnionType[*non_arrays]
705
+ [array_elem, non_array]
706
+ end
707
+
708
+ def evaluate_massign(sexp, values, scope)
709
+ values = sized_splat values, :to_ary, sexp.size unless values.is_a? Array
693
710
 
694
711
  rest_index = sexp.find_index { _1 in [:rest_param, ]}
695
712
  if rest_index
@@ -729,12 +746,12 @@ class KatakataIrb::TypeSimulator
729
746
  keys = []
730
747
  values = []
731
748
  kwargs.each do |kv|
732
- if kv in KatakataIrb::Types::Splat
749
+ if kv.is_a? KatakataIrb::Types::Splat
733
750
  hash = simulate_evaluate kv.item, scope
734
- unless (hash in KatakataIrb::Types::InstanceType) && hash.klass == Hash
751
+ unless hash.is_a?(KatakataIrb::Types::InstanceType) && hash.klass == Hash
735
752
  hash = simulate_call hash, :to_hash, [], nil, nil
736
753
  end
737
- if (hash in KatakataIrb::Types::InstanceType) && hash.klass == Hash
754
+ if hash.is_a?(KatakataIrb::Types::InstanceType) && hash.klass == Hash
738
755
  keys << hash.params[:K] if hash.params[:K]
739
756
  values << hash.params[:V] if hash.params[:V]
740
757
  end
@@ -822,6 +839,8 @@ class KatakataIrb::TypeSimulator
822
839
  [args, [], nil]
823
840
  in [:arg_paren, args]
824
841
  args ? retrieve_method_args(args) : [[], [], nil]
842
+ in [[:command | :command_call, ] => command_arg] # method(a b, c), method(a.b c, d)
843
+ [[command_arg], [], nil]
825
844
  else
826
845
  [[], [], nil]
827
846
  end
@@ -901,11 +920,7 @@ class KatakataIrb::TypeSimulator
901
920
  values = values.dup
902
921
  params => [:params, pre_required, optional, rest, post_required, _keywords, keyrest, block]
903
922
  size = (pre_required&.size || 0) + (optional&.size || 0) + (post_required&.size || 0) + (rest ? 1 : 0)
904
- if values.size == 1 && size >= 2
905
- value = values.first
906
- array_value = to_array value, :to_ary if value
907
- values = [array_value.params[:Elem] || KatakataIrb::Types::OBJECT] * size if array_value
908
- end
923
+ values = sized_splat values.first, :to_ary, size if values.size == 1 && size >= 2
909
924
  pre_values = values.shift pre_required.size if pre_required
910
925
  post_values = values.pop post_required.size if post_required
911
926
  opt_values = values.shift optional.size if optional
@@ -955,7 +970,7 @@ class KatakataIrb::TypeSimulator
955
970
  name.match?(/\A_[1-9]\z/) ? name[1..].to_i : 0
956
971
  else
957
972
  sexp.filter_map do |s|
958
- max_numbered_params s if s in Array
973
+ max_numbered_params s if s.is_a? Array
959
974
  end.max || 0
960
975
  end
961
976
  end
@@ -4,9 +4,16 @@ require 'rbs/cli'
4
4
  module KatakataIrb; end
5
5
  module KatakataIrb::Types
6
6
  def self.rbs_builder
7
- @rbs_builder ||= RBS::DefinitionBuilder.new(
8
- env: RBS::Environment.from_loader(RBS::CLI::LibraryOptions.new.loader).resolve_type_names
9
- )
7
+ @rbs_builder ||= load_rbs_builder
8
+ end
9
+
10
+ def self.load_rbs_builder
11
+ loader = RBS::CLI::LibraryOptions.new.loader
12
+ loader.add path: Pathname('sig')
13
+ RBS::DefinitionBuilder.new env: RBS::Environment.from_loader(loader).resolve_type_names
14
+ rescue => e
15
+ puts "\nKatakataIRB failed to initialize RBS::DefinitionBuild\n#{e}"
16
+ Object.new
10
17
  end
11
18
 
12
19
  Splat = Struct.new :item
@@ -24,7 +31,7 @@ module KatakataIrb::Types
24
31
  next unless name
25
32
  type_name = RBS::TypeName(name).absolute!
26
33
  definition = (singleton ? rbs_builder.build_singleton(type_name) : rbs_builder.build_instance(type_name)) rescue nil
27
- method = definition&.methods&.[](method_name)
34
+ method = definition.methods[method_name] if definition
28
35
  return method if method
29
36
  end
30
37
  nil
@@ -170,6 +177,9 @@ module KatakataIrb::Types
170
177
  def types() = [self]
171
178
  def nillable?() = false
172
179
  def nonnillable() = self
180
+ def inspect
181
+ "#{module_or_class}.itself"
182
+ end
173
183
  end
174
184
 
175
185
  class InstanceType
@@ -185,6 +195,19 @@ module KatakataIrb::Types
185
195
  def types() = [self]
186
196
  def nillable?() = (@klass == NilClass)
187
197
  def nonnillable() = self
198
+ def inspect
199
+ case klass
200
+ when NilClass
201
+ 'nil'
202
+ when TrueClass
203
+ 'true'
204
+ when FalseClass
205
+ 'false'
206
+ else
207
+ params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]" unless params.empty?
208
+ "#{klass.name}#{params_string}"
209
+ end
210
+ end
188
211
  end
189
212
 
190
213
  class ProcType
@@ -201,6 +224,7 @@ module KatakataIrb::Types
201
224
  def types() = [self]
202
225
  def nillable?() = (@klass == NilClass)
203
226
  def nonnillable() = self
227
+ def inspect() = 'Proc'
204
228
  end
205
229
 
206
230
  NIL = InstanceType.new NilClass
@@ -276,6 +300,7 @@ module KatakataIrb::Types
276
300
  def methods() = @types.flat_map(&:methods).uniq
277
301
  def all_methods() = @types.flat_map(&:all_methods).uniq
278
302
  def constants() = @types.flat_map(&:constants).uniq
303
+ def inspect() = @types.map(&:inspect).join(' | ')
279
304
  end
280
305
 
281
306
  BOOLEAN = UnionType[TRUE, FALSE]
@@ -284,9 +309,9 @@ module KatakataIrb::Types
284
309
  case return_type
285
310
  when RBS::Types::Bases::Self
286
311
  self_type
287
- when RBS::Types::Bases::Void, RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil
312
+ when RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil
288
313
  NIL
289
- when RBS::Types::Bases::Any
314
+ when RBS::Types::Bases::Any, RBS::Types::Bases::Void
290
315
  OBJECT
291
316
  when RBS::Types::Bases::Class
292
317
  self_type.transform do |type|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KatakataIrb
4
- VERSION = "0.1.5"
4
+ VERSION = "0.1.6"
5
5
  end
data/sig/katakata_irb.rbs CHANGED
@@ -1,4 +1,7 @@
1
1
  module KatakataIrb
2
2
  VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
3
+ module Completor
4
+ def self.analyze: (code: String, binding?: Binding) -> Array[Symbol | Object | String | true | false]?
5
+ def self.setup: () -> void
6
+ end
4
7
  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.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - tompng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-14 00:00:00.000000000 Z
11
+ date: 2023-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: irb