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 +4 -4
- data/katakata_irb.gemspec +1 -1
- data/lib/katakata_irb/completor.rb +11 -11
- data/lib/katakata_irb/type_analyzer.rb +42 -38
- data/lib/katakata_irb/types.rb +3 -28
- data/lib/katakata_irb/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad93f43d988f169816f4e842bdb70eda5a866574664f6afb5c015ae60b2f2d3b
|
4
|
+
data.tar.gz: 700e29af39db9a73fb71f0f2e76cf4d87bcf801e31fddaef3514416e6d3699e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
-
|
228
|
-
|
229
|
-
call_node = parents
|
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
|
-
|
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.
|
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
|
-
|
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
|
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::
|
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.
|
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
|
846
|
+
case node.type
|
847
|
+
when :required_parameter_node
|
838
848
|
scope[node.name.to_s] = value || KatakataIrb::Types::OBJECT
|
839
|
-
when
|
840
|
-
|
841
|
-
|
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
|
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
|
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
|
-
|
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.
|
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
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
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
|
-
|
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)
|
data/lib/katakata_irb/types.rb
CHANGED
@@ -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 =
|
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 =
|
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
|
-
|
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
|
data/lib/katakata_irb/version.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
54
|
+
version: 0.16.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rbs
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|