class ReplTypeCompletor::Types::SingletonType
Attributes
Public Class Methods
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 221 def initialize(module_or_class) @module_or_class = module_or_class end
Public Instance Methods
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 226 def all_methods() = methods | @module_or_class.private_methods def constants() = @module_or_class.constants def types() = [self] def nillable?() = false def nonnillable() = self def inspect "#{module_or_class}.itself" end end class InstanceType attr_reader :klass, :raw_params, :instances def initialize(klass, params = nil, instances = nil) @klass = klass @raw_params = params if params && !params.empty? @instances = instances if instances && !instances.empty? end def transform() = yield(self) def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods | singleton_methods def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods | singleton_methods | instances_private_methods def singleton_methods return [] unless @instances @singleton_methods ||= @instances.map do |instance| Methods::OBJECT_SINGLETON_METHODS_METHOD.bind_call(instance) end.inject(:|) end def instances_private_methods return [] unless @instances @private_instances_methods ||= @instances.map do |instance| Methods::OBJECT_PRIVATE_METHODS_METHOD.bind_call(instance, false) end.inject(:|) end def params @params ||= expand_params end def expand_params params = @raw_params || {} return params unless @instances if @klass == Array type = Types.union_type_from_objects(@instances.flatten(1)) { Elem: UnionType[*params[:Elem], *type] } elsif @klass == Hash key = Types.union_type_from_objects(@instances.map(&:keys).flatten(1)) value = Types.union_type_from_objects(@instances.map(&:values).flatten(1)) { K: UnionType[*params[:K], key], V: UnionType[*params[:V], value] } else params end end def constants() = [] def types() = [self] def nillable?() = (@klass == NilClass) def nonnillable() = self def rbs_methods return {} unless Types.rbs_builder name = Types.class_name_of(@klass) type_name = Types.rbs_absolute_type_name(name) Types.rbs_builder.build_instance(type_name).methods rescue {} end def inspect if !@params && (@klass == Array || @klass == Hash) && @instances "#{inspect_without_params}[unresolved]" elsif params.empty? inspect_without_params else params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]" "#{inspect_without_params}#{params_string}" end end def inspect_without_params if klass == NilClass 'nil' elsif klass == TrueClass 'true' elsif klass == FalseClass 'false' else klass.to_s end end end NIL = InstanceType.new NilClass OBJECT = InstanceType.new Object TRUE = InstanceType.new TrueClass FALSE = InstanceType.new FalseClass SYMBOL = InstanceType.new Symbol STRING = InstanceType.new String INTEGER = InstanceType.new Integer RANGE = InstanceType.new Range REGEXP = InstanceType.new Regexp FLOAT = InstanceType.new Float RATIONAL = InstanceType.new Rational COMPLEX = InstanceType.new Complex ARRAY = InstanceType.new Array HASH = InstanceType.new Hash CLASS = InstanceType.new Class MODULE = InstanceType.new Module PROC = InstanceType.new Proc class UnionType attr_reader :types def initialize(*types) @types = [] singleton_types = [] instance_types = {} collect = -> type do case type in UnionType type.types.each(&collect) in InstanceType params, instances = (instance_types[type.klass] ||= [{}, []]) type.instances&.each { instances << _1 } type.raw_params&.each do |k, v| (params[k] ||= []) << v end in SingletonType singleton_types << type end end types.each(&collect) @types = singleton_types.uniq + instance_types.map do |klass, (params, instances)| params = params.transform_values { |v| UnionType[*v] } InstanceType.new(klass, params, instances) end end def transform(&block) UnionType[*types.map(&block)] end def nillable? types.any?(&:nillable?) end def nonnillable UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }] end def self.[](*types) type = new(*types) if type.types.empty? OBJECT elsif type.types.size == 1 type.types.first else type end end def methods() = @types.flat_map(&:methods).uniq def all_methods() = @types.flat_map(&:all_methods).uniq def constants() = @types.flat_map(&:constants).uniq def inspect() = @types.map(&:inspect).sort.join(' | ') end BOOLEAN = UnionType[TRUE, FALSE] def self.array_of(*types) type = types.size >= 2 ? UnionType[*types] : types.first || OBJECT InstanceType.new Array, Elem: type end def self.from_rbs_type(return_type, self_type, extra_vars = {}) case return_type when RBS::Types::Bases::Self self_type when RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil NIL when RBS::Types::Bases::Any, RBS::Types::Bases::Void OBJECT when RBS::Types::Bases::Class self_type.transform do |type| case type in SingletonType InstanceType.new(self_type.module_or_class.is_a?(Class) ? Class : Module) in InstanceType SingletonType.new type.klass end end UnionType[*types] when RBS::Types::Bases::Bool BOOLEAN when RBS::Types::Bases::Instance self_type.transform do |type| if type.is_a?(SingletonType) && type.module_or_class.is_a?(Class) InstanceType.new type.module_or_class elsif type.is_a?(InstanceType) InstanceType.new type.klass else OBJECT end end when RBS::Types::Union, RBS::Types::Intersection # Intersection is unsupported. fallback to union type UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] when RBS::Types::Proc PROC when RBS::Types::Tuple elem = UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] InstanceType.new Array, Elem: elem when RBS::Types::Record InstanceType.new Hash, K: SYMBOL, V: OBJECT when RBS::Types::Literal InstanceType.new return_type.literal.class when RBS::Types::Variable if extra_vars.key? return_type.name extra_vars[return_type.name] elsif self_type.is_a? InstanceType self_type.params[return_type.name] || OBJECT elsif self_type.is_a? UnionType types = self_type.types.filter_map do |t| t.params[return_type.name] if t.is_a? InstanceType end UnionType[*types] else OBJECT end when RBS::Types::Optional UnionType[from_rbs_type(return_type.type, self_type, extra_vars), NIL] when RBS::Types::Alias case return_type.name.name when :int INTEGER when :boolish BOOLEAN when :string STRING else # TODO: ??? OBJECT end when RBS::Types::Interface # unimplemented OBJECT when RBS::Types::ClassInstance klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 } if return_type.args args = return_type.args.map { from_rbs_type _1, self_type, extra_vars } names = rbs_builder.build_singleton(return_type.name).type_params params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h end InstanceType.new klass, params || {} else OBJECT end end def self.method_return_bottom?(method) method.type.return_type.is_a? RBS::Types::Bases::Bottom end def self.match_free_variables(vars, types, values) accumulator = {} types.zip values do |t, v| _match_free_variable(vars, t, v, accumulator) if v end accumulator.transform_values { UnionType[*_1] } end def self._match_free_variable(vars, rbs_type, value, accumulator) case [rbs_type, value] in [RBS::Types::Variable,] (accumulator[rbs_type.name] ||= []) << value if vars.include? rbs_type.name in [RBS::Types::ClassInstance, InstanceType] names = rbs_builder.build_singleton(rbs_type.name).type_params names.zip(rbs_type.args).each do |name, arg| v = value.params[name] _match_free_variable vars, arg, v, accumulator if v end in [RBS::Types::Tuple, InstanceType] if value.klass == Array v = value.params[:Elem] rbs_type.types.each do |t| _match_free_variable vars, t, v, accumulator end in [RBS::Types::Record, InstanceType] if value.klass == Hash # TODO in [RBS::Types::Interface,] definition = rbs_builder.build_interface rbs_type.name convert = {} definition.type_params.zip(rbs_type.args).each do |from, arg| convert[from] = arg.name if arg.is_a? RBS::Types::Variable end return if convert.empty? ac = {} definition.methods.each do |method_name, method| return_type = method_return_type value, method_name method.defs.each do |method_def| interface_return_type = method_def.type.type.return_type _match_free_variable convert, interface_return_type, return_type, ac end end convert.each do |from, to| values = ac[from] (accumulator[to] ||= []
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 227 def constants() = @module_or_class.constants def types() = [self] def nillable?() = false def nonnillable() = self def inspect "#{module_or_class}.itself" end end class InstanceType attr_reader :klass, :raw_params, :instances def initialize(klass, params = nil, instances = nil) @klass = klass @raw_params = params if params && !params.empty? @instances = instances if instances && !instances.empty? end def transform() = yield(self) def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods | singleton_methods def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods | singleton_methods | instances_private_methods def singleton_methods return [] unless @instances @singleton_methods ||= @instances.map do |instance| Methods::OBJECT_SINGLETON_METHODS_METHOD.bind_call(instance) end.inject(:|) end def instances_private_methods return [] unless @instances @private_instances_methods ||= @instances.map do |instance| Methods::OBJECT_PRIVATE_METHODS_METHOD.bind_call(instance, false) end.inject(:|) end def params @params ||= expand_params end def expand_params params = @raw_params || {} return params unless @instances if @klass == Array type = Types.union_type_from_objects(@instances.flatten(1)) { Elem: UnionType[*params[:Elem], *type] } elsif @klass == Hash key = Types.union_type_from_objects(@instances.map(&:keys).flatten(1)) value = Types.union_type_from_objects(@instances.map(&:values).flatten(1)) { K: UnionType[*params[:K], key], V: UnionType[*params[:V], value] } else params end end def constants() = [] def types() = [self] def nillable?() = (@klass == NilClass) def nonnillable() = self def rbs_methods return {} unless Types.rbs_builder name = Types.class_name_of(@klass) type_name = Types.rbs_absolute_type_name(name) Types.rbs_builder.build_instance(type_name).methods rescue {} end def inspect if !@params && (@klass == Array || @klass == Hash) && @instances "#{inspect_without_params}[unresolved]" elsif params.empty? inspect_without_params else params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]" "#{inspect_without_params}#{params_string}" end end def inspect_without_params if klass == NilClass 'nil' elsif klass == TrueClass 'true' elsif klass == FalseClass 'false' else klass.to_s end end end NIL = InstanceType.new NilClass OBJECT = InstanceType.new Object TRUE = InstanceType.new TrueClass FALSE = InstanceType.new FalseClass SYMBOL = InstanceType.new Symbol STRING = InstanceType.new String INTEGER = InstanceType.new Integer RANGE = InstanceType.new Range REGEXP = InstanceType.new Regexp FLOAT = InstanceType.new Float RATIONAL = InstanceType.new Rational COMPLEX = InstanceType.new Complex ARRAY = InstanceType.new Array HASH = InstanceType.new Hash CLASS = InstanceType.new Class MODULE = InstanceType.new Module PROC = InstanceType.new Proc class UnionType attr_reader :types def initialize(*types) @types = [] singleton_types = [] instance_types = {} collect = -> type do case type in UnionType type.types.each(&collect) in InstanceType params, instances = (instance_types[type.klass] ||= [{}, []]) type.instances&.each { instances << _1 } type.raw_params&.each do |k, v| (params[k] ||= []) << v end in SingletonType singleton_types << type end end types.each(&collect) @types = singleton_types.uniq + instance_types.map do |klass, (params, instances)| params = params.transform_values { |v| UnionType[*v] } InstanceType.new(klass, params, instances) end end def transform(&block) UnionType[*types.map(&block)] end def nillable? types.any?(&:nillable?) end def nonnillable UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }] end def self.[](*types) type = new(*types) if type.types.empty? OBJECT elsif type.types.size == 1 type.types.first else type end end def methods() = @types.flat_map(&:methods).uniq def all_methods() = @types.flat_map(&:all_methods).uniq def constants() = @types.flat_map(&:constants).uniq def inspect() = @types.map(&:inspect).sort.join(' | ') end BOOLEAN = UnionType[TRUE, FALSE] def self.array_of(*types) type = types.size >= 2 ? UnionType[*types] : types.first || OBJECT InstanceType.new Array, Elem: type end def self.from_rbs_type(return_type, self_type, extra_vars = {}) case return_type when RBS::Types::Bases::Self self_type when RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil NIL when RBS::Types::Bases::Any, RBS::Types::Bases::Void OBJECT when RBS::Types::Bases::Class self_type.transform do |type| case type in SingletonType InstanceType.new(self_type.module_or_class.is_a?(Class) ? Class : Module) in InstanceType SingletonType.new type.klass end end UnionType[*types] when RBS::Types::Bases::Bool BOOLEAN when RBS::Types::Bases::Instance self_type.transform do |type| if type.is_a?(SingletonType) && type.module_or_class.is_a?(Class) InstanceType.new type.module_or_class elsif type.is_a?(InstanceType) InstanceType.new type.klass else OBJECT end end when RBS::Types::Union, RBS::Types::Intersection # Intersection is unsupported. fallback to union type UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] when RBS::Types::Proc PROC when RBS::Types::Tuple elem = UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] InstanceType.new Array, Elem: elem when RBS::Types::Record InstanceType.new Hash, K: SYMBOL, V: OBJECT when RBS::Types::Literal InstanceType.new return_type.literal.class when RBS::Types::Variable if extra_vars.key? return_type.name extra_vars[return_type.name] elsif self_type.is_a? InstanceType self_type.params[return_type.name] || OBJECT elsif self_type.is_a? UnionType types = self_type.types.filter_map do |t| t.params[return_type.name] if t.is_a? InstanceType end UnionType[*types] else OBJECT end when RBS::Types::Optional UnionType[from_rbs_type(return_type.type, self_type, extra_vars), NIL] when RBS::Types::Alias case return_type.name.name when :int INTEGER when :boolish BOOLEAN when :string STRING else # TODO: ??? OBJECT end when RBS::Types::Interface # unimplemented OBJECT when RBS::Types::ClassInstance klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 } if return_type.args args = return_type.args.map { from_rbs_type _1, self_type, extra_vars } names = rbs_builder.build_singleton(return_type.name).type_params params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h end InstanceType.new klass, params || {} else OBJECT end end def self.method_return_bottom?(method) method.type.return_type.is_a? RBS::Types::Bases::Bottom end def self.match_free_variables(vars, types, values) accumulator = {} types.zip values do |t, v| _match_free_variable(vars, t, v, accumulator) if v end accumulator.transform_values { UnionType[*_1] } end def self._match_free_variable(vars, rbs_type, value, accumulator) case [rbs_type, value] in [RBS::Types::Variable,] (accumulator[rbs_type.name] ||= []) << value if vars.include? rbs_type.name in [RBS::Types::ClassInstance, InstanceType] names = rbs_builder.build_singleton(rbs_type.name).type_params names.zip(rbs_type.args).each do |name, arg| v = value.params[name] _match_free_variable vars, arg, v, accumulator if v end in [RBS::Types::Tuple, InstanceType] if value.klass == Array v = value.params[:Elem] rbs_type.types.each do |t| _match_free_variable vars, t, v, accumulator end in [RBS::Types::Record, InstanceType] if value.klass == Hash # TODO in [RBS::Types::Interface,] definition = rbs_builder.build_interface rbs_type.name convert = {} definition.type_params.zip(rbs_type.args).each do |from, arg| convert[from] = arg.name if arg.is_a? RBS::Types::Variable end return if convert.empty? ac = {} definition.methods.each do |method_name, method| return_type = method_return_type value, method_name method.defs.each do |method_def| interface_return_type = method_def.type.type.return_type _match_free_variable convert, interface_return_type, return_type, ac end end convert.each do |from, to| values = ac[from] (accumulator[to] ||= []).
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 231 def inspect "#{module_or_class}.itself" end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 225 def methods() = @module_or_class.methods def all_methods() = methods | @module_or_class.private_methods def constants() = @module_or_class.constants def types() = [self] def nillable?() = false def nonnillable() = self def inspect "#{module_or_class}.itself" end end class InstanceType attr_reader :klass, :raw_params, :instances def initialize(klass, params = nil, instances = nil) @klass = klass @raw_params = params if params && !params.empty? @instances = instances if instances && !instances.empty? end def transform() = yield(self) def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods | singleton_methods def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods | singleton_methods | instances_private_methods def singleton_methods return [] unless @instances @singleton_methods ||= @instances.map do |instance| Methods::OBJECT_SINGLETON_METHODS_METHOD.bind_call(instance) end.inject(:|) end def instances_private_methods return [] unless @instances @private_instances_methods ||= @instances.map do |instance| Methods::OBJECT_PRIVATE_METHODS_METHOD.bind_call(instance, false) end.inject(:|) end def params @params ||= expand_params end def expand_params params = @raw_params || {} return params unless @instances if @klass == Array type = Types.union_type_from_objects(@instances.flatten(1)) { Elem: UnionType[*params[:Elem], *type] } elsif @klass == Hash key = Types.union_type_from_objects(@instances.map(&:keys).flatten(1)) value = Types.union_type_from_objects(@instances.map(&:values).flatten(1)) { K: UnionType[*params[:K], key], V: UnionType[*params[:V], value] } else params end end def constants() = [] def types() = [self] def nillable?() = (@klass == NilClass) def nonnillable() = self def rbs_methods return {} unless Types.rbs_builder name = Types.class_name_of(@klass) type_name = Types.rbs_absolute_type_name(name) Types.rbs_builder.build_instance(type_name).methods rescue {} end def inspect if !@params && (@klass == Array || @klass == Hash) && @instances "#{inspect_without_params}[unresolved]" elsif params.empty? inspect_without_params else params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]" "#{inspect_without_params}#{params_string}" end end def inspect_without_params if klass == NilClass 'nil' elsif klass == TrueClass 'true' elsif klass == FalseClass 'false' else klass.to_s end end end NIL = InstanceType.new NilClass OBJECT = InstanceType.new Object TRUE = InstanceType.new TrueClass FALSE = InstanceType.new FalseClass SYMBOL = InstanceType.new Symbol STRING = InstanceType.new String INTEGER = InstanceType.new Integer RANGE = InstanceType.new Range REGEXP = InstanceType.new Regexp FLOAT = InstanceType.new Float RATIONAL = InstanceType.new Rational COMPLEX = InstanceType.new Complex ARRAY = InstanceType.new Array HASH = InstanceType.new Hash CLASS = InstanceType.new Class MODULE = InstanceType.new Module PROC = InstanceType.new Proc class UnionType attr_reader :types def initialize(*types) @types = [] singleton_types = [] instance_types = {} collect = -> type do case type in UnionType type.types.each(&collect) in InstanceType params, instances = (instance_types[type.klass] ||= [{}, []]) type.instances&.each { instances << _1 } type.raw_params&.each do |k, v| (params[k] ||= []) << v end in SingletonType singleton_types << type end end types.each(&collect) @types = singleton_types.uniq + instance_types.map do |klass, (params, instances)| params = params.transform_values { |v| UnionType[*v] } InstanceType.new(klass, params, instances) end end def transform(&block) UnionType[*types.map(&block)] end def nillable? types.any?(&:nillable?) end def nonnillable UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }] end def self.[](*types) type = new(*types) if type.types.empty? OBJECT elsif type.types.size == 1 type.types.first else type end end def methods() = @types.flat_map(&:methods).uniq def all_methods() = @types.flat_map(&:all_methods).uniq def constants() = @types.flat_map(&:constants).uniq def inspect() = @types.map(&:inspect).sort.join(' | ') end BOOLEAN = UnionType[TRUE, FALSE] def self.array_of(*types) type = types.size >= 2 ? UnionType[*types] : types.first || OBJECT InstanceType.new Array, Elem: type end def self.from_rbs_type(return_type, self_type, extra_vars = {}) case return_type when RBS::Types::Bases::Self self_type when RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil NIL when RBS::Types::Bases::Any, RBS::Types::Bases::Void OBJECT when RBS::Types::Bases::Class self_type.transform do |type| case type in SingletonType InstanceType.new(self_type.module_or_class.is_a?(Class) ? Class : Module) in InstanceType SingletonType.new type.klass end end UnionType[*types] when RBS::Types::Bases::Bool BOOLEAN when RBS::Types::Bases::Instance self_type.transform do |type| if type.is_a?(SingletonType) && type.module_or_class.is_a?(Class) InstanceType.new type.module_or_class elsif type.is_a?(InstanceType) InstanceType.new type.klass else OBJECT end end when RBS::Types::Union, RBS::Types::Intersection # Intersection is unsupported. fallback to union type UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] when RBS::Types::Proc PROC when RBS::Types::Tuple elem = UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] InstanceType.new Array, Elem: elem when RBS::Types::Record InstanceType.new Hash, K: SYMBOL, V: OBJECT when RBS::Types::Literal InstanceType.new return_type.literal.class when RBS::Types::Variable if extra_vars.key? return_type.name extra_vars[return_type.name] elsif self_type.is_a? InstanceType self_type.params[return_type.name] || OBJECT elsif self_type.is_a? UnionType types = self_type.types.filter_map do |t| t.params[return_type.name] if t.is_a? InstanceType end UnionType[*types] else OBJECT end when RBS::Types::Optional UnionType[from_rbs_type(return_type.type, self_type, extra_vars), NIL] when RBS::Types::Alias case return_type.name.name when :int INTEGER when :boolish BOOLEAN when :string STRING else # TODO: ??? OBJECT end when RBS::Types::Interface # unimplemented OBJECT when RBS::Types::ClassInstance klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 } if return_type.args args = return_type.args.map { from_rbs_type _1, self_type, extra_vars } names = rbs_builder.build_singleton(return_type.name).type_params params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h end InstanceType.new klass, params || {} else OBJECT end end def self.method_return_bottom?(method) method.type.return_type.is_a? RBS::Types::Bases::Bottom end def self.match_free_variables(vars, types, values) accumulator = {} types.zip values do |t, v| _match_free_variable(vars, t, v, accumulator) if v end accumulator.transform_values { UnionType[*_1] } end def self._match_free_variable(vars, rbs_type, value, accumulator) case [rbs_type, value] in [RBS::Types::Variable,] (accumulator[rbs_type.name] ||= []) << value if vars.include? rbs_type.name in [RBS::Types::ClassInstance, InstanceType] names = rbs_builder.build_singleton(rbs_type.name).type_params names.zip(rbs_type.args).each do |name, arg| v = value.params[name] _match_free_variable vars, arg, v, accumulator if v end in [RBS::Types::Tuple, InstanceType] if value.klass == Array v = value.params[:Elem] rbs_type.types.each do |t| _match_free_variable vars, t, v, accumulator end in [RBS::Types::Record, InstanceType] if value.klass == Hash # TODO in [RBS::Types::Interface,] definition = rbs_builder.build_interface rbs_type.name convert = {} definition.type_params.zip(rbs_type.args).each do |from, arg| convert[from] = arg.name if arg.is_a? RBS::Types::Variable end return if convert.empty? ac = {} definition.methods.each do |method_name, method| return_type = method_return_type value, method_name method.defs.each do |method_def| interface_return_type = method_def.type.type.return_type _match_free_variable convert, interface_return_type, return_type, ac end end convert.each do |from, to| values = ac[from] (accumulator[to] ||=
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 229 def nillable?() = false def nonnillable() = self def inspect "#{module_or_class}.itself" end end class InstanceType attr_reader :klass, :raw_params, :instances def initialize(klass, params = nil, instances = nil) @klass = klass @raw_params = params if params && !params.empty? @instances = instances if instances && !instances.empty? end def transform() = yield(self) def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods | singleton_methods def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods | singleton_methods | instances_private_methods def singleton_methods return [] unless @instances @singleton_methods ||= @instances.map do |instance| Methods::OBJECT_SINGLETON_METHODS_METHOD.bind_call(instance) end.inject(:|) end def instances_private_methods return [] unless @instances @private_instances_methods ||= @instances.map do |instance| Methods::OBJECT_PRIVATE_METHODS_METHOD.bind_call(instance, false) end.inject(:|) end def params @params ||= expand_params end def expand_params params = @raw_params || {} return params unless @instances if @klass == Array type = Types.union_type_from_objects(@instances.flatten(1)) { Elem: UnionType[*params[:Elem], *type] } elsif @klass == Hash key = Types.union_type_from_objects(@instances.map(&:keys).flatten(1)) value = Types.union_type_from_objects(@instances.map(&:values).flatten(1)) { K: UnionType[*params[:K], key], V: UnionType[*params[:V], value] } else params end end def constants() = [] def types() = [self] def nillable?() = (@klass == NilClass) def nonnillable() = self def rbs_methods return {} unless Types.rbs_builder name = Types.class_name_of(@klass) type_name = Types.rbs_absolute_type_name(name) Types.rbs_builder.build_instance(type_name).methods rescue {} end def inspect if !@params && (@klass == Array || @klass == Hash) && @instances "#{inspect_without_params}[unresolved]" elsif params.empty? inspect_without_params else params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]" "#{inspect_without_params}#{params_string}" end end def inspect_without_params if klass == NilClass 'nil' elsif klass == TrueClass 'true' elsif klass == FalseClass 'false' else klass.to_s end end end NIL = InstanceType.new NilClass OBJECT = InstanceType.new Object TRUE = InstanceType.new TrueClass FALSE = InstanceType.new FalseClass SYMBOL = InstanceType.new Symbol STRING = InstanceType.new String INTEGER = InstanceType.new Integer RANGE = InstanceType.new Range REGEXP = InstanceType.new Regexp FLOAT = InstanceType.new Float RATIONAL = InstanceType.new Rational COMPLEX = InstanceType.new Complex ARRAY = InstanceType.new Array HASH = InstanceType.new Hash CLASS = InstanceType.new Class MODULE = InstanceType.new Module PROC = InstanceType.new Proc class UnionType attr_reader :types def initialize(*types) @types = [] singleton_types = [] instance_types = {} collect = -> type do case type in UnionType type.types.each(&collect) in InstanceType params, instances = (instance_types[type.klass] ||= [{}, []]) type.instances&.each { instances << _1 } type.raw_params&.each do |k, v| (params[k] ||= []) << v end in SingletonType singleton_types << type end end types.each(&collect) @types = singleton_types.uniq + instance_types.map do |klass, (params, instances)| params = params.transform_values { |v| UnionType[*v] } InstanceType.new(klass, params, instances) end end def transform(&block) UnionType[*types.map(&block)] end def nillable? types.any?(&:nillable?) end def nonnillable UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }] end def self.[](*types) type = new(*types) if type.types.empty? OBJECT elsif type.types.size == 1 type.types.first else type end end def methods() = @types.flat_map(&:methods).uniq def all_methods() = @types.flat_map(&:all_methods).uniq def constants() = @types.flat_map(&:constants).uniq def inspect() = @types.map(&:inspect).sort.join(' | ') end BOOLEAN = UnionType[TRUE, FALSE] def self.array_of(*types) type = types.size >= 2 ? UnionType[*types] : types.first || OBJECT InstanceType.new Array, Elem: type end def self.from_rbs_type(return_type, self_type, extra_vars = {}) case return_type when RBS::Types::Bases::Self self_type when RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil NIL when RBS::Types::Bases::Any, RBS::Types::Bases::Void OBJECT when RBS::Types::Bases::Class self_type.transform do |type| case type in SingletonType InstanceType.new(self_type.module_or_class.is_a?(Class) ? Class : Module) in InstanceType SingletonType.new type.klass end end UnionType[*types] when RBS::Types::Bases::Bool BOOLEAN when RBS::Types::Bases::Instance self_type.transform do |type| if type.is_a?(SingletonType) && type.module_or_class.is_a?(Class) InstanceType.new type.module_or_class elsif type.is_a?(InstanceType) InstanceType.new type.klass else OBJECT end end when RBS::Types::Union, RBS::Types::Intersection # Intersection is unsupported. fallback to union type UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] when RBS::Types::Proc PROC when RBS::Types::Tuple elem = UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] InstanceType.new Array, Elem: elem when RBS::Types::Record InstanceType.new Hash, K: SYMBOL, V: OBJECT when RBS::Types::Literal InstanceType.new return_type.literal.class when RBS::Types::Variable if extra_vars.key? return_type.name extra_vars[return_type.name] elsif self_type.is_a? InstanceType self_type.params[return_type.name] || OBJECT elsif self_type.is_a? UnionType types = self_type.types.filter_map do |t| t.params[return_type.name] if t.is_a? InstanceType end UnionType[*types] else OBJECT end when RBS::Types::Optional UnionType[from_rbs_type(return_type.type, self_type, extra_vars), NIL] when RBS::Types::Alias case return_type.name.name when :int INTEGER when :boolish BOOLEAN when :string STRING else # TODO: ??? OBJECT end when RBS::Types::Interface # unimplemented OBJECT when RBS::Types::ClassInstance klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 } if return_type.args args = return_type.args.map { from_rbs_type _1, self_type, extra_vars } names = rbs_builder.build_singleton(return_type.name).type_params params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h end InstanceType.new klass, params || {} else OBJECT end end def self.method_return_bottom?(method) method.type.return_type.is_a? RBS::Types::Bases::Bottom end def self.match_free_variables(vars, types, values) accumulator = {} types.zip values do |t, v| _match_free_variable(vars, t, v, accumulator) if v end accumulator.transform_values { UnionType[*_1] } end def self._match_free_variable(vars, rbs_type, value, accumulator) case [rbs_type, value] in [RBS::Types::Variable,] (accumulator[rbs_type.name] ||= []) << value if vars.include? rbs_type.name in [RBS::Types::ClassInstance, InstanceType] names = rbs_builder.build_singleton(rbs_type.name).type_params names.zip(rbs_type.args).each do |name, arg| v = value.params[name] _match_free_variable vars, arg, v, accumulator if v end in [RBS::Types::Tuple, InstanceType] if value.klass == Array v = value.params[:Elem] rbs_type.types.each do |t| _match_free_variable vars, t, v, accumulator end in [RBS::Types::Record, InstanceType] if value.klass == Hash # TODO in [RBS::Types::Interface,] definition = rbs_builder.build_interface rbs_type.name convert = {} definition.type_params.zip(rbs_type.args).each do |from, arg| convert[from] = arg.name if arg.is_a? RBS::Types::Variable end return if convert.empty? ac = {} definition.methods.each do |method_name, method| return_type = method_return_type value, method_name method.defs.each do |method_def| interface_return_type = method_def.type.type.return_type _match_free_variable convert, interface_return_type, return_type, ac end end convert.each do |from, to| values = ac[from] (accumulator[to] ||= []).concat values
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 230 def nonnillable() = self def inspect "#{module_or_class}.itself" end end
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 224 def transform() = yield(self) def methods() = @module_or_class.methods def all_methods() = methods | @module_or_class.private_methods def constants() = @module_or_class.constants def types() = [self] def nillable?() = false def nonnillable() = self def inspect "#{module_or_class}.itself" end end class InstanceType attr_reader :klass, :raw_params, :instances def initialize(klass, params = nil, instances = nil) @klass = klass @raw_params = params if params && !params.empty? @instances = instances if instances && !instances.empty? end def transform() = yield(self) def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods | singleton_methods def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods | singleton_methods | instances_private_methods def singleton_methods return [] unless @instances @singleton_methods ||= @instances.map do |instance| Methods::OBJECT_SINGLETON_METHODS_METHOD.bind_call(instance) end.inject(:|) end def instances_private_methods return [] unless @instances @private_instances_methods ||= @instances.map do |instance| Methods::OBJECT_PRIVATE_METHODS_METHOD.bind_call(instance, false) end.inject(:|) end def params @params ||= expand_params end def expand_params params = @raw_params || {} return params unless @instances if @klass == Array type = Types.union_type_from_objects(@instances.flatten(1)) { Elem: UnionType[*params[:Elem], *type] } elsif @klass == Hash key = Types.union_type_from_objects(@instances.map(&:keys).flatten(1)) value = Types.union_type_from_objects(@instances.map(&:values).flatten(1)) { K: UnionType[*params[:K], key], V: UnionType[*params[:V], value] } else params end end def constants() = [] def types() = [self] def nillable?() = (@klass == NilClass) def nonnillable() = self def rbs_methods return {} unless Types.rbs_builder name = Types.class_name_of(@klass) type_name = Types.rbs_absolute_type_name(name) Types.rbs_builder.build_instance(type_name).methods rescue {} end def inspect if !@params && (@klass == Array || @klass == Hash) && @instances "#{inspect_without_params}[unresolved]" elsif params.empty? inspect_without_params else params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]" "#{inspect_without_params}#{params_string}" end end def inspect_without_params if klass == NilClass 'nil' elsif klass == TrueClass 'true' elsif klass == FalseClass 'false' else klass.to_s end end end NIL = InstanceType.new NilClass OBJECT = InstanceType.new Object TRUE = InstanceType.new TrueClass FALSE = InstanceType.new FalseClass SYMBOL = InstanceType.new Symbol STRING = InstanceType.new String INTEGER = InstanceType.new Integer RANGE = InstanceType.new Range REGEXP = InstanceType.new Regexp FLOAT = InstanceType.new Float RATIONAL = InstanceType.new Rational COMPLEX = InstanceType.new Complex ARRAY = InstanceType.new Array HASH = InstanceType.new Hash CLASS = InstanceType.new Class MODULE = InstanceType.new Module PROC = InstanceType.new Proc class UnionType attr_reader :types def initialize(*types) @types = [] singleton_types = [] instance_types = {} collect = -> type do case type in UnionType type.types.each(&collect) in InstanceType params, instances = (instance_types[type.klass] ||= [{}, []]) type.instances&.each { instances << _1 } type.raw_params&.each do |k, v| (params[k] ||= []) << v end in SingletonType singleton_types << type end end types.each(&collect) @types = singleton_types.uniq + instance_types.map do |klass, (params, instances)| params = params.transform_values { |v| UnionType[*v] } InstanceType.new(klass, params, instances) end end def transform(&block) UnionType[*types.map(&block)] end def nillable? types.any?(&:nillable?) end def nonnillable UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }] end def self.[](*types) type = new(*types) if type.types.empty? OBJECT elsif type.types.size == 1 type.types.first else type end end def methods() = @types.flat_map(&:methods).uniq def all_methods() = @types.flat_map(&:all_methods).uniq def constants() = @types.flat_map(&:constants).uniq def inspect() = @types.map(&:inspect).sort.join(' | ') end BOOLEAN = UnionType[TRUE, FALSE] def self.array_of(*types) type = types.size >= 2 ? UnionType[*types] : types.first || OBJECT InstanceType.new Array, Elem: type end def self.from_rbs_type(return_type, self_type, extra_vars = {}) case return_type when RBS::Types::Bases::Self self_type when RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil NIL when RBS::Types::Bases::Any, RBS::Types::Bases::Void OBJECT when RBS::Types::Bases::Class self_type.transform do |type| case type in SingletonType InstanceType.new(self_type.module_or_class.is_a?(Class) ? Class : Module) in InstanceType SingletonType.new type.klass end end UnionType[*types] when RBS::Types::Bases::Bool BOOLEAN when RBS::Types::Bases::Instance self_type.transform do |type| if type.is_a?(SingletonType) && type.module_or_class.is_a?(Class) InstanceType.new type.module_or_class elsif type.is_a?(InstanceType) InstanceType.new type.klass else OBJECT end end when RBS::Types::Union, RBS::Types::Intersection # Intersection is unsupported. fallback to union type UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] when RBS::Types::Proc PROC when RBS::Types::Tuple elem = UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] InstanceType.new Array, Elem: elem when RBS::Types::Record InstanceType.new Hash, K: SYMBOL, V: OBJECT when RBS::Types::Literal InstanceType.new return_type.literal.class when RBS::Types::Variable if extra_vars.key? return_type.name extra_vars[return_type.name] elsif self_type.is_a? InstanceType self_type.params[return_type.name] || OBJECT elsif self_type.is_a? UnionType types = self_type.types.filter_map do |t| t.params[return_type.name] if t.is_a? InstanceType end UnionType[*types] else OBJECT end when RBS::Types::Optional UnionType[from_rbs_type(return_type.type, self_type, extra_vars), NIL] when RBS::Types::Alias case return_type.name.name when :int INTEGER when :boolish BOOLEAN when :string STRING else # TODO: ??? OBJECT end when RBS::Types::Interface # unimplemented OBJECT when RBS::Types::ClassInstance klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 } if return_type.args args = return_type.args.map { from_rbs_type _1, self_type, extra_vars } names = rbs_builder.build_singleton(return_type.name).type_params params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h end InstanceType.new klass, params || {} else OBJECT end end def self.method_return_bottom?(method) method.type.return_type.is_a? RBS::Types::Bases::Bottom end def self.match_free_variables(vars, types, values) accumulator = {} types.zip values do |t, v| _match_free_variable(vars, t, v, accumulator) if v end accumulator.transform_values { UnionType[*_1] } end def self._match_free_variable(vars, rbs_type, value, accumulator) case [rbs_type, value] in [RBS::Types::Variable,] (accumulator[rbs_type.name] ||= []) << value if vars.include? rbs_type.name in [RBS::Types::ClassInstance, InstanceType] names = rbs_builder.build_singleton(rbs_type.name).type_params names.zip(rbs_type.args).each do |name, arg| v = value.params[name] _match_free_variable vars, arg, v, accumulator if v end in [RBS::Types::Tuple, InstanceType] if value.klass == Array v = value.params[:Elem] rbs_type.types.each do |t| _match_free_variable vars, t, v, accumulator end in [RBS::Types::Record, InstanceType] if value.klass == Hash # TODO in [RBS::Types::Interface,] definition = rbs_builder.build_interface rbs_type.name convert = {} definition.type_params.zip(rbs_type.args).each do |from, arg| convert[from] = arg.name if arg.is_a? RBS::Types::Variable end return if convert.empty? ac = {} definition.methods.each do |method_name, method| return_type = method_return_type value, method_name method.defs.each do |method_def| interface_return_type = method_def.type.type.return_type _match_free_variable convert, interface_return_type, return_type, ac end end convert.each do |from, to| values = ac[from] (accumulator[to]
Source
# File bundled-src/repl_type_completor-0.1.12/lib/repl_type_completor/types.rb, line 228 def types() = [self] def nillable?() = false def nonnillable() = self def inspect "#{module_or_class}.itself" end end class InstanceType attr_reader :klass, :raw_params, :instances def initialize(klass, params = nil, instances = nil) @klass = klass @raw_params = params if params && !params.empty? @instances = instances if instances && !instances.empty? end def transform() = yield(self) def methods() = rbs_methods.select { _2.public? }.keys | @klass.instance_methods | singleton_methods def all_methods() = rbs_methods.keys | @klass.instance_methods | @klass.private_instance_methods | singleton_methods | instances_private_methods def singleton_methods return [] unless @instances @singleton_methods ||= @instances.map do |instance| Methods::OBJECT_SINGLETON_METHODS_METHOD.bind_call(instance) end.inject(:|) end def instances_private_methods return [] unless @instances @private_instances_methods ||= @instances.map do |instance| Methods::OBJECT_PRIVATE_METHODS_METHOD.bind_call(instance, false) end.inject(:|) end def params @params ||= expand_params end def expand_params params = @raw_params || {} return params unless @instances if @klass == Array type = Types.union_type_from_objects(@instances.flatten(1)) { Elem: UnionType[*params[:Elem], *type] } elsif @klass == Hash key = Types.union_type_from_objects(@instances.map(&:keys).flatten(1)) value = Types.union_type_from_objects(@instances.map(&:values).flatten(1)) { K: UnionType[*params[:K], key], V: UnionType[*params[:V], value] } else params end end def constants() = [] def types() = [self] def nillable?() = (@klass == NilClass) def nonnillable() = self def rbs_methods return {} unless Types.rbs_builder name = Types.class_name_of(@klass) type_name = Types.rbs_absolute_type_name(name) Types.rbs_builder.build_instance(type_name).methods rescue {} end def inspect if !@params && (@klass == Array || @klass == Hash) && @instances "#{inspect_without_params}[unresolved]" elsif params.empty? inspect_without_params else params_string = "[#{params.map { "#{_1}: #{_2.inspect}" }.join(', ')}]" "#{inspect_without_params}#{params_string}" end end def inspect_without_params if klass == NilClass 'nil' elsif klass == TrueClass 'true' elsif klass == FalseClass 'false' else klass.to_s end end end NIL = InstanceType.new NilClass OBJECT = InstanceType.new Object TRUE = InstanceType.new TrueClass FALSE = InstanceType.new FalseClass SYMBOL = InstanceType.new Symbol STRING = InstanceType.new String INTEGER = InstanceType.new Integer RANGE = InstanceType.new Range REGEXP = InstanceType.new Regexp FLOAT = InstanceType.new Float RATIONAL = InstanceType.new Rational COMPLEX = InstanceType.new Complex ARRAY = InstanceType.new Array HASH = InstanceType.new Hash CLASS = InstanceType.new Class MODULE = InstanceType.new Module PROC = InstanceType.new Proc class UnionType attr_reader :types def initialize(*types) @types = [] singleton_types = [] instance_types = {} collect = -> type do case type in UnionType type.types.each(&collect) in InstanceType params, instances = (instance_types[type.klass] ||= [{}, []]) type.instances&.each { instances << _1 } type.raw_params&.each do |k, v| (params[k] ||= []) << v end in SingletonType singleton_types << type end end types.each(&collect) @types = singleton_types.uniq + instance_types.map do |klass, (params, instances)| params = params.transform_values { |v| UnionType[*v] } InstanceType.new(klass, params, instances) end end def transform(&block) UnionType[*types.map(&block)] end def nillable? types.any?(&:nillable?) end def nonnillable UnionType[*types.reject { _1.is_a?(InstanceType) && _1.klass == NilClass }] end def self.[](*types) type = new(*types) if type.types.empty? OBJECT elsif type.types.size == 1 type.types.first else type end end def methods() = @types.flat_map(&:methods).uniq def all_methods() = @types.flat_map(&:all_methods).uniq def constants() = @types.flat_map(&:constants).uniq def inspect() = @types.map(&:inspect).sort.join(' | ') end BOOLEAN = UnionType[TRUE, FALSE] def self.array_of(*types) type = types.size >= 2 ? UnionType[*types] : types.first || OBJECT InstanceType.new Array, Elem: type end def self.from_rbs_type(return_type, self_type, extra_vars = {}) case return_type when RBS::Types::Bases::Self self_type when RBS::Types::Bases::Bottom, RBS::Types::Bases::Nil NIL when RBS::Types::Bases::Any, RBS::Types::Bases::Void OBJECT when RBS::Types::Bases::Class self_type.transform do |type| case type in SingletonType InstanceType.new(self_type.module_or_class.is_a?(Class) ? Class : Module) in InstanceType SingletonType.new type.klass end end UnionType[*types] when RBS::Types::Bases::Bool BOOLEAN when RBS::Types::Bases::Instance self_type.transform do |type| if type.is_a?(SingletonType) && type.module_or_class.is_a?(Class) InstanceType.new type.module_or_class elsif type.is_a?(InstanceType) InstanceType.new type.klass else OBJECT end end when RBS::Types::Union, RBS::Types::Intersection # Intersection is unsupported. fallback to union type UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] when RBS::Types::Proc PROC when RBS::Types::Tuple elem = UnionType[*return_type.types.map { from_rbs_type _1, self_type, extra_vars }] InstanceType.new Array, Elem: elem when RBS::Types::Record InstanceType.new Hash, K: SYMBOL, V: OBJECT when RBS::Types::Literal InstanceType.new return_type.literal.class when RBS::Types::Variable if extra_vars.key? return_type.name extra_vars[return_type.name] elsif self_type.is_a? InstanceType self_type.params[return_type.name] || OBJECT elsif self_type.is_a? UnionType types = self_type.types.filter_map do |t| t.params[return_type.name] if t.is_a? InstanceType end UnionType[*types] else OBJECT end when RBS::Types::Optional UnionType[from_rbs_type(return_type.type, self_type, extra_vars), NIL] when RBS::Types::Alias case return_type.name.name when :int INTEGER when :boolish BOOLEAN when :string STRING else # TODO: ??? OBJECT end when RBS::Types::Interface # unimplemented OBJECT when RBS::Types::ClassInstance klass = return_type.name.to_namespace.path.reduce(Object) { _1.const_get _2 } if return_type.args args = return_type.args.map { from_rbs_type _1, self_type, extra_vars } names = rbs_builder.build_singleton(return_type.name).type_params params = names.map.with_index { [_1, args[_2] || OBJECT] }.to_h end InstanceType.new klass, params || {} else OBJECT end end def self.method_return_bottom?(method) method.type.return_type.is_a? RBS::Types::Bases::Bottom end def self.match_free_variables(vars, types, values) accumulator = {} types.zip values do |t, v| _match_free_variable(vars, t, v, accumulator) if v end accumulator.transform_values { UnionType[*_1] } end def self._match_free_variable(vars, rbs_type, value, accumulator) case [rbs_type, value] in [RBS::Types::Variable,] (accumulator[rbs_type.name] ||= []) << value if vars.include? rbs_type.name in [RBS::Types::ClassInstance, InstanceType] names = rbs_builder.build_singleton(rbs_type.name).type_params names.zip(rbs_type.args).each do |name, arg| v = value.params[name] _match_free_variable vars, arg, v, accumulator if v end in [RBS::Types::Tuple, InstanceType] if value.klass == Array v = value.params[:Elem] rbs_type.types.each do |t| _match_free_variable vars, t, v, accumulator end in [RBS::Types::Record, InstanceType] if value.klass == Hash # TODO in [RBS::Types::Interface,] definition = rbs_builder.build_interface rbs_type.name convert = {} definition.type_params.zip(rbs_type.args).each do |from, arg| convert[from] = arg.name if arg.is_a? RBS::Types::Variable end return if convert.empty? ac = {} definition.methods.each do |method_name, method| return_type = method_return_type value, method_name method.defs.each do |method_def| interface_return_type = method_def.type.type.return_type _match_free_variable convert, interface_return_type, return_type, ac end end convert.each do |from, to| values = ac[from] (accumulator[to] ||= []).concat