Class: Carbon::Concrete::Index
- Inherits:
-
Object
- Object
- Carbon::Concrete::Index
- Extended by:
- Forwardable
- Includes:
- Enumerable, TSort
- Defined in:
- lib/carbon/concrete/index.rb
Overview
A list of all of the "items" in the global context of Carbon. Items are mostly functions and data definitions. This keeps track of them and their dependencies, so that they can be built later. Indexes are also designed to be easily serialized if needed (which is likely the case, for libraries).
Constant Summary collapse
- ITEMS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Used only for #define. This maps item "names" to the classes that represent them.
{ internal: Concrete::Item::Internal, function: Concrete::Item::Function, struct: Concrete::Item::Struct, trait: Concrete::Item::Trait }.freeze
Instance Method Summary collapse
-
#add(item) ⇒ self
(also: #<<)
Adds a defined item to the index.
-
#build(item) {|dep| ... } ⇒ ::Enumerable, void
Yields the builds that need to be built for the given item.
-
#define(data) {|data| ... } ⇒ void
Defines a type.
- #fetch(type, default = @canary) ⇒ Object
-
#finalize ⇒ self
Finalizes the index.
-
#id ⇒ ::String
The digest of the ID.
-
#initialize(data = {}) ⇒ Index
constructor
Initialize the index with the given data.
- #item?(type) ⇒ Boolean
- #items ⇒ Object
- #link(index) ⇒ Object
- #to_json ⇒ Object
Constructor Details
#initialize(data = {}) ⇒ Index
Initialize the index with the given data.
41 42 43 44 45 |
# File 'lib/carbon/concrete/index.rb', line 41 def initialize(data = {}) @items = ::Set.new.merge(data.fetch(:items, [])) @links = ::Set.new @id = data.fetch(:id) { id } end |
Instance Method Details
#add(item) ⇒ self Also known as: <<
Adds a defined item to the index. The item just has to respond to the item API (see Carbon::Concrete::Item). This clears the index's cache, such that the ID (#id) and item list (#items) are reset and have to be recalculated.
110 111 112 113 |
# File 'lib/carbon/concrete/index.rb', line 110 def add(item) @items << item clear! end |
#build(item) {|dep| ... } ⇒ ::Enumerable, void
Yields the builds that need to be built for the given item. This uses the TSort module in order to determine all of the dependencies the given item has, and yields each; and finally, yields the last item. The item may not have any generics, even if they are fully formed generics (e.g. have a definition). If any items have a cyclic depdendency, it fails.
204 205 206 207 208 209 210 |
# File 'lib/carbon/concrete/index.rb', line 204 def build(item) fail ArgumentError, "Passed item cannot be generic" if \ item.generics.any? return to_enum(:build, item) unless block_given? build_from_request(item, &Proc.new) end |
#define(data) {|data| ... } ⇒ void
This method returns an undefined value.
Defines a type. This is mostly a shorthand method. The purpose of this is to make it easy to define items on the index. The only parameter, data, is a hash. The key is the name of the type of the item; this corresponds to the keys in the ITEMS hash. The value is the Type that is being defined. The method then yields a hash that is later used to define the item.
177 178 179 180 181 182 183 184 185 |
# File 'lib/carbon/concrete/index.rb', line 177 def define(data) fail ArgumentError, "Expected only one pair" if data.size > 1 data.each do |itype, name| item = ITEMS.fetch(itype) opts = item.from(Carbon::Type(name)) yield opts self << item.new(opts) end end |
#fetch(type, default = @canary) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/carbon/concrete/index.rb', line 48 def fetch(type, default = @canary) matching = items.map { |i| [i, i.type.match?(type)] }.select(&:last) fail TooManyItemsError, "Multiple items match #{type}" if matching.size > 1 match = matching.first return match if match return yield if block_given? return default if default != @canary fail ItemNotFoundError, "Could not find an item named #{type}" end |
#finalize ⇒ self
This freezes the item list for the index. This prevents modification for this instance of the index.
Finalizes the index. This should only be used when all of the items defined on the index are defined. For libraries, this is the culmination of everything in the library.
130 131 132 133 134 135 |
# File 'lib/carbon/concrete/index.rb', line 130 def finalize current = @items.dup items = ::Set.new(current.map { |item| item.define(self) }) @items = items.freeze clear! end |
#id ⇒ ::String
The digest of the ID. This uses the SHA256 base58 digest of the items defined on the current index. This includes both defined and merged items.
92 93 94 95 96 97 |
# File 'lib/carbon/concrete/index.rb', line 92 def id @_id ||= begin body = (@items.map(&:type).map(&:to_s) + @links.map(&:id)).join("\n") Carbon.hash(body) end end |
#item?(type) ⇒ Boolean
60 61 62 |
# File 'lib/carbon/concrete/index.rb', line 60 def item?(type) items.any? { |item| item.type.match?(type) } end |
#items ⇒ Object
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/carbon/concrete/index.rb', line 64 def items @_current ||= begin current = @items.dup @links.each do |link| current.merge(link.items) end current.freeze end end |
#link(index) ⇒ Object
117 118 119 120 |
# File 'lib/carbon/concrete/index.rb', line 117 def link(index) @links << index clear! end |