# encoding: utf-8 # frozen_string_literal: true module Carbon module Concrete # Handles building requests. This is the step after all requests are # determined from the dependency build stage. The entire purpose of this # class is to consolidate state information for LLVM module building. # # @api semiprivate class Build # The types that have been defined. This is a mapping of the # {Concrete::Type} to an arry of the {Concrete::Item} and the # corresponding `LLVM::Type`. This is so that no information is lost # when converting the item to the type. # # @return [{Concrete::Type => (Concrete::Item, ::LLVM::Value)}] attr_reader :items # The LLVM module that is being used for compilation. # # @return [::LLVM::Module] attr_reader :module # The index associated with this build. # # @return [Concrete::Index] attr_reader :index # Initialize the build process. This only initializes instance # variables. # # @param requests [::Enumerable] An enumerable over # each request that needs to be built. The requests should be # resolved, i.e. the generics for the request should resolve to a # valid type. # @param index [Concrete::Index] The index that is being built from. def initialize(requests, index) @requests = requests @index = index end def fetch(name, default = nil) result = @items.find { |(k, _v)| k.match?(name) } return result[1] if result return default if default yield if block_given? fail ItemNotFoundError, "Could not find item with name #{name}" end # Performs the build process. Builds each request in order by calling # {Concrete::Item::Base#call} on each. # # @return [::LLVM::Module] The built module. def call @items = {} @module = ::LLVM::Module.new("__carbon_main") @requests.each do |request| item = @index.fetch(request).first generics = item.generics.map(&:name) .zip(request.generics.map(&:name)).to_h item.call(self, generics) end @module end end end end