Skip to content

Commit

Permalink
Helpers for accessing unknown state information (#781)
Browse files Browse the repository at this point in the history
  • Loading branch information
TristonianJones committed Jul 19, 2023
1 parent 15d896d commit e517cf5
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 3 deletions.
36 changes: 36 additions & 0 deletions common/types/unknown.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"math"
"reflect"
"sort"
"strings"
"unicode"

Expand Down Expand Up @@ -160,6 +161,26 @@ func NewUnknown(id int64, attr *AttributeTrail) *Unknown {
}
}

// IDs returns the set of unknown expression ids contained by this value.
//
// Numeric identifiers are guaranteed to be in sorted order.
func (u *Unknown) IDs() []int64 {
ids := make(int64Slice, len(u.attributeTrails))
i := 0
for id := range u.attributeTrails {
ids[i] = id
i++
}
ids.Sort()
return ids
}

// GetAttributeTrails returns the attribute trails, if present, missing for a given expression id.
func (u *Unknown) GetAttributeTrails(id int64) ([]*AttributeTrail, bool) {
trails, found := u.attributeTrails[id]
return trails, found
}

// Contains returns true if the input unknown is a subset of the current unknown.
func (u *Unknown) Contains(other *Unknown) bool {
for id, otherTrails := range other.attributeTrails {
Expand Down Expand Up @@ -288,3 +309,18 @@ func MergeUnknowns(unk1, unk2 *Unknown) *Unknown {
}
return out
}

// int64Slice is an implementation of the sort.Interface
type int64Slice []int64

// Len returns the number of elements in the slice.
func (x int64Slice) Len() int { return len(x) }

// Less indicates whether the value at index i is less than the value at index j.
func (x int64Slice) Less(i, j int) bool { return x[i] < x[j] }

// Swap swaps the values at indices i and j in place.
func (x int64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }

// Sort is a convenience method: x.Sort() calls Sort(x).
func (x int64Slice) Sort() { sort.Sort(x) }
67 changes: 64 additions & 3 deletions common/types/unknown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package types
import (
"fmt"
"math"
"reflect"
"strings"
"testing"

Expand Down Expand Up @@ -228,6 +229,68 @@ func TestUnknownContains(t *testing.T) {
}
}

func TestUnknownIDs(t *testing.T) {
tests := []struct {
unk *Unknown
ids []int64
attrs []string
}{
{
unk: NewUnknown(1, nil),
ids: []int64{1},
attrs: []string{"<unspecified>"},
},
{
unk: NewUnknown(2, QualifyAttribute[bool](NewAttributeTrail("a"), true)),
ids: []int64{2},
attrs: []string{"a[true]"},
},
{
unk: NewUnknown(3, QualifyAttribute[string](NewAttributeTrail("a"), "b")),
ids: []int64{3},
attrs: []string{"a.b"},
},
{
unk: NewUnknown(4, QualifyAttribute[string](NewAttributeTrail("a"), "c")),
ids: []int64{4},
attrs: []string{"a.c"},
},
{
unk: MergeUnknowns(
NewUnknown(4, QualifyAttribute[string](NewAttributeTrail("a"), "b")),
NewUnknown(3, QualifyAttribute[bool](NewAttributeTrail("a"), true)),
),
ids: []int64{3, 4},
attrs: []string{"a[true]", "a.b"},
},
}
for i, tst := range tests {
tc := tst
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
ids := tc.unk.IDs()
if !reflect.DeepEqual(ids, tc.ids) {
t.Errorf("%v.IDs() got %v, wanted %v", tc.unk, ids, tc.ids)
}
attrs := make([]string, len(ids))
idx := 0
for _, id := range ids {
trails, found := tc.unk.GetAttributeTrails(id)
if !found {
t.Fatalf("GetAttributeTrails(%d) not found", id)
}
if len(trails) != 1 {
t.Fatalf("GetAttributeTrails(%d) got %d trails, wanted 1", id, len(trails))
}
attrs[idx] = trails[0].String()
idx++
}
if !reflect.DeepEqual(attrs, tc.attrs) {
t.Errorf("%v.GetAttributeTrails() got %v, wanted %v", tc.unk, attrs, tc.attrs)
}
})
}
}

func TestUnknownString(t *testing.T) {
tests := []struct {
unk *Unknown
Expand Down Expand Up @@ -340,7 +403,5 @@ func TestMaybeMergeUnknowns(t *testing.T) {

func newUnk(t *testing.T, id int64, varName string) *Unknown {
t.Helper()
attr := NewAttributeTrail(varName)
unk := NewUnknown(id, attr)
return unk
return NewUnknown(id, NewAttributeTrail(varName))
}

0 comments on commit e517cf5

Please sign in to comment.