# encoding: utf-8 # frozen_string_literal: true module Carbon module Concrete class Type # The function part of a type. This comes after the module that it is # defined in, and contains three pieces of information: the name of the # function, the generics associated with the function, and the parameters # of the function. # # @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. # @note # This class does not include comparison methods; however, if they # were to ever be needed, {#to_s} should be used for the basis of # comparison. class Function # The name of the function. This is normally a bland string. # Functions can have a variety of names to override default operations # in the language; even more so than ruby. # # @api public # @example # type = Carbon::Type("A.+(A, B)") # func = type.function # func.name # => "+" # @return [::String] The name of the function. attr_reader :name # The parameters for the function. These are the arguments that are # passed to the function when it's called. This is included in the # definition for the name of the function to allow overloading. # # @api public # @example # type = Carbon::Type("A.+(A, B)") # func = type.function # func.parameters # # => [#, # # #] # @return [::Array] attr_reader :parameters # The generics used in the function definition. # # @api public # @example # type = Carbon::Type("A.+(A, T)") # func = type.function # func.generics # # => [#] # @return [::Array] attr_reader :generics # Initialize the function. # # @see #name # @see #params # @param name [::String] The name of the function. # @param params [::Array] The parameters of the function. # This is frozen before stored. def initialize(name, params, generics = []) @name = name.to_s @parameters = params @generics = generics deep_freeze! end # Returns a string representation of this function. In contrast to # {#intern}, this includes generic information. # # @api public # @example # func.name # => "+" # func.parameters # => [#>] # func.to_s # => "+(Test)" # @return [::String] def to_s if @generics.any? "#{@name}<#{@generics.map(&:to_s).join(',')}>" \ "(#{@parameters.map(&:to_s).join(', ')})".freeze else "#{@name}(#{@parameters.map(&:to_s).join(', ')})".freeze end end # Returns the interned version of this function. In contrast to # {#to_s}, this does not include generic information. # # @api public # @note See {Item::Base#intern} For more information about interned # names. # @example # func.name # => "+" # func.parameters # => [#>] # func.intern # => "+(Test)" # @return [::String] def intern "#{@name}(#{@parameters.map(&:intern).join(', ')})".freeze end end end end end