Reuse alias tree for discovery and help
This commit is contained in:
@@ -182,3 +182,50 @@ func (resolver *Resolver) ResolveWithProvenance(path commandpath.Path) (commandp
|
||||
origins = nextOrigins
|
||||
}
|
||||
}
|
||||
|
||||
// ProperSourcePrefixes returns distinct nonempty proper prefixes of source paths.
|
||||
// Returned paths are owned by the caller.
|
||||
func (resolver *Resolver) ProperSourcePrefixes() []commandpath.Path {
|
||||
if resolver == nil {
|
||||
return nil
|
||||
}
|
||||
var paths []commandpath.Path
|
||||
for index := 1; index < len(resolver.trie); index++ {
|
||||
node := &resolver.trie[index]
|
||||
if len(node.children) != 0 {
|
||||
paths = append(paths, node.path.Clone())
|
||||
}
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
// Descendants returns owned mappings whose sources are strictly below prefix.
|
||||
func (resolver *Resolver) Descendants(prefix commandpath.Path) []Mapping {
|
||||
if resolver == nil {
|
||||
return nil
|
||||
}
|
||||
index := 0
|
||||
for _, component := range prefix {
|
||||
next, ok := resolver.trie[index].children[component]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
index = next
|
||||
}
|
||||
var mappings []Mapping
|
||||
var visit func(int)
|
||||
visit = func(index int) {
|
||||
node := &resolver.trie[index]
|
||||
if node.mapping >= 0 {
|
||||
mapping := resolver.mappings[node.mapping]
|
||||
mappings = append(mappings, Mapping{Source: mapping.Source.Clone(), Target: mapping.Target.Clone()})
|
||||
}
|
||||
for _, child := range node.children {
|
||||
visit(child)
|
||||
}
|
||||
}
|
||||
for _, child := range resolver.trie[index].children {
|
||||
visit(child)
|
||||
}
|
||||
return mappings
|
||||
}
|
||||
|
||||
@@ -314,3 +314,34 @@ func (machine *Machine) classify(token string) symbol {
|
||||
}
|
||||
return symbol{kind: otherSymbol}
|
||||
}
|
||||
|
||||
func TestResolverSourcePrefixesAndDescendantsAreOwned(t *testing.T) {
|
||||
resolver, err := NewResolver([]Mapping{
|
||||
{Source: commandpath.Path{"a"}, Target: commandpath.Path{"root"}},
|
||||
{Source: commandpath.Path{"a", "b", "one"}, Target: commandpath.Path{"root", "one"}},
|
||||
{Source: commandpath.Path{"a", "b", "two"}, Target: commandpath.Path{"root", "two"}},
|
||||
{Source: commandpath.Path{"other"}, Target: commandpath.Path{"root"}},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
prefixes := resolver.ProperSourcePrefixes()
|
||||
if len(prefixes) != 2 || !prefixes[0].Equal(commandpath.Path{"a"}) || !prefixes[1].Equal(commandpath.Path{"a", "b"}) {
|
||||
t.Fatalf("prefixes = %#v", prefixes)
|
||||
}
|
||||
prefixes[0][0] = "mutated"
|
||||
descendants := resolver.Descendants(commandpath.Path{"a"})
|
||||
if len(descendants) != 2 {
|
||||
t.Fatalf("descendants = %#v", descendants)
|
||||
}
|
||||
for _, mapping := range descendants {
|
||||
if len(mapping.Source) != 3 || mapping.Source[0] != "a" {
|
||||
t.Fatalf("mapping = %#v", mapping)
|
||||
}
|
||||
}
|
||||
descendants[0].Source[0] = "mutated"
|
||||
descendants[0].Target[0] = "mutated"
|
||||
if !resolver.Resolve(commandpath.Path{"a", "b", "one"}).Equal(commandpath.Path{"root", "one"}) || len(resolver.Descendants(commandpath.Path{"missing"})) != 0 {
|
||||
t.Fatal("resolver was mutated or missing branch returned mappings")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user