module I18n::Processes::References
Public Instance Methods
Given a raw usage tree and a tree of reference keys in the data, return 3 trees:
-
Raw references – a subset of the usages tree with keys that are reference key usages.
-
Resolved references – all the used references in their fully resolved form.
-
Reference keys – all the used reference keys.
# File lib/i18n/processes/references.rb, line 9 def process_references(usages, data_refs = merge_reference_trees(data_forest.select_keys { |_, node| node.reference? })) fail ArgumentError, 'usages must be a Data::Tree::Instance' unless usages.is_a?(Data::Tree::Siblings) fail ArgumentError, 'all_references must be a Data::Tree::Instance' unless data_refs.is_a?(Data::Tree::Siblings) raw_refs = empty_forest resolved_refs = empty_forest refs = empty_forest data_refs.key_to_node.each do |ref_key_part, ref_node| usages.each do |usage_node| next unless usage_node.key == ref_key_part if ref_node.leaf? process_leaf!(ref_node, usage_node, raw_refs, resolved_refs, refs) else process_non_leaf!(ref_node, usage_node, raw_refs, resolved_refs, refs) end end end [raw_refs, resolved_refs, refs] end
Private Instance Methods
@param [Hash] ref_data @param [I18n::Processes::Data::Tree::Siblings] new_resolved_refs
# File lib/i18n/processes/references.rb, line 53 def add_occurences!(ref_data, new_resolved_refs) ref_data[:occurrences] ||= [] new_resolved_refs.leaves do |leaf| ref_data[:occurrences].concat(leaf.data[:occurrences] || []) end ref_data[:occurrences].sort_by!(&:path) ref_data[:occurrences].uniq! end
Given a forest of references, merge trees into one tree, ensuring there are no conflicting references. @param roots [I18n::Processes::Data::Tree::Siblings] @return [I18n::Processes::Data::Tree::Siblings]
# File lib/i18n/processes/references.rb, line 77 def merge_reference_trees(roots) roots.inject(empty_forest) do |forest, root| root.keys do |full_key, node| if full_key == node.value.to_s log_warn( "Self-referencing key #{node.full_key(root: false).inspect} in #{node.data[:locale].inspect}" ) end end forest.merge!( root.children, on_leaves_merge: lambda do |node, other| if node.value != other.value log_warn( 'Conflicting references: '\ "#{node.full_key(root: false)} ⮕ #{node.value} in #{node.data[:locale]},"\ " but ⮕ #{other.value} in #{other.data[:locale]}" ) end end ) end end
@param [I18n::Processes::Data::Tree::Node] ref @param [I18n::Processes::Data::Tree::Node] usage @param [I18n::Processes::Data::Tree::Siblings] raw_refs @param [I18n::Processes::Data::Tree::Siblings] resolved_refs @param [I18n::Processes::Data::Tree::Siblings] refs
# File lib/i18n/processes/references.rb, line 36 def process_leaf!(ref, usage, raw_refs, resolved_refs, refs) refs.merge_node!(Data::Tree::Node.new(key: ref.key, data: usage.data)) unless refs.key_to_node.key?(ref.key) new_resolved_refs = Data::Tree::Siblings.from_key_names([ref.value.to_s]) do |_, resolved_node| raw_refs.merge_node!(usage) if usage.leaf? resolved_node.data.merge!(usage.data) else resolved_node.children = usage.children end resolved_node.leaves { |node| node.data[:ref_info] = [ref.full_key, ref.value.to_s] } end add_occurences! refs.key_to_node[ref.key].data, new_resolved_refs resolved_refs.merge! new_resolved_refs end
@param [I18n::Processes::Data::Tree::Node] ref @param [I18n::Processes::Data::Tree::Node] usage @param [I18n::Processes::Data::Tree::Siblings] raw_refs @param [I18n::Processes::Data::Tree::Siblings] resolved_refs @param [I18n::Processes::Data::Tree::Siblings] refs
# File lib/i18n/processes/references.rb, line 67 def process_non_leaf!(ref, usage, raw_refs, resolved_refs, refs) child_raw_refs, child_resolved_refs, child_refs = process_references(usage.children, ref.children) raw_refs.merge_node! Data::Tree::Node.new(key: ref.key, children: child_raw_refs) unless child_raw_refs.empty? resolved_refs.merge! child_resolved_refs refs.merge_node! Data::Tree::Node.new(key: ref.key, children: child_refs) unless child_refs.empty? end