repl_type_completor 0.1.10 → 0.1.12
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/lib/repl_type_completor/methods.rb +3 -1
- data/lib/repl_type_completor/result.rb +5 -1
- data/lib/repl_type_completor/scope.rb +8 -25
- data/lib/repl_type_completor/type_analyzer.rb +6 -0
- data/lib/repl_type_completor/types.rb +95 -23
- data/lib/repl_type_completor/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e17428782dfde53e8b592d0fb16957c02ec537bee5122a624e3a99bbfc663e5a
|
|
4
|
+
data.tar.gz: ebebeec739da4ae0e46ac690f3e238cff6759a3cedebccdf9e180e28ee6c51a8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d2d803e3ae97d53a1b3287b564615f9f4f9790d58065ad224d9376ec4fd2407d6df66d10c20a54175ad10c57e2b9efafe10955e01306b21c0d92213b6cc5b9e9
|
|
7
|
+
data.tar.gz: 4ffb182ae4720b9e67d4abb575c09b1e07f7c00a33c1c2601bf66f763eaa4997f8a813980b9367f47ba9731f6ce318a13b277d8c80396c9e7cfe43178896198c
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module ReplTypeCompletor
|
|
4
4
|
module Methods
|
|
5
|
-
|
|
5
|
+
OBJECT_SINGLETON_METHODS_METHOD = Object.instance_method(:singleton_methods)
|
|
6
|
+
OBJECT_PRIVATE_METHODS_METHOD = Object.instance_method(:private_methods)
|
|
6
7
|
OBJECT_INSTANCE_VARIABLES_METHOD = Object.instance_method(:instance_variables)
|
|
8
|
+
OBJECT_INSTANCE_VARIABLE_DEFINED_METHOD = Object.instance_method(:instance_variable_defined?)
|
|
7
9
|
OBJECT_INSTANCE_VARIABLE_GET_METHOD = Object.instance_method(:instance_variable_get)
|
|
8
10
|
OBJECT_CLASS_METHOD = Object.instance_method(:class)
|
|
9
11
|
MODULE_NAME_METHOD = Module.instance_method(:name)
|
|
@@ -72,7 +72,11 @@ module ReplTypeCompletor
|
|
|
72
72
|
else
|
|
73
73
|
[]
|
|
74
74
|
end
|
|
75
|
-
|
|
75
|
+
|
|
76
|
+
candidates.filter_map do
|
|
77
|
+
_1[name.size..] if _1.start_with?(name)
|
|
78
|
+
rescue EncodingError
|
|
79
|
+
end
|
|
76
80
|
rescue Exception => e
|
|
77
81
|
ReplTypeCompletor.handle_exception(e)
|
|
78
82
|
[]
|
|
@@ -284,36 +284,19 @@ module ReplTypeCompletor
|
|
|
284
284
|
end
|
|
285
285
|
|
|
286
286
|
def instance_variables
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
self_instance_variables = singleton_classes.flat_map do |singleton_class|
|
|
291
|
-
if singleton_class.respond_to? :attached_object
|
|
292
|
-
Methods::OBJECT_INSTANCE_VARIABLES_METHOD.bind_call(singleton_class.attached_object).map(&:to_s)
|
|
293
|
-
elsif singleton_class == Methods::OBJECT_SINGLETON_CLASS_METHOD.bind_call(base_self)
|
|
294
|
-
Methods::OBJECT_INSTANCE_VARIABLES_METHOD.bind_call(base_self).map(&:to_s)
|
|
295
|
-
else
|
|
296
|
-
[]
|
|
297
|
-
end
|
|
298
|
-
end
|
|
287
|
+
modules = self_type.types.grep(Types::SingletonType).map(&:module_or_class)
|
|
288
|
+
instances = self_type.types.grep(Types::InstanceType).filter_map(&:instances).flatten(1)
|
|
289
|
+
self_objects = modules + instances
|
|
299
290
|
[
|
|
300
|
-
|
|
301
|
-
self_instance_variables || [],
|
|
291
|
+
self_objects.flat_map { Methods::OBJECT_INSTANCE_VARIABLES_METHOD.bind_call(_1).map(&:to_s) },
|
|
302
292
|
table_instance_variables
|
|
303
|
-
].inject(:|)
|
|
293
|
+
].inject([], :|)
|
|
304
294
|
end
|
|
305
295
|
|
|
306
296
|
def self_instance_variable_get(name)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
singleton_classes.each do |singleton_class|
|
|
311
|
-
if singleton_class.respond_to? :attached_object
|
|
312
|
-
self_objects << singleton_class.attached_object
|
|
313
|
-
elsif singleton_class == base_self.singleton_class
|
|
314
|
-
self_objects << base_self
|
|
315
|
-
end
|
|
316
|
-
end
|
|
297
|
+
modules = self_type.types.grep(Types::SingletonType).map(&:module_or_class)
|
|
298
|
+
instances = self_type.types.grep(Types::InstanceType).filter_map(&:instances).flatten(1)
|
|
299
|
+
self_objects = modules + instances
|
|
317
300
|
types = self_objects.map do |object|
|
|
318
301
|
value = begin
|
|
319
302
|
Methods::OBJECT_INSTANCE_VARIABLE_GET_METHOD.bind_call(object, name)
|
|
@@ -1179,6 +1179,12 @@ module ReplTypeCompletor
|
|
|
1179
1179
|
end
|
|
1180
1180
|
end
|
|
1181
1181
|
end
|
|
1182
|
+
|
|
1183
|
+
if types.empty? && args.empty? && !kwargs && !block
|
|
1184
|
+
t = Types.accessor_method_return_type(receiver, method_name)
|
|
1185
|
+
types << t if t
|
|
1186
|
+
end
|
|
1187
|
+
|
|
1182
1188
|
scope&.terminate if terminates && breaks.empty?
|
|
1183
1189
|
Types::UnionType[*types, *breaks]
|
|
1184
1190
|
end
|
|
@@ -105,6 +105,28 @@ module ReplTypeCompletor
|
|
|
105
105
|
UnionType[*types]
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
+
def self.accessor_method_return_type(type, method_name)
|
|
109
|
+
return unless method_name.match?(/\A[a-z_][a-z_0-9]*\z/)
|
|
110
|
+
|
|
111
|
+
ivar_name = :"@#{method_name}"
|
|
112
|
+
instances = type.types.filter_map do |t|
|
|
113
|
+
case t
|
|
114
|
+
in SingletonType
|
|
115
|
+
t.module_or_class
|
|
116
|
+
in InstanceType
|
|
117
|
+
t.instances
|
|
118
|
+
end
|
|
119
|
+
end.flatten
|
|
120
|
+
instances = instances.sample(OBJECT_TO_TYPE_SAMPLE_SIZE) if instances.size > OBJECT_TO_TYPE_SAMPLE_SIZE
|
|
121
|
+
objects = []
|
|
122
|
+
instances.each do |instance|
|
|
123
|
+
if Methods::OBJECT_INSTANCE_VARIABLE_DEFINED_METHOD.bind_call(instance, ivar_name)
|
|
124
|
+
objects << Methods::OBJECT_INSTANCE_VARIABLE_GET_METHOD.bind_call(instance, ivar_name)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
union_type_from_objects(objects) unless objects.empty?
|
|
128
|
+
end
|
|
129
|
+
|
|
108
130
|
def self.rbs_methods(type, method_name, args_types, kwargs_type, has_block)
|
|
109
131
|
return [] unless rbs_builder
|
|
110
132
|
|
|
@@ -177,21 +199,21 @@ module ReplTypeCompletor
|
|
|
177
199
|
def self.type_from_object(object)
|
|
178
200
|
case object
|
|
179
201
|
when Array
|
|
180
|
-
InstanceType.new Array,
|
|
202
|
+
InstanceType.new Array, nil, [object]
|
|
181
203
|
when Hash
|
|
182
|
-
InstanceType.new Hash,
|
|
204
|
+
InstanceType.new Hash, nil, [object]
|
|
183
205
|
when Module
|
|
184
206
|
SingletonType.new object
|
|
185
207
|
else
|
|
186
|
-
|
|
187
|
-
InstanceType.new klass
|
|
208
|
+
InstanceType.new Methods::OBJECT_CLASS_METHOD.bind_call(object), nil, [object]
|
|
188
209
|
end
|
|
189
210
|
end
|
|
190
211
|
|
|
191
212
|
def self.union_type_from_objects(objects)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
213
|
+
instances = objects.size <= OBJECT_TO_TYPE_SAMPLE_SIZE ? objects : objects.sample(OBJECT_TO_TYPE_SAMPLE_SIZE)
|
|
214
|
+
modules, instances = instances.partition { Module === _1 }
|
|
215
|
+
class_instances = instances.group_by { Methods::OBJECT_CLASS_METHOD.bind_call(_1) }
|
|
216
|
+
UnionType[*class_instances.map { InstanceType.new _1, nil, _2 }, *modules.uniq.map { SingletonType.new _1 }]
|
|
195
217
|
end
|
|
196
218
|
|
|
197
219
|
class SingletonType
|
|
@@ -212,18 +234,59 @@ module ReplTypeCompletor
|
|
|
212
234
|
end
|
|
213
235
|
|
|
214
236
|
class InstanceType
|
|
215
|
-
attr_reader :klass, :
|
|
216
|
-
def initialize(klass, params =
|
|
237
|
+
attr_reader :klass, :raw_params, :instances
|
|
238
|
+
def initialize(klass, params = nil, instances = nil)
|
|
217
239
|
@klass = klass
|
|
218
|
-
@
|
|
240
|
+
@raw_params = params if params && !params.empty?
|
|
241
|
+
@instances = instances if instances && !instances.empty?
|
|
219
242
|
end
|
|
243
|
+
|
|
220
244
|
def transform() = yield(self)
|
|
221
|
-
def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods
|
|
222
|
-
def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods
|
|
245
|
+
def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods | singleton_methods
|
|
246
|
+
def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods | singleton_methods | instances_private_methods
|
|
247
|
+
|
|
248
|
+
def singleton_methods
|
|
249
|
+
return [] unless @instances
|
|
250
|
+
@singleton_methods ||= @instances.map do |instance|
|
|
251
|
+
Methods::OBJECT_SINGLETON_METHODS_METHOD.bind_call(instance)
|
|
252
|
+
end.inject(:|)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def instances_private_methods
|
|
256
|
+
return [] unless @instances
|
|
257
|
+
@private_instances_methods ||= @instances.map do |instance|
|
|
258
|
+
Methods::OBJECT_PRIVATE_METHODS_METHOD.bind_call(instance, false)
|
|
259
|
+
end.inject(:|)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def params
|
|
263
|
+
@params ||= expand_params
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def expand_params
|
|
267
|
+
params = @raw_params || {}
|
|
268
|
+
return params unless @instances
|
|
269
|
+
|
|
270
|
+
if @klass == Array
|
|
271
|
+
type = Types.union_type_from_objects(@instances.flatten(1))
|
|
272
|
+
{ Elem: UnionType[*params[:Elem], *type] }
|
|
273
|
+
elsif @klass == Hash
|
|
274
|
+
key = Types.union_type_from_objects(@instances.map(&:keys).flatten(1))
|
|
275
|
+
value = Types.union_type_from_objects(@instances.map(&:values).flatten(1))
|
|
276
|
+
{
|
|
277
|
+
K: UnionType[*params[:K], key],
|
|
278
|
+
V: UnionType[*params[:V], value]
|
|
279
|
+
}
|
|
280
|
+
else
|
|
281
|
+
params
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
223
285
|
def constants() = []
|
|
224
286
|
def types() = [self]
|
|
225
287
|
def nillable?() = (@klass == NilClass)
|
|
226
288
|
def nonnillable() = self
|
|
289
|
+
|
|
227
290
|
def rbs_methods
|
|
228
291
|
return {} unless Types.rbs_builder
|
|
229
292
|
|
|
@@ -231,14 +294,18 @@ module ReplTypeCompletor
|
|
|
231
294
|
type_name = Types.rbs_absolute_type_name(name)
|
|
232
295
|
Types.rbs_builder.build_instance(type_name).methods rescue {}
|
|
233
296
|
end
|
|
297
|
+
|
|
234
298
|
def inspect
|
|
235
|
-
if params
|
|
299
|
+
if !@params && (@klass == Array || @klass == Hash) && @instances
|
|
300
|
+
"#{inspect_without_params}[unresolved]"
|
|
301
|
+
elsif params.empty?
|
|
236
302
|
inspect_without_params
|
|
237
303
|
else
|
|
238
304
|
params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]"
|
|
239
305
|
"#{inspect_without_params}#{params_string}"
|
|
240
306
|
end
|
|
241
307
|
end
|
|
308
|
+
|
|
242
309
|
def inspect_without_params
|
|
243
310
|
if klass == NilClass
|
|
244
311
|
'nil'
|
|
@@ -247,7 +314,7 @@ module ReplTypeCompletor
|
|
|
247
314
|
elsif klass == FalseClass
|
|
248
315
|
'false'
|
|
249
316
|
else
|
|
250
|
-
klass.
|
|
317
|
+
klass.to_s
|
|
251
318
|
end
|
|
252
319
|
end
|
|
253
320
|
end
|
|
@@ -275,24 +342,26 @@ module ReplTypeCompletor
|
|
|
275
342
|
|
|
276
343
|
def initialize(*types)
|
|
277
344
|
@types = []
|
|
278
|
-
|
|
279
|
-
|
|
345
|
+
singleton_types = []
|
|
346
|
+
instance_types = {}
|
|
280
347
|
collect = -> type do
|
|
281
348
|
case type
|
|
282
349
|
in UnionType
|
|
283
350
|
type.types.each(&collect)
|
|
284
351
|
in InstanceType
|
|
285
|
-
params = (
|
|
286
|
-
type.
|
|
352
|
+
params, instances = (instance_types[type.klass] ||= [{}, []])
|
|
353
|
+
type.instances&.each { instances << _1 }
|
|
354
|
+
type.raw_params&.each do |k, v|
|
|
287
355
|
(params[k] ||= []) << v
|
|
288
356
|
end
|
|
289
357
|
in SingletonType
|
|
290
|
-
|
|
358
|
+
singleton_types << type
|
|
291
359
|
end
|
|
292
360
|
end
|
|
293
361
|
types.each(&collect)
|
|
294
|
-
@types =
|
|
295
|
-
|
|
362
|
+
@types = singleton_types.uniq + instance_types.map do |klass, (params, instances)|
|
|
363
|
+
params = params.transform_values { |v| UnionType[*v] }
|
|
364
|
+
InstanceType.new(klass, params, instances)
|
|
296
365
|
end
|
|
297
366
|
end
|
|
298
367
|
|
|
@@ -322,7 +391,7 @@ module ReplTypeCompletor
|
|
|
322
391
|
def methods() = @types.flat_map(&:methods).uniq
|
|
323
392
|
def all_methods() = @types.flat_map(&:all_methods).uniq
|
|
324
393
|
def constants() = @types.flat_map(&:constants).uniq
|
|
325
|
-
def inspect() = @types.map(&:inspect).join(' | ')
|
|
394
|
+
def inspect() = @types.map(&:inspect).sort.join(' | ')
|
|
326
395
|
end
|
|
327
396
|
|
|
328
397
|
BOOLEAN = UnionType[TRUE, FALSE]
|
|
@@ -362,7 +431,8 @@ module ReplTypeCompletor
|
|
|
362
431
|
OBJECT
|
|
363
432
|
end
|
|
364
433
|
end
|
|
365
|
-
when RBS::Types::Union
|
|
434
|
+
when RBS::Types::Union, RBS::Types::Intersection
|
|
435
|
+
# Intersection is unsupported. fallback to union type
|
|
366
436
|
UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }]
|
|
367
437
|
when RBS::Types::Proc
|
|
368
438
|
PROC
|
|
@@ -411,6 +481,8 @@ module ReplTypeCompletor
|
|
|
411
481
|
params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h
|
|
412
482
|
end
|
|
413
483
|
InstanceType.new klass, params || {}
|
|
484
|
+
else
|
|
485
|
+
OBJECT
|
|
414
486
|
end
|
|
415
487
|
end
|
|
416
488
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: repl_type_completor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tompng
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: prism
|
|
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
85
|
version: '0'
|
|
86
86
|
requirements: []
|
|
87
|
-
rubygems_version: 3.6.
|
|
87
|
+
rubygems_version: 3.6.7
|
|
88
88
|
specification_version: 4
|
|
89
89
|
summary: Type based completion for REPL.
|
|
90
90
|
test_files: []
|