Skip to content

Commit

Permalink
improve graph reachability filtering and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
benweint committed Jun 4, 2024
1 parent acc1b9b commit a119b1d
Show file tree
Hide file tree
Showing 7 changed files with 379 additions and 300 deletions.
4 changes: 0 additions & 4 deletions pkg/commands/testdata/cases/viz_from/expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ digraph {
<TR><TD COLSPAN="3" PORT="main" BGCOLOR="#fbb4ae">object Query</TD></TR>
<TR><TD ROWSPAN="2">fruit</TD><TD COLSPAN="2" PORT="p_fruit">Fruit</TD></TR>
<TR><TD>name</TD><TD PORT="p_fruit_name">String</TD></TR>
<TR><TD ROWSPAN="2">edible</TD><TD COLSPAN="2" PORT="p_edible">Edible</TD></TR>
<TR><TD>name</TD><TD PORT="p_edible_name">String</TD></TR>
<TR><TD ROWSPAN="2">edibles</TD><TD COLSPAN="2" PORT="p_edibles">[Edible!]!</TD></TR>
<TR><TD>filter</TD><TD PORT="p_edibles_filter">Filter</TD></TR>

</TABLE>>]
n_Apple:p_variety -> n_AppleVariety:main
Expand Down
91 changes: 0 additions & 91 deletions pkg/graph/field_filter.go

This file was deleted.

185 changes: 0 additions & 185 deletions pkg/graph/field_filter_test.go

This file was deleted.

55 changes: 35 additions & 20 deletions pkg/graph/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,39 +134,49 @@ func (g *Graph) GetDefinitions() model.DefinitionMap {
}

func (g *Graph) ReachableFrom(roots []*model.NameReference, maxDepth int) *Graph {
var defs model.DefinitionList
for _, node := range g.nodes {
defs = append(defs, node)
}
rootDefs := applyFieldFilters(defs, roots)

seen := model.DefinitionMap{}
seen := referenceSet{}

var traverse func(n *model.Definition, depth int)

traverseField := func(typeName string, f *model.FieldDefinition, depth int) {
key := fieldRef(typeName, f.Name)
if seen[key] {
return
}
seen[key] = true

if maxDepth > 0 && depth > maxDepth {
return
}

for _, arg := range f.Arguments {
argType := arg.Type.Unwrap()
traverse(g.nodes[argType.Name], depth+1)
}

underlyingType := f.Type.Unwrap()
traverse(g.nodes[underlyingType.Name], depth+1)
}

traverse = func(n *model.Definition, depth int) {
if maxDepth > 0 && depth > maxDepth {
return
}
if _, ok := seen[n.Name]; ok {
key := typeRef(n.Name)
if _, ok := seen[key]; ok {
return
}
if n.Kind == ast.Scalar {
return
}

seen[n.Name] = n
seen[key] = true
kind := normalizeKind(n.Kind, g.interfacesAsUnions)

switch kind {
case ast.Object, ast.InputObject:
for _, field := range n.Fields {
for _, arg := range field.Arguments {
argType := arg.Type.Unwrap()
traverse(g.nodes[argType.Name], depth+1)
}

underlyingType := field.Type.Unwrap()
traverse(g.nodes[underlyingType.Name], depth+1)
traverseField(n.Name, field, depth)
}
case ast.Union:
for _, pt := range n.PossibleTypes {
Expand All @@ -175,14 +185,19 @@ func (g *Graph) ReachableFrom(roots []*model.NameReference, maxDepth int) *Graph
}
}

for _, root := range rootDefs {
traverse(root, 1)
for _, root := range roots {
targetType := root.GetTargetType()
if fieldName := root.GetFieldName(); fieldName != "" {
traverseField(targetType.Name, targetType.Fields.Named(fieldName), 1)
} else {
traverse(targetType, 1)
}
}

filteredNodes := model.DefinitionMap{}
for name, node := range g.nodes {
if _, ok := seen[name]; ok {
filteredNodes[name] = node
if seen.includesType(name) {
filteredNodes[name] = seen.filterFields(node)
}
}

Expand Down
Loading

0 comments on commit a119b1d

Please sign in to comment.