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