blob: 85074c52227cbf287aaddf276ab760a7fd46e7b9 [file] [log] [blame]
// Copyright (C) 2016 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 annotate
import (
"fmt"
"android.googlesource.com/platform/tools/gpu/api/snippets"
)
// container represents the nested structure of a container type such
// as Map, Array and Slice. It is also used for pointer, where Key is
// ignored.
type container struct {
// Map, Array, Slice
self *Location
key *Location
elem *Location
}
var _ Nested = &container{}
// newContainer creates a new container nested structure with a new location
// (a temporary). To create a container at an existing location use
// (*Location).newContainer()
func newContainer() *container {
l := &Location{}
return l.newContainer()
}
// Elem returns the equivalence set leader for an element of the collection.
func (c *container) Elem() *Location {
return c.elem.leader()
}
// Key returns the equivalence set leader for the key of the collection.
func (c *container) Key() *Location {
return c.key.leader()
}
// leader returns the leader of the equivalence set for the container.
func (c *container) leader() *Location { return c.self.leader() }
// isNestedEmpty returns true if the container has no interesting information.
func (c *container) isNestedEmpty() bool {
return c.elem.leader().isEmpty() && c.key.leader().isEmpty()
}
func (c *container) String() string {
return fmt.Sprintf("container(key: %s, elem: %s)", c.key, c.elem)
}
// getSnippets returns the snippets for this container's equivalence set.
func (c *container) getSnippets() snippets.Snippets {
return c.leader().getSnippets()
}
// merge merges nested into the receiver. It is an error if nested is
// not a container or if the structure of key or element does not correspond.
func (c *container) merge(nested Nested) error {
if cc, ok := nested.(*container); !ok {
return fmt.Errorf("expected container got %T", nested)
} else {
if err := alias(c.key, cc.key); err != nil {
return fmt.Errorf("failed alias of container key %v", err)
}
if err := alias(c.elem, cc.elem); err != nil {
return fmt.Errorf("failed alias of container element %v", err)
}
}
return nil
}
// getTable traverses the container structure and populates table with
// snippets. Each entry is associated with the path which leads to them.
func (c *container) getTable(path snippets.Pathway, table *SnippetTable) {
c.elem.leader().getTable(snippets.Elem(path), table)
c.key.leader().getTable(snippets.Key(path), table)
}