From 209d54a89341e566723f5c3fbc8560ebe941941f Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Fri, 3 Jul 2015 12:21:13 +0100 Subject: Add path.Flatten to flatten a path chain into a slice. Add String() methods to each of the paths so we get pretty error messages. Fix Atoms.Path(). Change-Id: I8d555de52ebd3750f2b38563cb1474645f6ff4e1 --- service/path/README.md | 118 +++++++++++++++++++++++++++++++++++++++++-- service/path/array_index.go | 8 +++ service/path/atom.go | 8 +++ service/path/atoms.go | 10 +++- service/path/capture.go | 8 +++ service/path/field.go | 8 +++ service/path/flatten.go | 31 ++++++++++++ service/path/flatten_test.go | 34 +++++++++++++ service/path/map_index.go | 8 +++ service/path/path.go | 11 ++-- service/path/state.go | 9 ++++ 11 files changed, 242 insertions(+), 11 deletions(-) create mode 100644 service/path/flatten.go create mode 100644 service/path/flatten_test.go (limited to 'service') diff --git a/service/path/README.md b/service/path/README.md index 8f01850c2..2b9b01af7 100644 --- a/service/path/README.md +++ b/service/path/README.md @@ -10,6 +10,14 @@ Package path contains types that represent data references. var Namespace = registry.NewNamespace() ``` +#### func Flatten + +```go +func Flatten(p Path) []Path +``` +Flatten returns the path p flattened into a list of path nodes, starting with +the root and ending with p. + #### type ArrayIndex ```go @@ -29,6 +37,13 @@ func (n *ArrayIndex) ArrayIndex(index uint64) Value ``` ArrayIndex implements the Value interface. +#### func (*ArrayIndex) Base + +```go +func (n *ArrayIndex) Base() Path +``` +Base implements the Path interface, returning the path to the array. + #### func (*ArrayIndex) Class ```go @@ -56,6 +71,13 @@ func (n *ArrayIndex) Path() string ``` Path implements the Path interface. +#### func (*ArrayIndex) String + +```go +func (n *ArrayIndex) String() string +``` +String returns the string representation of the path. + #### type Atom ```go @@ -75,6 +97,13 @@ func (n *Atom) ArrayIndex(index uint64) Value ``` ArrayIndex implements the Value interface. +#### func (*Atom) Base + +```go +func (n *Atom) Base() Path +``` +Base implements the Path interface, returning the path to the atom list. + #### func (*Atom) Class ```go @@ -109,6 +138,13 @@ func (n *Atom) StateAfter() *State ``` StateAfter returns the path to the state immediately following this atom. +#### func (*Atom) String + +```go +func (n *Atom) String() string +``` +String returns the string representation of the path. + #### type Atoms ```go @@ -120,6 +156,13 @@ type Atoms struct { Atoms is a path that refers to the full list of atoms in a capture. +#### func (*Atoms) Base + +```go +func (n *Atoms) Base() Path +``` +Base implements the Path interface, returning the path to the capture. + #### func (*Atoms) Class ```go @@ -140,6 +183,13 @@ func (n *Atoms) Path() string ``` Path implements the Path interface. +#### func (*Atoms) String + +```go +func (n *Atoms) String() string +``` +String returns the string representation of the path. + #### type Capture ```go @@ -158,6 +208,13 @@ func (c *Capture) Atoms() *Atoms ``` Atoms returns the path to the full list of atoms in the capture. +#### func (*Capture) Base + +```go +func (c *Capture) Base() Path +``` +Base implements the Path interface, returning nil as this is a root. + #### func (*Capture) Class ```go @@ -171,6 +228,13 @@ func (c *Capture) Path() string ``` Path implements the Path interface. +#### func (*Capture) String + +```go +func (c *Capture) String() string +``` +String returns the string representation of the path. + #### type Field ```go @@ -190,6 +254,13 @@ func (n *Field) ArrayIndex(index uint64) Value ``` ArrayIndex implements the Value interface. +#### func (*Field) Base + +```go +func (n *Field) Base() Path +``` +Base implements the Path interface, returning the path to the struct. + #### func (*Field) Class ```go @@ -217,6 +288,13 @@ func (n *Field) Path() string ``` Path implements the Path interface. +#### func (*Field) String + +```go +func (n *Field) String() string +``` +String returns the string representation of the path. + #### type MapIndex ```go @@ -236,6 +314,13 @@ func (n *MapIndex) ArrayIndex(index uint64) Value ``` ArrayIndex implements the Value interface. +#### func (*MapIndex) Base + +```go +func (n *MapIndex) Base() Path +``` +Base implements the Path interface, returning the path to the map. + #### func (*MapIndex) Class ```go @@ -263,6 +348,13 @@ func (n *MapIndex) Path() string ``` Path implements the Path interface. +#### func (*MapIndex) String + +```go +func (n *MapIndex) String() string +``` +String returns the string representation of the path. + #### type Path ```go @@ -272,6 +364,10 @@ type Path interface { // Path returns the string representation of the path. // The returned string must be consistent for equal paths. Path() string + + // Base returns the path that this path derives from. + // If this path is a root, then Base returns nil. + Base() Path } ``` @@ -297,6 +393,14 @@ func (n *State) ArrayIndex(index uint64) Value ``` ArrayIndex implements the Value interface. +#### func (*State) Base + +```go +func (n *State) Base() Path +``` +Base implements the Path interface, returning the path to the atom the state is +after. + #### func (*State) Class ```go @@ -324,15 +428,19 @@ func (n *State) Path() string ``` Path implements the Path interface. +#### func (*State) String + +```go +func (n *State) String() string +``` +String returns the string representation of the path. + #### type Value ```go type Value interface { - binary.Object - - // Path returns the string representation of the path. - // The returned string must be consistent for equal paths. - Path() string + // Value extends the Path interface. + Path // Field returns the path to the field value with the specified name on the // struct object represented by this path. diff --git a/service/path/array_index.go b/service/path/array_index.go index 1cff74061..fb7f6c55f 100644 --- a/service/path/array_index.go +++ b/service/path/array_index.go @@ -27,11 +27,19 @@ type ArrayIndex struct { Index uint64 // The index of the element in the array. } +// String returns the string representation of the path. +func (n *ArrayIndex) String() string { return n.Path() } + // Path implements the Path interface. func (n *ArrayIndex) Path() string { return fmt.Sprintf("%v[%d]", n.Array, n.Index) } +// Base implements the Path interface, returning the path to the array. +func (n *ArrayIndex) Base() Path { + return n.Array +} + // Field implements the Value interface. func (n *ArrayIndex) Field(name string) Value { return &Field{Struct: n, Name: name} diff --git a/service/path/atom.go b/service/path/atom.go index b87080347..db210b518 100644 --- a/service/path/atom.go +++ b/service/path/atom.go @@ -27,11 +27,19 @@ type Atom struct { Index uint64 // The index of the atom in the array. } +// String returns the string representation of the path. +func (n *Atom) String() string { return n.Path() } + // Path implements the Path interface. func (n *Atom) Path() string { return fmt.Sprintf("%v[%d]", n.Atoms, n.Index) } +// Base implements the Path interface, returning the path to the atom list. +func (n *Atom) Base() Path { + return n.Atoms +} + // Field implements the Value interface. func (n *Atom) Field(name string) Value { return &Field{Struct: n, Name: name} diff --git a/service/path/atoms.go b/service/path/atoms.go index 5b73ef773..7dc66efb9 100644 --- a/service/path/atoms.go +++ b/service/path/atoms.go @@ -26,9 +26,17 @@ type Atoms struct { Capture *Capture // The path to the capture containing the atoms. } +// String returns the string representation of the path. +func (n *Atoms) String() string { return n.Path() } + // Path implements the Path interface. func (n *Atoms) Path() string { - return fmt.Sprintf("%v.Atom(%d)", n.Capture, n.Index) + return fmt.Sprintf("%v.Atoms", n.Capture) +} + +// Base implements the Path interface, returning the path to the capture. +func (n *Atoms) Base() Path { + return n.Capture } // Index returns the path to the i'th atom in the atom list. diff --git a/service/path/capture.go b/service/path/capture.go index d58270841..576907396 100644 --- a/service/path/capture.go +++ b/service/path/capture.go @@ -26,11 +26,19 @@ type Capture struct { ID binary.ID // The capture's unique identifier. } +// String returns the string representation of the path. +func (c *Capture) String() string { return c.Path() } + // Path implements the Path interface. func (c *Capture) Path() string { return fmt.Sprintf("Capture(%v)", c.ID) } +// Base implements the Path interface, returning nil as this is a root. +func (c *Capture) Base() Path { + return nil +} + // Atoms returns the path to the full list of atoms in the capture. func (c *Capture) Atoms() *Atoms { return &Atoms{Capture: c} diff --git a/service/path/field.go b/service/path/field.go index b650aec69..97fe36057 100644 --- a/service/path/field.go +++ b/service/path/field.go @@ -27,11 +27,19 @@ type Field struct { Name string // The name of the field. } +// String returns the string representation of the path. +func (n *Field) String() string { return n.Path() } + // Path implements the Path interface. func (n *Field) Path() string { return fmt.Sprintf("%v.%s", n.Struct, n.Name) } +// Base implements the Path interface, returning the path to the struct. +func (n *Field) Base() Path { + return n.Struct +} + // Field implements the Value interface. func (n *Field) Field(name string) Value { return &Field{Struct: n, Name: name} diff --git a/service/path/flatten.go b/service/path/flatten.go new file mode 100644 index 000000000..45f292f3d --- /dev/null +++ b/service/path/flatten.go @@ -0,0 +1,31 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package path + +// Flatten returns the path p flattened into a list of path nodes, starting with +// the root and ending with p. +func Flatten(p Path) []Path { + l := []Path{} + for p != nil { + l = append(l, p) + p = p.Base() + } + // l is backwards, reverse. + for i, c, m := 0, len(l), len(l)/2; i < m; i++ { + j := c - i - 1 + l[i], l[j] = l[j], l[i] + } + return l +} diff --git a/service/path/flatten_test.go b/service/path/flatten_test.go new file mode 100644 index 000000000..8247651d8 --- /dev/null +++ b/service/path/flatten_test.go @@ -0,0 +1,34 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package path + +import ( + "testing" + + "android.googlesource.com/platform/tools/gpu/check" +) + +func TestFlatten(t *testing.T) { + a := &Capture{} + b := a.Atoms() + c := b.Index(10) + d := c.StateAfter() + e := d.Field("x") + f := e.ArrayIndex(1) + g := f.MapIndex(20) + + check.SlicesEqual(t, Flatten(f), []Path{a, b, c, d, e, f}) // Even + check.SlicesEqual(t, Flatten(g), []Path{a, b, c, d, e, f, g}) // Odd +} diff --git a/service/path/map_index.go b/service/path/map_index.go index f19b75fdf..219b28329 100644 --- a/service/path/map_index.go +++ b/service/path/map_index.go @@ -27,11 +27,19 @@ type MapIndex struct { Key interface{} // The key to the value in the map. } +// String returns the string representation of the path. +func (n *MapIndex) String() string { return n.Path() } + // Path implements the Path interface. func (n *MapIndex) Path() string { return fmt.Sprintf("%v[%v]", n.Map, n.Key) } +// Base implements the Path interface, returning the path to the map. +func (n *MapIndex) Base() Path { + return n.Map +} + // Field implements the Value interface. func (n *MapIndex) Field(name string) Value { return &Field{Struct: n, Name: name} diff --git a/service/path/path.go b/service/path/path.go index c7773d12c..3b9ed6137 100644 --- a/service/path/path.go +++ b/service/path/path.go @@ -27,6 +27,10 @@ type Path interface { // Path returns the string representation of the path. // The returned string must be consistent for equal paths. Path() string + + // Base returns the path that this path derives from. + // If this path is a root, then Base returns nil. + Base() Path } // Value is the expanded Path interface for types that represent a reference to @@ -34,11 +38,8 @@ type Path interface { // The value referenced by this path may be a struct, array, slice, map or POD // type. type Value interface { - binary.Object - - // Path returns the string representation of the path. - // The returned string must be consistent for equal paths. - Path() string + // Value extends the Path interface. + Path // Field returns the path to the field value with the specified name on the // struct object represented by this path. diff --git a/service/path/state.go b/service/path/state.go index ffb1524bb..77d5e5d2b 100644 --- a/service/path/state.go +++ b/service/path/state.go @@ -26,11 +26,20 @@ type State struct { After *Atom // The path to the atom the state immediately follows. } +// String returns the string representation of the path. +func (n *State) String() string { return n.Path() } + // Path implements the Path interface. func (n *State) Path() string { return fmt.Sprintf("State(After: %v)", n.After) } +// Base implements the Path interface, returning the path to the atom the state +// is after. +func (n *State) Base() Path { + return n.After +} + // Field implements the Value interface. func (n *State) Field(name string) Value { return &Field{Struct: n, Name: name} -- cgit v1.2.3