# encoding: utf-8 # frozen_string_literal: true require "carbon/concrete/item/trait/expectation" module Carbon module Concrete module Item # A trait. This says that a specific type behaves with a certain set # of functions. # # @api private # @note # **This class is frozen upon initialization.** This means that any # attempt to modify it will result in an error. In most cases, the # attributes on this class will also be frozen, as well. class Trait include Base # (see Item::Base.from) def self.from(type) { module: type, expectations: [] } end # The expectations for the trait. # # @api semipublic # @example # trait.expectations # # => [#] attr_reader :expectations # Initialize the trait with data. # # @param data [::Hash] The data to initialize the trait with. # @option data [Type] :module The name of the trait type. # @option data [<(::String, , Type)>] :expectations # The expectations that the trait requires. def initialize(data) @module = data.fetch(:module) @generics = @module.generics @intern = @module.intern @name = @module.to_s derive_expectations(data.fetch(:expectations)) derive_dependencies deep_freeze! end # (see Base#call) def call(build, generics) super # TODO: fixme. end private def derive_expectations(expectations) expects = expectations.map { |e| Expectation.new(*e) } @expectations = Set.new(expects) end def derive_dependencies @expectations.each do |expect| @dependencies.merge(expect.parameters.map(&:to_request)) @dependencies << expect.return.to_request end end end end end end