class Carbon::Concrete::Type::Generic

A generic part of a type. This is normally the `T` in `Carbon::Pointer<T>`. Generic portions can also have traits that the generic type must implement; this keeps track of that too. A complete example, containing traits, would look like this: `Carbon::Pointer<T: Carbon::Sized + Carbon::Numeric>`. The actual pointer type may not use those traits.

@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.

Attributes

implements[R]

The implements of the generic. These are the traits that the generic parameter has to implement; this allows the generic code to make assumptions about the generic type (such as behavior or size) that would otherwise be impossible to make.

@api public @example

name = "Carbon::Pointer<T: Carbon::Sized>"
type = Carbon::Type(name)
type.generics.first.implements
  # => Set[#<Carbon::Concrete::Type Carbon::Sized>]

@return [Set<Type>] The traits the generic has to implement.

location[R]

The location of the type. This is used for interfacing with other programs that require a location of some sort.

@api semiprivate @return [Object]

name[R]

The name of the generic. This is the generic type variable that is substituted in later for an actual value. This is normally a single character module name, but can be as complicated as needed.

@api public @example

type = Carbon::Type("Carbon::Pointer<T>")
type.generics.first.name # => #<Carbon::Concrete::Type T>

@return [Type] The name.

Public Class Methods

new(name, implements, location: nil) click to toggle source

Initialize the generic part of the type.

@see name @see implements @param name [Type] The name of the generic. @param implements [Set<Type>] The traits the generic must

implement, if any.
# File lib/carbon/concrete/type/generic.rb, line 58
def initialize(name, implements, location: nil)
  @location = location
  @name = name
  @implements = Set.new(implements)
  deep_freeze!
end

Public Instance Methods

==(other) click to toggle source

Compares this generic instance to another generic instance. If the other generic instance is this generic instance it returns true; otherwise, if the other value is a generic, and that generic's {#to_s} is equal to this one's, it returns true; otherwise, it returns false.

@api public @example

type1 = Carbon::Type("Carbon::Pointer<T>")
type2 = Carbon::Type("Carbon::List<T>")
type1.generics == type2.generics # => true

@param other [Type::Generic, ::Object] The object to compare. @return [::Boolean] True if the two are equivalent.

# File lib/carbon/concrete/type/generic.rb, line 99
def ==(other)
  equal?(other) ||
    (other.is_a?(Type::Generic) && other.to_s == to_s)
end
Also aliased as: eql?
accept(visitor, *params) click to toggle source

Accepts the current visitor unto itself.

@param visitor [#visit] @return [Object]

# File lib/carbon/concrete/type/generic.rb, line 128
def accept(visitor, *params)
  visitor.visit(self, *params)
end
eql?(other)
Alias for: ==
sub(mapping) click to toggle source

Returns the correct generic. This is a weird function, but essentially, if the {#name}'s {Type#intern} is oen of the keys of the mapping, it returns the new generic; otherwise, it returns this object.

@api public @example

generic.to_s # => "T: Carbon::Sized"
generic.is_a?(Generic) # => true
other.to_s # => "Carbon::String"
other.is_a?(Generic) # => true
result = generic.sub("T" => other)
result.to_s # => "Carbon::String: Carbon::Sized"

@param mapping [{::String => Type}] The mapping. @return [Type::Generic] A different instance of the generic, if it's

in the mapping.

@return [self] otherwise.

# File lib/carbon/concrete/type/generic.rb, line 82
def sub(mapping)
  Generic.new(mapping.fetch(@name, @name), @implements)
end
to_s() click to toggle source

A string representation of the generic. If there are no implements, this is a direct call to {#name}'s {Type#to_s}; otherwise, this includes the name with a joined string of implements.

@api public @example

name = "Carbon::Pointer<T: Carbon::Sized>"
type = Carbon::Type(name)
type.generics.first.to_s # => "T: Carbon::Sized"

@return [::String] The string representation.

# File lib/carbon/concrete/type/generic.rb, line 116
def to_s
  if @implements.any?
    "#{@name}: #{@implements.map(&:to_s).join(' + ')}".freeze
  else
    @name.to_s
  end
end