lib/steep/interface/shape.rb in steep-1.7.0.dev.2 vs lib/steep/interface/shape.rb in steep-1.7.0.dev.3

- old
+ new

@@ -1,18 +1,47 @@ module Steep module Interface class Shape class Entry - attr_reader :method_types - - def initialize(method_types:) + def initialize(method_types: nil, private_method:, &block) @method_types = method_types + @generator = block + @private_method = private_method end + def force + unless @method_types + @method_types = @generator&.call + @generator = nil + end + end + + def method_types + force + @method_types or raise + end + + def has_method_type? + force + @method_types ? true : false + end + def to_s - "{ #{method_types.join(" || ")} }" + if @generator + "<< Lazy entry >>" + else + "{ #{method_types.join(" || ")} }" + end end + + def private_method? + @private_method + end + + def public_method? + !private_method? + end end class Methods attr_reader :substs, :methods, :resolved_methods @@ -23,11 +52,15 @@ @methods = methods @resolved_methods = methods.transform_values { nil } end def key?(name) - methods.key?(name) + if entry = methods.fetch(name, nil) + entry.has_method_type? + else + false + end end def []=(name, entry) resolved_methods[name] = nil methods[name] = entry @@ -35,32 +68,36 @@ def [](name) return nil unless key?(name) resolved_methods[name] ||= begin + entry = methods[name] Entry.new( - method_types: methods[name].method_types.map do |method_type| + method_types: entry.method_types.map do |method_type| method_type.subst(subst) - end + end, + private_method: entry.private_method? ) end end def each(&block) if block methods.each_key do |name| - entry = self[name] or raise + entry = self[name] or next yield [name, entry] end else enum_for :each end end def each_name(&block) if block - methods.each_key(&block) + each do |name, _| + yield name + end else enum_for :each_name end end @@ -74,23 +111,25 @@ def push_substitution(subst) Methods.new(substs: [*substs, subst], methods: methods) end - def merge!(other) + def merge!(other, &block) other.each do |name, entry| - methods[name] = entry + if block && (old_entry = methods[name]) + methods[name] = yield(name, old_entry, entry) + else + methods[name] = entry + end end end - def +(other) - methods = Methods.new(substs: [], methods: {}) - - methods.merge!(self) - methods.merge!(other) - - methods + def public_methods + Methods.new( + substs: substs, + methods: methods.reject {|_, entry| entry.private_method? } + ) end end attr_reader :type attr_reader :methods @@ -124,9 +163,21 @@ @private end def public? !private? + end + + def public_shape + if public? + self + else + @public_shape ||= Shape.new( + type: type, + private: false, + methods: methods.public_methods + ) + end end end end end