Class: Ryac::SiteBucketMapping
- Inherits:
-
Object
- Object
- Ryac::SiteBucketMapping
- Defined in:
- lib/ryac/analysis/site_bucket_mapping.rb,
sig/ryac/analysis/site_bucket_mapping.rbs
Overview
One (cpath, name) → sites table for the sigil families: instance and class variables differ only in their sigil, and a name of sigil + one character is already minimal.
Buckets merge along inheritance, and the merge records an alias so a site added afterwards lands in the merged bucket instead of silently resurrecting the child's. After assign_short_names the table is sealed: anything arriving later would miss renaming, so the phase that got its order wrong fails loudly instead.
Instance Method Summary collapse
- #add_site(cpath, name, node) ⇒ void
- #assign_short_names ⇒ void
- #check_open!(action) ⇒ void
- #each_canonical_cpath {|arg0| ... } ⇒ void
- #exclude_cpath(cpath) ⇒ void
-
#initialize(prefix:) ⇒ SiteBucketMapping
constructor
A new instance of SiteBucketMapping.
- #merge_with_ancestor(child_cpath, ancestor_cpath) ⇒ void
- #node_mapping ⇒ Hash[[Integer, Integer], String]
- #reserve_name(cpath, short_name) ⇒ void
- #resolve_canonical(cpath) ⇒ Array[Symbol]
Constructor Details
#initialize(prefix:) ⇒ SiteBucketMapping
Returns a new instance of SiteBucketMapping.
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 14 def initialize(prefix:) @prefix = prefix @kept_name_max = prefix.size + 1 @buckets = {} @cpath_to_canonical = {} @excluded_cpaths = Set.new @reserved_names = {} @node_short_names = {} @frozen = false end |
Instance Method Details
#add_site(cpath, name, node) ⇒ void
This method returns an undefined value.
25 26 27 28 29 30 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 25 def add_site(cpath, name, node) check_open!('site added') canonical = resolve_canonical(cpath) @buckets[canonical] ||= {} (@buckets[canonical][name] ||= []) << node end |
#assign_short_names ⇒ void
This method returns an undefined value.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 76 def assign_short_names @buckets.each do |cpath, names| next if @excluded_cpaths.include?(cpath) existing_names = Set.new names.each_key do |name| existing_names << name.to_s if name.to_s.size <= @kept_name_max end reserved = @reserved_names[cpath] existing_names.merge(reserved) if reserved generator = NameGenerator.new(existing_names, prefix: @prefix) sorted = names.sort_by do |name, nodes| -(name.to_s.size * nodes.size) end sorted.each do |name, nodes| next if name.to_s.size <= @kept_name_max short_name = generator.next_name savings = (name.to_s.size - short_name.size) * nodes.size next unless savings > 0 nodes.each { |n| @node_short_names[AstUtils.location_key(n)] = short_name } end end @frozen = true end |
#check_open!(action) ⇒ void
This method returns an undefined value.
111 112 113 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 111 def check_open!(action) raise InternalError, "#{@prefix}-mapping: #{action} after assign_short_names" if @frozen end |
#each_canonical_cpath {|arg0| ... } ⇒ void
This method returns an undefined value.
44 45 46 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 44 def each_canonical_cpath(&block) @buckets.each_key(&block) end |
#exclude_cpath(cpath) ⇒ void
This method returns an undefined value.
32 33 34 35 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 32 def exclude_cpath(cpath) check_open!('cpath excluded') @excluded_cpaths << resolve_canonical(cpath) end |
#merge_with_ancestor(child_cpath, ancestor_cpath) ⇒ void
This method returns an undefined value.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 48 def merge_with_ancestor(child_cpath, ancestor_cpath) check_open!('merge') child_canonical = resolve_canonical(child_cpath) ancestor_canonical = resolve_canonical(ancestor_cpath) return if child_canonical == ancestor_canonical return unless @buckets.key?(ancestor_canonical) child_entry = @buckets[child_canonical] return unless child_entry # Recorded before the sites move: from here on, a site added for the # child cpath belongs to the merged bucket. @cpath_to_canonical[child_canonical] = ancestor_canonical ancestor_entry = @buckets[ancestor_canonical] child_entry.keys.each do |name| child_nodes = child_entry.delete(name) next unless child_nodes if ancestor_entry.key?(name) ancestor_entry[name].concat(child_nodes) else ancestor_entry[name] = child_nodes end end @buckets.delete(child_canonical) if child_entry.none? end |
#node_mapping ⇒ Hash[[Integer, Integer], String]
105 106 107 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 105 def node_mapping @node_short_names.dup end |
#reserve_name(cpath, short_name) ⇒ void
This method returns an undefined value.
37 38 39 40 41 42 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 37 def reserve_name(cpath, short_name) check_open!('name reserved') canonical = resolve_canonical(cpath) @reserved_names[canonical] ||= Set.new @reserved_names[canonical] << short_name end |
#resolve_canonical(cpath) ⇒ Array[Symbol]
115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/ryac/analysis/site_bucket_mapping.rb', line 115 def resolve_canonical(cpath) return cpath unless @cpath_to_canonical.key?(cpath) current = cpath seen = Set.new while @cpath_to_canonical.key?(current) && !seen.include?(current) seen << current current = @cpath_to_canonical[current] end current end |