lib/steep/interface/builder.rb in steep-0.4.0 vs lib/steep/interface/builder.rb in steep-0.5.0

- old
+ new

@@ -71,10 +71,16 @@ when AST::Types::Tuple AST::Types::Tuple.new( types: type.types.map {|ty| absolute_type(ty, current:current) }, location: type.location ) + when AST::Types::Proc + AST::Types::Proc.new( + params: type.params.map_type {|ty| absolute_type(ty, current: current) }, + return_type: absolute_type(type.return_type, current: current), + location: type.location + ) else type end end @@ -135,20 +141,20 @@ end merge_ivars ivars, instantiated.ivars end - def add_method(type_name, method, methods:) + def add_method(type_name, method, methods:, extra_attributes: []) super_method = methods[method.name] new_method = Method.new( type_name: type_name, name: method.name, types: method.types.map do |method_type| method_type_to_method_type(method_type, current: type_name.name) end, super_method: super_method, - attributes: method.attributes + attributes: method.attributes + extra_attributes ) methods[method.name] = if super_method&.include_in_chain?(new_method) super_method else @@ -241,10 +247,21 @@ end end end end + signatures.find_extensions(sig.name).each do |ext| + ext.members.each do |member| + case member + when AST::Signature::Members::Method + if member.module_method? + add_method(type_name, member, methods: methods) + end + end + end + end + unless constructor methods.delete(:new) end Abstract.new( @@ -259,10 +276,11 @@ def module_to_interface(sig) type_name = TypeName::Module.new(name: sig.name) supers = [sig.self_type].compact.map {|type| absolute_type(type, current: nil) } methods = {} + ivar_chains = {} module_instance = build(TypeName::Instance.new(name: ModuleName.parse("::Module"))) instantiated = module_instance.instantiate( type: AST::Types::Self.new, args: [], @@ -275,18 +293,18 @@ case member when AST::Signature::Members::Include merge_mixin(TypeName::Module.new(name: member.name), member.args.map {|type| absolute_type(type, current: sig.name) }, methods: methods, - ivars: {}, + ivars: ivar_chains, supers: supers, current: sig.name) when AST::Signature::Members::Extend merge_mixin(TypeName::Instance.new(name: member.name), member.args.map {|type| absolute_type(type, current: sig.name) }, methods: methods, - ivars: {}, + ivars: ivar_chains, supers: supers, current: sig.name) end end @@ -294,19 +312,35 @@ case member when AST::Signature::Members::Method if member.module_method? add_method(type_name, member, methods: methods) end + when AST::Signature::Members::Ivar + merge_ivars(ivar_chains, + { member.name => absolute_type(member.type, current: sig.name) }) + when AST::Signature::Members::Attr + merge_attribute(sig, ivar_chains, methods, type_name, member) end end + signatures.find_extensions(sig.name).each do |ext| + ext.members.each do |member| + case member + when AST::Signature::Members::Method + if member.module_method? + add_method(type_name, member, methods: methods) + end + end + end + end + Abstract.new( name: type_name, params: [], methods: methods, supers: supers, - ivar_chains: {} + ivar_chains: ivar_chains ) end def instance_to_interface(sig, with_initialize:) type_name = TypeName::Instance.new(name: sig.name) @@ -317,11 +351,11 @@ ivar_chains = {} if sig.is_a?(AST::Signature::Class) unless sig.name == ModuleName.parse("::BasicObject") super_class_name = sig.super_class&.name || ModuleName.parse("::Object") - super_class_interface = build(TypeName::Instance.new(name: super_class_name), current: nil) + super_class_interface = build(TypeName::Instance.new(name: super_class_name), current: nil, with_initialize: with_initialize) supers.push(*super_class_interface.supers) instantiated = super_class_interface.instantiate( type: AST::Types::Self.new, args: (sig.super_class&.args || []).map {|type| absolute_type(type, current: nil) }, @@ -355,55 +389,19 @@ sig.members.each do |member| case member when AST::Signature::Members::Method if member.instance_method? if with_initialize || member.name != :initialize - add_method(type_name, member, methods: methods) + extra_attrs = member.name == :initialize ? [:incompatible] : [] + add_method(type_name, member, methods: methods, extra_attributes: extra_attrs) end end when AST::Signature::Members::Ivar merge_ivars(ivar_chains, { member.name => absolute_type(member.type, current: sig.name) }) when AST::Signature::Members::Attr - if member.ivar != false - ivar_name = member.ivar || "@#{member.name}".to_sym - merge_ivars(ivar_chains, - { ivar_name => absolute_type(member.type, current: sig.name) }) - end - - reader_method = AST::Signature::Members::Method.new( - location: member.location, - name: member.name, - kind: :instance, - types: [ - AST::MethodType.new(location: member.type.location, - type_params: nil, - params: nil, - block: nil, - return_type: member.type) - ], - attributes: [] - ) - add_method(type_name, reader_method, methods: methods) - - if member.accessor? - writer_method = AST::Signature::Members::Method.new( - location: member.location, - name: "#{member.name}=".to_sym, - kind: :instance, - types: [ - AST::MethodType.new(location: member.type.location, - type_params: nil, - params: AST::MethodType::Params::Required.new(location: member.type.location, - type: member.type), - block: nil, - return_type: member.type) - ], - attributes: [] - ) - add_method(type_name, writer_method, methods: methods) - end + merge_attribute(sig, ivar_chains, methods, type_name, member) end end signatures.find_extensions(sig.name).each do |ext| ext.members.each do |member| @@ -423,10 +421,51 @@ supers: supers, ivar_chains: ivar_chains ) end + def merge_attribute(sig, ivar_chains, methods, type_name, member) + if member.ivar != false + ivar_name = member.ivar || "@#{member.name}".to_sym + merge_ivars(ivar_chains, + { ivar_name => absolute_type(member.type, current: sig.name) }) + end + + reader_method = AST::Signature::Members::Method.new( + location: member.location, + name: member.name, + kind: :instance, + types: [ + AST::MethodType.new(location: member.type.location, + type_params: nil, + params: nil, + block: nil, + return_type: member.type) + ], + attributes: [] + ) + add_method(type_name, reader_method, methods: methods) + + if member.accessor? + writer_method = AST::Signature::Members::Method.new( + location: member.location, + name: "#{member.name}=".to_sym, + kind: :instance, + types: [ + AST::MethodType.new(location: member.type.location, + type_params: nil, + params: AST::MethodType::Params::Required.new(location: member.type.location, + type: member.type), + block: nil, + return_type: member.type) + ], + attributes: [] + ) + add_method(type_name, writer_method, methods: methods) + end + end + def merge_ivars(dest, new_vars) new_vars.each do |name, new_type| dest[name] = IvarChain.new(type: new_type, parent: dest[name]) end end @@ -458,11 +497,15 @@ def method_type_to_method_type(method_type, current:) type_params = method_type.type_params&.variables || [] params = params_to_params(method_type.params, current: current) block = method_type.block && Block.new( - params: params_to_params(method_type.block.params, current: current), - return_type: absolute_type(method_type.block.return_type, current: current) + type: AST::Types::Proc.new( + params: params_to_params(method_type.block.params, current: current), + return_type: absolute_type(method_type.block.return_type, current: current), + location: method_type.block.location, + ), + optional: method_type.block.optional ) MethodType.new( type_params: type_params, return_type: absolute_type(method_type.return_type, current: current),