carbon-core 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitattributes +17 -0
- data/.gitignore +0 -0
- data/.rspec +0 -0
- data/.rubocop.yml +0 -0
- data/.travis.yml +0 -0
- data/.yardopts +0 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +0 -0
- data/LICENSE.txt +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/Vagrantfile +0 -0
- data/carbon.gemspec +0 -0
- data/lib/carbon.rb +25 -1
- data/lib/carbon/concrete.rb +4 -2
- data/lib/carbon/concrete/build.rb +21 -13
- data/lib/carbon/concrete/index.rb +53 -159
- data/lib/carbon/concrete/item.rb +0 -0
- data/lib/carbon/concrete/item/base.rb +14 -27
- data/lib/carbon/concrete/item/class.rb +71 -0
- data/lib/carbon/concrete/item/class/element.rb +42 -0
- data/lib/carbon/concrete/item/data.rb +0 -0
- data/lib/carbon/concrete/item/function.rb +35 -39
- data/lib/carbon/concrete/item/internal.rb +17 -19
- data/lib/carbon/concrete/item/struct.rb +12 -7
- data/lib/carbon/concrete/item/struct/element.rb +0 -0
- data/lib/carbon/concrete/item/trait.rb +9 -10
- data/lib/carbon/concrete/item/trait/expectation.rb +0 -0
- data/lib/carbon/concrete/request.rb +137 -136
- data/lib/carbon/concrete/type.rb +126 -21
- data/lib/carbon/concrete/type/function.rb +26 -10
- data/lib/carbon/concrete/type/generic.rb +19 -3
- data/lib/carbon/concrete/type/name.rb +0 -0
- data/lib/carbon/concrete/type/parse.rb +1 -0
- data/lib/carbon/concrete/type/part.rb +9 -1
- data/lib/carbon/core.rb +6 -1
- data/lib/carbon/core/int.rb +0 -0
- data/lib/carbon/core/integer.rb +0 -0
- data/lib/carbon/core/integer/cast.rb +0 -0
- data/lib/carbon/core/integer/math.rb +0 -0
- data/lib/carbon/core/integer/misc.rb +17 -1
- data/lib/carbon/core/integer/pole.rb +0 -0
- data/lib/carbon/core/integer/ship.rb +8 -4
- data/lib/carbon/core/integer/sign.rb +0 -0
- data/lib/carbon/core/integer/type.rb +0 -0
- data/lib/carbon/core/integer/zero.rb +0 -0
- data/lib/carbon/core/main.rb +50 -0
- data/lib/carbon/core/pointer.rb +0 -0
- data/lib/carbon/core/pointer/access.rb +1 -1
- data/lib/carbon/core/pointer/cast.rb +0 -0
- data/lib/carbon/core/pointer/math.rb +14 -0
- data/lib/carbon/core/pointer/memory.rb +2 -4
- data/lib/carbon/core/pointer/type.rb +0 -0
- data/lib/carbon/core/void.rb +20 -0
- data/lib/carbon/counter.rb +27 -0
- data/lib/carbon/errors.rb +13 -0
- data/lib/carbon/tacky.rb +0 -0
- data/lib/carbon/tacky/block.rb +0 -0
- data/lib/carbon/tacky/builder.rb +3 -6
- data/lib/carbon/tacky/context.rb +4 -10
- data/lib/carbon/tacky/function.rb +0 -24
- data/lib/carbon/tacky/instruction.rb +2 -5
- data/lib/carbon/tacky/instruction/generation.rb +19 -41
- data/lib/carbon/tacky/parameter.rb +0 -0
- data/lib/carbon/tacky/reference.rb +0 -0
- data/lib/carbon/tacky/typed.rb +0 -0
- data/lib/carbon/tacky/value.rb +0 -2
- data/lib/carbon/version.rb +1 -1
- data/scripts/core.rb +0 -0
- data/scripts/test.rb +5 -7
- metadata +9 -4
- data/lib/carbon/tacky/instruction/dependencies.rb +0 -33
- data/lib/carbon/tacky/instruction/typeof.rb +0 -25
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 8365acf735d2c50dee428d024b4a840c1c6161e7
         | 
| 4 | 
            +
              data.tar.gz: 279f5819696b66cd4e7add773d8afc8a75409ea7
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 0b429250034abeca6ee48306e4ce461cfc432ac622f6ef0471c8efa7c9e40baa5016559672660258ea90fcd93f92d7ccfe39d852a9fefb34b3dc9b4ffaa6aa4a
         | 
| 7 | 
            +
              data.tar.gz: 3e9e619482e2303cc9643a7c73eb5417982a285986a329b6509e521278b76a6e45c91c32b40b48154625fbc3dabbea38eb56c29c90a9b8747d29f507007964e1
         | 
    
        data/.gitattributes
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            # Auto detect text files and perform LF normalization
         | 
| 2 | 
            +
            * text=auto
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # Custom for Visual Studio
         | 
| 5 | 
            +
            *.cs     diff=csharp
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            # Standard to msysgit
         | 
| 8 | 
            +
            *.doc	 diff=astextplain
         | 
| 9 | 
            +
            *.DOC	 diff=astextplain
         | 
| 10 | 
            +
            *.docx diff=astextplain
         | 
| 11 | 
            +
            *.DOCX diff=astextplain
         | 
| 12 | 
            +
            *.dot  diff=astextplain
         | 
| 13 | 
            +
            *.DOT  diff=astextplain
         | 
| 14 | 
            +
            *.pdf  diff=astextplain
         | 
| 15 | 
            +
            *.PDF	 diff=astextplain
         | 
| 16 | 
            +
            *.rtf	 diff=astextplain
         | 
| 17 | 
            +
            *.RTF	 diff=astextplain
         | 
    
        data/.gitignore
    CHANGED
    
    | 
            File without changes
         | 
    
        data/.rspec
    CHANGED
    
    | 
            File without changes
         | 
    
        data/.rubocop.yml
    CHANGED
    
    | 
            File without changes
         | 
    
        data/.travis.yml
    CHANGED
    
    | 
            File without changes
         | 
    
        data/.yardopts
    CHANGED
    
    | 
            File without changes
         | 
    
        data/CODE_OF_CONDUCT.md
    CHANGED
    
    | 
            File without changes
         | 
    
        data/Gemfile
    CHANGED
    
    | 
            File without changes
         | 
    
        data/LICENSE.txt
    CHANGED
    
    | 
            File without changes
         | 
    
        data/README.md
    CHANGED
    
    | 
            File without changes
         | 
    
        data/Rakefile
    CHANGED
    
    | 
            File without changes
         | 
    
        data/Vagrantfile
    CHANGED
    
    | 
            File without changes
         | 
    
        data/carbon.gemspec
    CHANGED
    
    | 
            File without changes
         | 
    
        data/lib/carbon.rb
    CHANGED
    
    | @@ -9,6 +9,8 @@ require "concurrent" | |
| 9 9 | 
             
            require "llvm"
         | 
| 10 10 | 
             
            require "llvm/core"
         | 
| 11 11 | 
             
            require "carbon/version"
         | 
| 12 | 
            +
            require "carbon/counter"
         | 
| 13 | 
            +
            require "carbon/errors"
         | 
| 12 14 |  | 
| 13 15 | 
             
            # Carbon.  The language.
         | 
| 14 16 | 
             
            module Carbon
         | 
| @@ -37,11 +39,26 @@ module Carbon | |
| 37 39 | 
             
              # @param string [::String] The string to hash.
         | 
| 38 40 | 
             
              # @return [::String] The hashed string.
         | 
| 39 41 | 
             
              def self.hash(string)
         | 
| 40 | 
            -
                digest = Digest::SHA2.hexdigest(string).hex
         | 
| 42 | 
            +
                digest = (Digest::SHA2.hexdigest(string).hex << 6) ^ 0xCA5B04
         | 
| 41 43 | 
             
                encoded = Base58.encode(digest)
         | 
| 42 44 | 
             
                encoded.scan(/.{1,9}/).join("-").freeze
         | 
| 43 45 | 
             
              end
         | 
| 44 46 |  | 
| 47 | 
            +
              # The verboseness of Carbon.  This is a global setting.
         | 
| 48 | 
            +
              #
         | 
| 49 | 
            +
              # @return [::Integer] The verboseness.
         | 
| 50 | 
            +
              def self.verbose
         | 
| 51 | 
            +
                @_verbose ||= 1
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              # The verboseness of Carbon.  This is a global setting.
         | 
| 55 | 
            +
              #
         | 
| 56 | 
            +
              # @param verbose [::Integer] The new verbose level.
         | 
| 57 | 
            +
              # @return [::Integer]
         | 
| 58 | 
            +
              def self.verbose=(verbose)
         | 
| 59 | 
            +
                @_verbose = verbose
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 45 62 | 
             
              require "carbon/concrete"
         | 
| 46 63 |  | 
| 47 64 | 
             
              # A Boolean type for Carbon.  This is used as a handy shortcut.
         | 
| @@ -50,6 +67,13 @@ module Carbon | |
| 50 67 | 
             
              # @return [Carbon::Concrete::Type]
         | 
| 51 68 | 
             
              Boolean = Carbon::Type("Carbon::Boolean")
         | 
| 52 69 |  | 
| 70 | 
            +
              # A Void type for Carbon.  This is used as a handy shortcut.
         | 
| 71 | 
            +
              #
         | 
| 72 | 
            +
              # @api private
         | 
| 73 | 
            +
              # @return [Carbon::Concrete::Type]
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              Void = Carbon::Type("Carbon::Void")
         | 
| 76 | 
            +
             | 
| 53 77 | 
             
              require "carbon/tacky"
         | 
| 54 78 | 
             
              require "carbon/core"
         | 
| 55 79 | 
             
            end
         | 
    
        data/lib/carbon/concrete.rb
    CHANGED
    
    | @@ -14,6 +14,8 @@ module Carbon | |
| 14 14 | 
             
              # the things within this module should be serializable, so that libraries
         | 
| 15 15 | 
             
              # may be linked easily back into the process.
         | 
| 16 16 | 
             
              module Concrete
         | 
| 17 | 
            +
                OPTIONS = { circular: true, class_cache: true }.freeze
         | 
| 18 | 
            +
             | 
| 17 19 | 
             
                # Loads a dumped object into an instance.  The dumped object should be a
         | 
| 18 20 | 
             
                # Zlib compressed (with Deflate) string.  The dumped object
         | 
| 19 21 | 
             
                # is decompressed and loaded, then passed to {.from}.
         | 
| @@ -24,7 +26,7 @@ module Carbon | |
| 24 26 | 
             
                # @return [::Object] The represented object.
         | 
| 25 27 | 
             
                def self.load(source)
         | 
| 26 28 | 
             
                  raw = Zlib::Inflate.inflate(source)
         | 
| 27 | 
            -
                  Oj.load(raw)
         | 
| 29 | 
            +
                  Oj.load(raw, OPTIONS)
         | 
| 28 30 | 
             
                end
         | 
| 29 31 |  | 
| 30 32 | 
             
                # Dumps an object to a string.  If the object responds to `#to_basic`, the
         | 
| @@ -36,7 +38,7 @@ module Carbon | |
| 36 38 | 
             
                # @param index [::Object] The object to dump.
         | 
| 37 39 | 
             
                # @return [::String] The dumped object.
         | 
| 38 40 | 
             
                def self.dump(index)
         | 
| 39 | 
            -
                  raw = Oj.dump(index,  | 
| 41 | 
            +
                  raw = Oj.dump(index, OPTIONS)
         | 
| 40 42 | 
             
                  Zlib::Deflate.deflate(raw, 9)
         | 
| 41 43 | 
             
                end
         | 
| 42 44 | 
             
              end
         | 
| @@ -14,24 +14,23 @@ module Carbon | |
| 14 14 | 
             
                  # corresponding `LLVM::Type`.  This is so that no information is lost
         | 
| 15 15 | 
             
                  # when converting the item to the type.
         | 
| 16 16 | 
             
                  #
         | 
| 17 | 
            -
                  # @return [{Concrete::Type => (Concrete::Item, ::LLVM:: | 
| 18 | 
            -
                  attr_reader : | 
| 19 | 
            -
             | 
| 20 | 
            -
                  # The functions that have been defined.  This is a mapping of the
         | 
| 21 | 
            -
                  # {Concrete::Type} to the `LLVM::Function` that was defined.
         | 
| 22 | 
            -
                  #
         | 
| 23 | 
            -
                  # @return [{Concrete::Type => (Concrete::Item, ::LLVM::Function)}]
         | 
| 24 | 
            -
                  attr_reader :functions
         | 
| 17 | 
            +
                  # @return [{Concrete::Type => (Concrete::Item, ::LLVM::Value)}]
         | 
| 18 | 
            +
                  attr_reader :items
         | 
| 25 19 |  | 
| 26 20 | 
             
                  # The LLVM module that is being used for compilation.
         | 
| 27 21 | 
             
                  #
         | 
| 28 22 | 
             
                  # @return [::LLVM::Module]
         | 
| 29 23 | 
             
                  attr_reader :module
         | 
| 30 24 |  | 
| 25 | 
            +
                  # The index associated with this build.
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  # @return [Concrete::Index]
         | 
| 28 | 
            +
                  attr_reader :index
         | 
| 29 | 
            +
             | 
| 31 30 | 
             
                  # Initialize the build process.  This only initializes instance
         | 
| 32 31 | 
             
                  # variables.
         | 
| 33 32 | 
             
                  #
         | 
| 34 | 
            -
                  # @param requests [::Enumerable<Concrete:: | 
| 33 | 
            +
                  # @param requests [::Enumerable<Concrete::Type>] An enumerable over
         | 
| 35 34 | 
             
                  #   each request that needs to be built.  The requests should be
         | 
| 36 35 | 
             
                  #   resolved, i.e. the generics for the request should resolve to a
         | 
| 37 36 | 
             
                  #   valid type.
         | 
| @@ -41,18 +40,27 @@ module Carbon | |
| 41 40 | 
             
                    @index = index
         | 
| 42 41 | 
             
                  end
         | 
| 43 42 |  | 
| 43 | 
            +
                  def fetch(name, default = nil)
         | 
| 44 | 
            +
                    result = @items.find { |(k, _v)| k.match?(name) }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    return result[1] if result
         | 
| 47 | 
            +
                    return default if default
         | 
| 48 | 
            +
                    yield if block_given?
         | 
| 49 | 
            +
                    fail ItemNotFoundError, "Could not find item with name #{name}"
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 44 52 | 
             
                  # Performs the build process.  Builds each request in order by calling
         | 
| 45 53 | 
             
                  # {Concrete::Item::Base#call} on each.
         | 
| 46 54 | 
             
                  #
         | 
| 47 55 | 
             
                  # @return [::LLVM::Module] The built module.
         | 
| 48 56 | 
             
                  def call
         | 
| 49 | 
            -
                    @ | 
| 50 | 
            -
                    @functions = {}
         | 
| 57 | 
            +
                    @items = {}
         | 
| 51 58 | 
             
                    @module = ::LLVM::Module.new("__carbon_main")
         | 
| 52 59 |  | 
| 53 60 | 
             
                    @requests.each do |request|
         | 
| 54 | 
            -
                      item = @index.fetch(request. | 
| 55 | 
            -
                      generics = item.generics. | 
| 61 | 
            +
                      item = @index.fetch(request).first
         | 
| 62 | 
            +
                      generics = item.generics.map(&:name)
         | 
| 63 | 
            +
                        .zip(request.generics.map(&:name)).to_h
         | 
| 56 64 | 
             
                      item.call(self, generics)
         | 
| 57 65 | 
             
                    end
         | 
| 58 66 |  | 
| @@ -14,6 +14,7 @@ module Carbon | |
| 14 14 | 
             
                class Index
         | 
| 15 15 | 
             
                  include TSort
         | 
| 16 16 | 
             
                  extend Forwardable
         | 
| 17 | 
            +
                  include Enumerable
         | 
| 17 18 |  | 
| 18 19 | 
             
                  # We can't use these methods because we don't fit the bill - we don't
         | 
| 19 20 | 
             
                  # define a `tsort_each_node`, since we don't need it.  We only use
         | 
| @@ -27,6 +28,8 @@ module Carbon | |
| 27 28 | 
             
                  undef_method :each_strongly_connected_component
         | 
| 28 29 | 
             
                  undef_method :strongly_connected_components
         | 
| 29 30 |  | 
| 31 | 
            +
                  delegate [:each] => :items
         | 
| 32 | 
            +
             | 
| 30 33 | 
             
                  # Initialize the index with the given data.
         | 
| 31 34 | 
             
                  #
         | 
| 32 35 | 
             
                  # @api public
         | 
| @@ -36,95 +39,45 @@ module Carbon | |
| 36 39 | 
             
                  #   completely derived from the index itself; or, rather, what's defined
         | 
| 37 40 | 
             
                  #   on the index.  See {#id}.
         | 
| 38 41 | 
             
                  def initialize(data = {})
         | 
| 39 | 
            -
                    @items =  | 
| 42 | 
            +
                    @items = ::Set.new.merge(data.fetch(:items, []))
         | 
| 43 | 
            +
                    @links = ::Set.new
         | 
| 40 44 | 
             
                    @id = data.fetch(:id) { id }
         | 
| 41 | 
            -
                    mutex
         | 
| 42 45 | 
             
                  end
         | 
| 43 46 |  | 
| 44 | 
            -
                   | 
| 45 | 
            -
                   | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
                  #   true, then the method raises `KeyError`.
         | 
| 51 | 
            -
                  #
         | 
| 52 | 
            -
                  #   @api public
         | 
| 53 | 
            -
                  #   @example Successful fetch.
         | 
| 54 | 
            -
                  #     index.fetch("Carbon::Integer") # => #<Carbon::Concrete::Item::Base>
         | 
| 55 | 
            -
                  #   @example Failed fetch with argument.
         | 
| 56 | 
            -
                  #     index.fetch("Carbon::Foo", false) # => false
         | 
| 57 | 
            -
                  #   @example Failed fetch with block.
         | 
| 58 | 
            -
                  #     index.fetch("Carbon::Foo") { |n| n.sub("F", "B") }
         | 
| 59 | 
            -
                  #       # => "Carbon::Boo"
         | 
| 60 | 
            -
                  #   @example Failed fetch with both.
         | 
| 61 | 
            -
                  #     index.fetch("Carbon::Foo", false) { |n| n.sub("F", "B") }
         | 
| 62 | 
            -
                  #       # => "Carbon::Boo"
         | 
| 63 | 
            -
                  #   @param name [::Object] The key of the item to fetch.
         | 
| 64 | 
            -
                  #   @param default [::Object] The value to return if the key doesn't match
         | 
| 65 | 
            -
                  #     an item and a block wasn't given.
         | 
| 66 | 
            -
                  #   @yield [name] If the key doesn't match an item, the method yields.
         | 
| 67 | 
            -
                  #   @yieldparam name [::Object] The name of the item.
         | 
| 68 | 
            -
                  #   @return [::Object] The item, if the key matched; otherwise, the result
         | 
| 69 | 
            -
                  #     of the block, if given; otherwise, the value of the `default`
         | 
| 70 | 
            -
                  #     parameter.
         | 
| 71 | 
            -
                  #   @raise [KeyError] If the key doesn't match an item and neither a
         | 
| 72 | 
            -
                  #     block nor the second argument were passed.
         | 
| 73 | 
            -
                  def fetch(*options, &block)
         | 
| 74 | 
            -
                    mutex.synchronize { @items.fetch(*options, &block) }
         | 
| 75 | 
            -
                  end
         | 
| 47 | 
            +
                  @canary = ::Object.new
         | 
| 48 | 
            +
                  def fetch(type, default = @canary)
         | 
| 49 | 
            +
                    matching = items.map { |i| [i, i.type.match?(type)] }.select(&:last)
         | 
| 50 | 
            +
                    fail TooManyItemsError, "Multiple items match #{type}" if
         | 
| 51 | 
            +
                      matching.size > 1
         | 
| 52 | 
            +
                    match = matching.first
         | 
| 76 53 |  | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
                  #   @api public
         | 
| 82 | 
            -
                  #   @example Successful retrieval.
         | 
| 83 | 
            -
                  #     index["Carbon::Integer"] # => #<Carbon::Concrete::Item::Base>
         | 
| 84 | 
            -
                  #   @example Unsuccessful retrieval.
         | 
| 85 | 
            -
                  #     index["Carbon::Foo"] # => nil
         | 
| 86 | 
            -
                  #   @param key [::Object] The key of the item to lookup.
         | 
| 87 | 
            -
                  #   @return [::Object] The item, if it exists;
         | 
| 88 | 
            -
                  #   @return [nil] Otherwise.
         | 
| 89 | 
            -
                  def [](*options)
         | 
| 90 | 
            -
                    mutex.synchronize { @items[*options] }
         | 
| 54 | 
            +
                    return match if match
         | 
| 55 | 
            +
                    return yield if block_given?
         | 
| 56 | 
            +
                    return default if default != @canary
         | 
| 57 | 
            +
                    fail ItemNotFoundError, "Could not find an item named #{type}"
         | 
| 91 58 | 
             
                  end
         | 
| 92 59 |  | 
| 93 | 
            -
                   | 
| 94 | 
            -
             | 
| 95 | 
            -
                  #   with it.
         | 
| 96 | 
            -
                  #
         | 
| 97 | 
            -
                  #   @api public
         | 
| 98 | 
            -
                  #   @example Existing key.
         | 
| 99 | 
            -
                  #     index.key?("Carbon::Integer") # => true
         | 
| 100 | 
            -
                  #   @example Non-existant key.
         | 
| 101 | 
            -
                  #     index.key?("Carbon::Foo") # => false
         | 
| 102 | 
            -
                  #   @param key [::Object] The key of the item to check.
         | 
| 103 | 
            -
                  #   @return [::Boolean] Whether the key exists or not.
         | 
| 104 | 
            -
                  def key?(*options)
         | 
| 105 | 
            -
                    mutex.synchronize { @items.key?(*options) }
         | 
| 60 | 
            +
                  def item?(type)
         | 
| 61 | 
            +
                    items.any? { |item| item.type.match?(type) }
         | 
| 106 62 | 
             
                  end
         | 
| 107 63 |  | 
| 108 | 
            -
                   | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
                     | 
| 64 | 
            +
                  def items
         | 
| 65 | 
            +
                    @_current ||= begin
         | 
| 66 | 
            +
                      current = @items.dup
         | 
| 67 | 
            +
                      @links.each do |link|
         | 
| 68 | 
            +
                        current.merge(link.items)
         | 
| 69 | 
            +
                      end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                      current.freeze
         | 
| 72 | 
            +
                    end
         | 
| 117 73 | 
             
                  end
         | 
| 118 74 |  | 
| 119 | 
            -
                   | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
                  # @return [<Item::Base>] The values in the index.
         | 
| 126 | 
            -
                  def values
         | 
| 127 | 
            -
                    mutex.synchornize { @items.values.freeze }
         | 
| 75 | 
            +
                  def to_json
         | 
| 76 | 
            +
                    links, @links = @links, nil
         | 
| 77 | 
            +
                    clear! && id
         | 
| 78 | 
            +
                    value = Oj.dump(self, Concrete::OPTIONS)
         | 
| 79 | 
            +
                    @links = links
         | 
| 80 | 
            +
                    value
         | 
| 128 81 | 
             
                  end
         | 
| 129 82 |  | 
| 130 83 | 
             
                  # The digest of the ID.  This uses the SHA256 base58 digest of the items
         | 
| @@ -133,23 +86,14 @@ module Carbon | |
| 133 86 | 
             
                  #
         | 
| 134 87 | 
             
                  # @api public
         | 
| 135 88 | 
             
                  # @example
         | 
| 136 | 
            -
                  #   index.items # =>  | 
| 89 | 
            +
                  #   index.items # => []
         | 
| 137 90 | 
             
                  #   index.id # => "gjNT5GbSC-81KmUPncw-hzQAGV3GU-eAXafmkMP-Bw2GMHWM"
         | 
| 138 91 | 
             
                  # @return [::String]
         | 
| 139 92 | 
             
                  def id
         | 
| 140 | 
            -
                    @ | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
                  # Therefore, this is not guarenteed to be up to date.
         | 
| 145 | 
            -
                  #
         | 
| 146 | 
            -
                  # @api public
         | 
| 147 | 
            -
                  # @example Items
         | 
| 148 | 
            -
                  #   index.items
         | 
| 149 | 
            -
                  #     # => {"Carbon::Integer" => #<Carbon::Concrete::Item::Base>}
         | 
| 150 | 
            -
                  # @return [{::String => Item::Base}] The items of the index.
         | 
| 151 | 
            -
                  def items
         | 
| 152 | 
            -
                    mutex.synchronize { @items.dup.deep_freeze! }
         | 
| 93 | 
            +
                    @_id ||= begin
         | 
| 94 | 
            +
                      body = (@items.map(&:type).map(&:to_s) + @links.map(&:id)).join("\n")
         | 
| 95 | 
            +
                      Carbon.hash(body)
         | 
| 96 | 
            +
                    end
         | 
| 153 97 | 
             
                  end
         | 
| 154 98 |  | 
| 155 99 | 
             
                  # Adds a defined item to the index.  The item just has to respond to
         | 
| @@ -161,41 +105,18 @@ module Carbon | |
| 161 105 | 
             
                  # @example Adding an item.
         | 
| 162 106 | 
             
                  #   index << item
         | 
| 163 107 | 
             
                  #   index.key?(item.intern) # => true
         | 
| 164 | 
            -
                  # @example Merging an index.
         | 
| 165 | 
            -
                  #   other.is_a?(Carbon::Concrete::Index) # => true
         | 
| 166 | 
            -
                  #   index << other
         | 
| 167 | 
            -
                  #   index.items.keys.to_set <= other.items.keys.to_set
         | 
| 168 | 
            -
                  # @note
         | 
| 169 | 
            -
                  #   If the item is an index instead, it passes it to {#merge} and
         | 
| 170 | 
            -
                  #   returns.  This usage is not recommended for {#add}, but can be
         | 
| 171 | 
            -
                  #   used for {#<<}.
         | 
| 172 108 | 
             
                  # @param item [Concrete::Item::Base] The item to add.
         | 
| 173 109 | 
             
                  # @return [self]
         | 
| 174 110 | 
             
                  def add(item)
         | 
| 175 | 
            -
                     | 
| 176 | 
            -
                     | 
| 177 | 
            -
                      @items[item.intern] = item
         | 
| 178 | 
            -
                      clear!
         | 
| 179 | 
            -
                    end
         | 
| 111 | 
            +
                    @items << item
         | 
| 112 | 
            +
                    clear!
         | 
| 180 113 | 
             
                  end
         | 
| 181 114 |  | 
| 182 115 | 
             
                  alias_method :<<, :add
         | 
| 183 116 |  | 
| 184 | 
            -
                   | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
                  #
         | 
| 188 | 
            -
                  # @api public
         | 
| 189 | 
            -
                  # @example Merging.
         | 
| 190 | 
            -
                  #   index.merge(other)
         | 
| 191 | 
            -
                  #   index.items.keys.to_set <= other.items.keys.to_set
         | 
| 192 | 
            -
                  # @param index [Index] The index to merge.
         | 
| 193 | 
            -
                  # @return [self]
         | 
| 194 | 
            -
                  def merge(index)
         | 
| 195 | 
            -
                    mutex.synchronize do
         | 
| 196 | 
            -
                      @items.merge(index.items)
         | 
| 197 | 
            -
                      clear!
         | 
| 198 | 
            -
                    end
         | 
| 117 | 
            +
                  def link(index)
         | 
| 118 | 
            +
                    @links << index
         | 
| 119 | 
            +
                    clear!
         | 
| 199 120 | 
             
                  end
         | 
| 200 121 |  | 
| 201 122 | 
             
                  # Finalizes the index.  This should only be used when all of the items
         | 
| @@ -207,15 +128,10 @@ module Carbon | |
| 207 128 | 
             
                  #   for this instance of the index.
         | 
| 208 129 | 
             
                  # @return [self]
         | 
| 209 130 | 
             
                  def finalize
         | 
| 210 | 
            -
                     | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
| 215 | 
            -
                      @items = items.freeze
         | 
| 216 | 
            -
                    end
         | 
| 217 | 
            -
             | 
| 218 | 
            -
                    self
         | 
| 131 | 
            +
                    current = @items.dup
         | 
| 132 | 
            +
                    items = ::Set.new(current.map { |item| item.define(self) })
         | 
| 133 | 
            +
                    @items = items.freeze
         | 
| 134 | 
            +
                    clear!
         | 
| 219 135 | 
             
                  end
         | 
| 220 136 |  | 
| 221 137 | 
             
                  # Used only for {#define}.  This maps item "names" to the classes that
         | 
| @@ -280,47 +196,34 @@ module Carbon | |
| 280 196 | 
             
                  #   request.intern # => "Main"
         | 
| 281 197 | 
             
                  #   request.generics # => []
         | 
| 282 198 | 
             
                  #   index.build(request).to_a # => [...]
         | 
| 283 | 
            -
                  # @param item [ | 
| 284 | 
            -
                  #   contains behavior that is required by this method (namely,
         | 
| 285 | 
            -
                  #   {Item::Base#corrected_dependencies}, {Item::Base#intern}, and
         | 
| 286 | 
            -
                  #   {Item::Base#generics}).
         | 
| 199 | 
            +
                  # @param item [Concrete::Type] The type to build.
         | 
| 287 200 | 
             
                  # @return [::Enumerable] The build items, if no block is given.
         | 
| 288 201 | 
             
                  # @return [void] If a block is given.
         | 
| 289 202 | 
             
                  # @yield [dep] Multiple times, each with a dependency.
         | 
| 290 203 | 
             
                  # @yieldparam dep [Request] A request.
         | 
| 291 204 | 
             
                  def build(item)
         | 
| 292 | 
            -
                    mutex.lock
         | 
| 293 205 | 
             
                    fail ArgumentError, "Passed item cannot be generic" if \
         | 
| 294 206 | 
             
                      item.generics.any?
         | 
| 295 207 | 
             
                    return to_enum(:build, item) unless block_given?
         | 
| 296 | 
            -
                    request = Request.new(item.intern, [])
         | 
| 297 208 |  | 
| 298 | 
            -
                    build_from_request( | 
| 299 | 
            -
                  ensure
         | 
| 300 | 
            -
                    mutex.unlock
         | 
| 209 | 
            +
                    build_from_request(item, &Proc.new)
         | 
| 301 210 | 
             
                  end
         | 
| 302 211 |  | 
| 303 212 | 
             
                private
         | 
| 304 213 |  | 
| 305 | 
            -
                  def  | 
| 306 | 
            -
                    @ | 
| 214 | 
            +
                  def clear!
         | 
| 215 | 
            +
                    @_id = @_current = nil
         | 
| 216 | 
            +
                    self
         | 
| 307 217 | 
             
                  end
         | 
| 308 218 |  | 
| 309 | 
            -
                  # rubocop:disable Metrics/MethodLength
         | 
| 310 219 | 
             
                  def build_from_request(request)
         | 
| 311 220 | 
             
                    components = to_enum(:each_strongly_connected_component_from, request)
         | 
| 312 221 | 
             
                    components.each do |group|
         | 
| 313 222 | 
             
                      fail TSort::Cyclic, "cyclic dependencies: #{group.join(', ')}" if \
         | 
| 314 223 | 
             
                        group.size > 1
         | 
| 315 | 
            -
                       | 
| 316 | 
            -
                        mutex.unlock
         | 
| 317 | 
            -
                        yield group.first
         | 
| 318 | 
            -
                      ensure
         | 
| 319 | 
            -
                        mutex.lock
         | 
| 320 | 
            -
                      end
         | 
| 224 | 
            +
                      yield group.first
         | 
| 321 225 | 
             
                    end
         | 
| 322 226 | 
             
                  end
         | 
| 323 | 
            -
                  # rubocop:enable Metrics/MethodLength
         | 
| 324 227 |  | 
| 325 228 | 
             
                  # Iterates over all of the "children" of a node.  This iterates over all
         | 
| 326 229 | 
             
                  # of the corrected dependencies of a node, allowing the TSort module
         | 
| @@ -332,16 +235,7 @@ module Carbon | |
| 332 235 | 
             
                  # @yieldparam request [Request]
         | 
| 333 236 | 
             
                  # @return [void]
         | 
| 334 237 | 
             
                  def tsort_each_child(node, &block)
         | 
| 335 | 
            -
                     | 
| 336 | 
            -
                  end
         | 
| 337 | 
            -
             | 
| 338 | 
            -
                  # Clears the cache, forcing the id to be rebuilt on next call.
         | 
| 339 | 
            -
                  #
         | 
| 340 | 
            -
                  # @api private
         | 
| 341 | 
            -
                  # @return [self]
         | 
| 342 | 
            -
                  def clear!
         | 
| 343 | 
            -
                    @id = nil
         | 
| 344 | 
            -
                    self
         | 
| 238 | 
            +
                    fetch(node).first.corrected_dependencies(node, &block)
         | 
| 345 239 | 
             
                  end
         | 
| 346 240 | 
             
                end
         | 
| 347 241 | 
             
              end
         |