Class: Expressir::Model::Indexes::ReferenceIndex

Inherits:
Object
  • Object
show all
Defined in:
lib/expressir/model/indexes/reference_index.rb

Overview

Index for cross-schema reference tracking Maintains USE FROM, REFERENCE FROM relationships and dependency graphs

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(schemas = []) ⇒ ReferenceIndex

Initialize a new reference index

Parameters:



13
14
15
16
17
18
# File 'lib/expressir/model/indexes/reference_index.rb', line 13

def initialize(schemas = [])
  @use_from = {}
  @reference_from = {}
  @dependencies = {}
  build(schemas) unless schemas.empty?
end

Instance Attribute Details

#dependenciesObject (readonly)

Returns the value of attribute dependencies.



9
10
11
# File 'lib/expressir/model/indexes/reference_index.rb', line 9

def dependencies
  @dependencies
end

#reference_fromObject (readonly)

Returns the value of attribute reference_from.



9
10
11
# File 'lib/expressir/model/indexes/reference_index.rb', line 9

def reference_from
  @reference_from
end

#use_fromObject (readonly)

Returns the value of attribute use_from.



9
10
11
# File 'lib/expressir/model/indexes/reference_index.rb', line 9

def use_from
  @use_from
end

Instance Method Details

#build(schemas) ⇒ void

This method returns an undefined value.

Build indexes from schemas

Parameters:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/expressir/model/indexes/reference_index.rb', line 23

def build(schemas)
  @use_from = {}
  @reference_from = {}
  @dependencies = {}

  schemas.each do |schema|
    schema_id = schema.id.safe_downcase

    # Initialize schema entries even if there are no interfaces
    @use_from[schema_id] = []
    @reference_from[schema_id] = []

    next unless schema.interfaces

    schema.interfaces.each do |interface|
      referenced_schema = interface.schema.id.safe_downcase
      items = interface.items.map { |item| item.ref.id }

      if interface.kind == Declarations::Interface::USE
        @use_from[schema_id] << {
          schema: referenced_schema,
          items: items,
        }
      elsif interface.kind == Declarations::Interface::REFERENCE
        @reference_from[schema_id] << {
          schema: referenced_schema,
          items: items,
        }
      end

      @dependencies[schema_id] ||= Set.new
      @dependencies[schema_id] << referenced_schema
    end
  end
end

#detect_circular_dependenciesArray<Array<String>>

Detect circular dependencies in schema references

Returns:

  • (Array<Array<String>>)

    List of circular dependency cycles



82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/expressir/model/indexes/reference_index.rb', line 82

def detect_circular_dependencies
  cycles = []
  visited = Set.new
  rec_stack = Set.new

  @dependencies.each_key do |schema_id|
    next if visited.include?(schema_id)

    path = []
    detect_cycle(schema_id, visited, rec_stack, path, cycles)
  end

  cycles
end

#empty?Boolean

Check if index is empty

Returns:

  • (Boolean)

    True if no references indexed



99
100
101
# File 'lib/expressir/model/indexes/reference_index.rb', line 99

def empty?
  @dependencies.empty?
end

#reference_from_countInteger

Count total REFERENCE FROM references

Returns:

  • (Integer)

    Total REFERENCE FROM references



111
112
113
# File 'lib/expressir/model/indexes/reference_index.rb', line 111

def reference_from_count
  @reference_from.values.sum(&:size)
end

#reference_references(schema) ⇒ Array<Hash>

Get REFERENCE FROM references for a schema

Parameters:

  • schema (String)

    Schema name

Returns:

  • (Array<Hash>)

    List of REFERENCE FROM references



69
70
71
# File 'lib/expressir/model/indexes/reference_index.rb', line 69

def reference_references(schema)
  @reference_from[schema.safe_downcase] || []
end

#schema_dependencies(schema) ⇒ Set<String>

Get all dependencies for a schema

Parameters:

  • schema (String)

    Schema name

Returns:

  • (Set<String>)

    Set of dependent schema names



76
77
78
# File 'lib/expressir/model/indexes/reference_index.rb', line 76

def schema_dependencies(schema)
  @dependencies[schema.safe_downcase] || Set.new
end

#use_from_countInteger

Count total USE FROM references

Returns:

  • (Integer)

    Total USE FROM references



105
106
107
# File 'lib/expressir/model/indexes/reference_index.rb', line 105

def use_from_count
  @use_from.values.sum(&:size)
end

#use_references(schema) ⇒ Array<Hash>

Get USE FROM references for a schema

Parameters:

  • schema (String)

    Schema name

Returns:

  • (Array<Hash>)

    List of USE FROM references



62
63
64
# File 'lib/expressir/model/indexes/reference_index.rb', line 62

def use_references(schema)
  @use_from[schema.safe_downcase] || []
end