Class: Parlour::ConflictResolver
- Inherits:
-
Object
- Object
- Parlour::ConflictResolver
- Extended by:
- T::Sig
- Defined in:
- lib/parlour/conflict_resolver.rb
Overview
Responsible for resolving conflicts (that is, multiple definitions with the same name) between objects defined in the same namespace.
Instance Method Summary collapse
-
#resolve_conflicts(namespace) {|message, candidates| ... } ⇒ void
Given a namespace, attempts to automatically resolve conflicts in the namespace’s definitions.
Instance Method Details
#resolve_conflicts(namespace) {|message, candidates| ... } ⇒ void
This method returns an undefined value.
Given a namespace, attempts to automatically resolve conflicts in the namespace’s definitions. (A conflict occurs when multiple objects share the same name.)
All children of the given namespace which are also namespaces are processed recursively, so passing RbiGenerator#root will eliminate all conflicts in the entire object tree.
If automatic resolution is not possible, the block passed to this method is invoked and passed two arguments: a message on what the conflict is, and an array of candidate objects. The block should return one of these candidate objects, which will be kept, and all other definitions are deleted. Alternatively, the block may return nil, which will delete all definitions. The block may be invoked many times from one call to #resolve_conflicts, one for each unresolvable conflict.
41 42 43 44 45 46 47 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 75 76 77 78 79 80 81 82 83 |
# File 'lib/parlour/conflict_resolver.rb', line 41 def resolve_conflicts(namespace, &resolver) # Check for multiple definitions with the same name grouped_by_name_children = namespace.children.group_by(&:name) grouped_by_name_children.each do |name, children| if children.length > 1 # We found a conflict! # Start by removing all the conflicting items children.each do |c| namespace.children.delete(c) end # We can only try to resolve automatically if they're all the same # type of object, so check that first children_type = single_type_of_array(children) unless children_type # The types aren't the same, so ask the resovler what to do, and # insert that (if not nil) choice = resolver.call("Different kinds of definition for the same name", children) namespace.children << choice if choice next end # Can the children merge themselves automatically? If so, let them first, *rest = children first, rest = T.must(first), T.must(rest) if T.must(first).mergeable?(T.must(rest)) first.merge_into_self(rest) namespace.children << first next end # I give up! Let it be resolved manually somehow choice = resolver.call("Can't automatically resolve", children) namespace.children << choice if choice end end # Recurse to child namespaces namespace.children.each do |child| resolve_conflicts(child, &resolver) if RbiGenerator::Namespace === child end end |