module ReplTypeCompletor::Types
Constants
- OBJECT_TO_TYPE_SAMPLE_SIZE
Attributes
Public Class Methods
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 108 def self.accessor_method_return_type(type, method_name) return unless method_name.match?(/\A[a-z_][a-z_0-9]*\z/) ivar_name = :"@#{method_name}" instances = type.types.filter_map do |t| case t in SingletonType t.module_or_class in InstanceType t.instances end end.flatten instances = instances.sample(OBJECT_TO_TYPE_SAMPLE_SIZE) if instances.size > OBJECT_TO_TYPE_SAMPLE_SIZE objects = [] instances.each do |instance| if Methods::OBJECT_INSTANCE_VARIABLE_DEFINED_METHOD.bind_call(instance, ivar_name) objects << Methods::OBJECT_INSTANCE_VARIABLE_GET_METHOD.bind_call(instance, ivar_name) end end union_type_from_objects(objects) unless objects.empty? end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 55 def self.class_name_of(klass) while true name = Methods::MODULE_NAME_METHOD.bind_call klass return name if name klass = klass.superclass end end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 187 def self.intersect?(a, b) atypes = a.types.group_by(&:class) btypes = b.types.group_by(&:class) if atypes[SingletonType] && btypes[SingletonType] aa, bb = [atypes, btypes].map {|types| types[SingletonType].map(&:module_or_class) } return true if (aa & bb).any? end aa, bb = [atypes, btypes].map {|types| (types[InstanceType] || []).map(&:klass) } (aa.flat_map(&:ancestors) & bb).any? end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 26 def self.load_rbs_builder @load_started = true loader = RBS::CLI::LibraryOptions.new.loader sig_path = Pathname('sig') loader.add path: sig_path expanded_sig_path = sig_path.expand_path.to_s unless File.exist?('rbs_collection.yaml') # Load rbs signature from gems. This is a fallback when rbs_collection.yaml is not available. Gem.loaded_specs.values.each do |spec| gem_sig_path = File.expand_path("#{spec.gem_dir}/sig") loader.add(library: spec.name, version: spec.version) if Dir.exist?(gem_sig_path) && expanded_sig_path != gem_sig_path end end # Hack to make this thread priority lower, not to block the main thread. thread_pass_counter = 0 tracepoint = TracePoint.new(:call) do Thread.pass if ((thread_pass_counter += 1) % 10).zero? end tracepoint.enable do env = RBS::Environment.from_loader(loader) @rbs_builder = RBS::DefinitionBuilder.new env: env.resolve_type_names end rescue LoadError, StandardError => e @rbs_load_error = e nil end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 89 def self.method_return_type(type, method_name) receivers = type.types.map do |t| case t in SingletonType [t, t.module_or_class, true] in InstanceType [t, t.klass, false] end end types = receivers.flat_map do |receiver_type, klass, singleton| method = rbs_search_method klass, method_name, singleton next [] unless method method.method_types.map do |method| from_rbs_type(method.type.return_type, receiver_type, {}) end end UnionType[*types] end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 18 def self.preload_rbs_builder return if rbs_load_started? @load_started = true Thread.new do load_rbs_builder end end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 65 def self.rbs_absolute_type_name(name) RBS::TypeName.parse(name).absolute! end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 14 def self.rbs_load_started? !!@load_started end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 130 def self.rbs_methods(type, method_name, args_types, kwargs_type, has_block) return [] unless rbs_builder receivers = type.types.map do |t| case t in SingletonType [t, t.module_or_class, true] in InstanceType [t, t.klass, false] end end has_splat = args_types.include?(nil) methods_with_score = receivers.flat_map do |receiver_type, klass, singleton| method = rbs_search_method klass, method_name, singleton next [] unless method method.method_types.filter_map do |method_type| next unless method_type.type.respond_to?(:required_positionals) score = 0 score += 2 if !!method_type.block == has_block reqs = method_type.type.required_positionals opts = method_type.type.optional_positionals rest = method_type.type.rest_positionals trailings = method_type.type.trailing_positionals keyreqs = method_type.type.required_keywords keyopts = method_type.type.optional_keywords keyrest = method_type.type.rest_keywords args = args_types if kwargs_type&.any? && keyreqs.empty? && keyopts.empty? && keyrest.nil? kw_value_type = UnionType[*kwargs_type.values] args += [InstanceType.new(Hash, K: SYMBOL, V: kw_value_type)] end if has_splat score += 1 if args.count(&:itself) <= reqs.size + opts.size + trailings.size elsif reqs.size + trailings.size <= args.size && (rest || args.size <= reqs.size + opts.size + trailings.size) score += 2 centers = args[reqs.size...-trailings.size] given = args.first(reqs.size) + centers.take(opts.size) + args.last(trailings.size) expected = (reqs + opts.take(centers.size) + trailings).map(&:type) if rest given << UnionType[*centers.drop(opts.size)] expected << rest.type end if given.any? score += given.zip(expected).count do |t, e| e = from_rbs_type e, receiver_type intersect?(t, e) || (intersect?(STRING, e) && t.methods.include?(:to_str)) || (intersect?(INTEGER, e) && t.methods.include?(:to_int)) || (intersect?(ARRAY, e) && t.methods.include?(:to_ary)) end.fdiv(given.size) end end [[method_type, given || [], expected || []], score] end end max_score = methods_with_score.map(&:last).max methods_with_score.select { _2 == max_score }.map(&:first) end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 75 def self.rbs_search_method(klass, method_name, singleton) return unless rbs_builder klass.ancestors.each do |ancestor| next unless (name = Methods::MODULE_NAME_METHOD.bind_call(ancestor)) type_name = rbs_absolute_type_name(name) definition = (singleton ? rbs_builder.build_singleton(type_name) : rbs_builder.build_instance(type_name)) rescue nil method = definition.methods[method_name] if definition return method if method end nil end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 199 def self.type_from_object(object) case object when Array InstanceType.new Array, nil, [object] when Hash InstanceType.new Hash, nil, [object] when Module SingletonType.new object else InstanceType.new Methods::OBJECT_CLASS_METHOD.bind_call(object), nil, [object] end end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 212 def self.union_type_from_objects(objects) instances = objects.size <= OBJECT_TO_TYPE_SAMPLE_SIZE ? objects : objects.sample(OBJECT_TO_TYPE_SAMPLE_SIZE) modules, instances = instances.partition { Module === _1 } class_instances = instances.group_by { Methods::OBJECT_CLASS_METHOD.bind_call(_1) } UnionType[*class_instances.map { InstanceType.new _1, nil, _2 }, *modules.uniq.map { SingletonType.new _1 }] end