Merge changes from topic "soong-namespaces" am: 73c2099534
am: 40573a7456
am: 0b97da65fe
Change-Id: I43e1f9844414ce329e6dd87c25267fe4f12387a4
This commit is contained in:
@@ -22,7 +22,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
)
|
)
|
||||||
@@ -66,6 +65,15 @@ func (s *sortedNamespaces) sortedItems() []*Namespace {
|
|||||||
return s.items
|
return s.items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *sortedNamespaces) index(namespace *Namespace) int {
|
||||||
|
for i, candidate := range s.sortedItems() {
|
||||||
|
if namespace == candidate {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
// A NameResolver implements blueprint.NameInterface, and implements the logic to
|
// A NameResolver implements blueprint.NameInterface, and implements the logic to
|
||||||
// find a module from namespaces based on a query string.
|
// find a module from namespaces based on a query string.
|
||||||
// A query string can be a module name or can be be "//namespace_path:module_path"
|
// A query string can be a module name or can be be "//namespace_path:module_path"
|
||||||
@@ -73,7 +81,7 @@ type NameResolver struct {
|
|||||||
rootNamespace *Namespace
|
rootNamespace *Namespace
|
||||||
|
|
||||||
// id counter for atomic.AddInt32
|
// id counter for atomic.AddInt32
|
||||||
numNamespaces int32
|
nextNamespaceId int32
|
||||||
|
|
||||||
// All namespaces, without duplicates.
|
// All namespaces, without duplicates.
|
||||||
sortedNamespaces sortedNamespaces
|
sortedNamespaces sortedNamespaces
|
||||||
@@ -104,14 +112,6 @@ func (r *NameResolver) newNamespace(path string) *Namespace {
|
|||||||
|
|
||||||
namespace.exportToKati = r.namespaceExportFilter(namespace)
|
namespace.exportToKati = r.namespaceExportFilter(namespace)
|
||||||
|
|
||||||
nextId := atomic.AddInt32(&r.numNamespaces, 1)
|
|
||||||
id := nextId - 1
|
|
||||||
stringId := ""
|
|
||||||
if id > 0 {
|
|
||||||
stringId = strconv.Itoa(int(id))
|
|
||||||
}
|
|
||||||
namespace.id = stringId
|
|
||||||
|
|
||||||
return namespace
|
return namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +291,14 @@ func (r *NameResolver) FindNamespaceImports(namespace *Namespace) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *NameResolver) chooseId(namespace *Namespace) {
|
||||||
|
id := r.sortedNamespaces.index(namespace)
|
||||||
|
if id < 0 {
|
||||||
|
panic(fmt.Sprintf("Namespace not found: %v\n", namespace.id))
|
||||||
|
}
|
||||||
|
namespace.id = strconv.Itoa(id)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *NameResolver) MissingDependencyError(depender string, dependerNamespace blueprint.Namespace, depName string) (err error) {
|
func (r *NameResolver) MissingDependencyError(depender string, dependerNamespace blueprint.Namespace, depName string) (err error) {
|
||||||
text := fmt.Sprintf("%q depends on undefined module %q", depender, depName)
|
text := fmt.Sprintf("%q depends on undefined module %q", depender, depName)
|
||||||
|
|
||||||
@@ -332,6 +340,14 @@ func (r *NameResolver) findNamespaceFromCtx(ctx blueprint.NamespaceContext) *Nam
|
|||||||
return r.findNamespace(filepath.Dir(ctx.ModulePath()))
|
return r.findNamespace(filepath.Dir(ctx.ModulePath()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *NameResolver) UniqueName(ctx blueprint.NamespaceContext, name string) (unique string) {
|
||||||
|
prefix := r.findNamespaceFromCtx(ctx).id
|
||||||
|
if prefix != "" {
|
||||||
|
prefix = prefix + "-"
|
||||||
|
}
|
||||||
|
return prefix + name
|
||||||
|
}
|
||||||
|
|
||||||
var _ blueprint.NameInterface = (*NameResolver)(nil)
|
var _ blueprint.NameInterface = (*NameResolver)(nil)
|
||||||
|
|
||||||
type Namespace struct {
|
type Namespace struct {
|
||||||
@@ -391,15 +407,17 @@ func NamespaceFactory() Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RegisterNamespaceMutator(ctx RegisterMutatorsContext) {
|
func RegisterNamespaceMutator(ctx RegisterMutatorsContext) {
|
||||||
ctx.BottomUp("namespace_deps", namespaceDeps)
|
ctx.BottomUp("namespace_deps", namespaceMutator).Parallel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func namespaceDeps(ctx BottomUpMutatorContext) {
|
func namespaceMutator(ctx BottomUpMutatorContext) {
|
||||||
module, ok := ctx.Module().(*NamespaceModule)
|
module, ok := ctx.Module().(*NamespaceModule)
|
||||||
if ok {
|
if ok {
|
||||||
err := module.resolver.FindNamespaceImports(module.namespace)
|
err := module.resolver.FindNamespaceImports(module.namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ModuleErrorf(err.Error())
|
ctx.ModuleErrorf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.resolver.chooseId(module.namespace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
@@ -562,6 +563,25 @@ func TestDeclaringNamespaceInNonAndroidBpFile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// so that the generated .ninja file will have consistent names
|
||||||
|
func TestConsistentNamespaceNames(t *testing.T) {
|
||||||
|
ctx := setupTest(t,
|
||||||
|
map[string]string{
|
||||||
|
"dir1": "soong_namespace{}",
|
||||||
|
"dir2": "soong_namespace{}",
|
||||||
|
"dir3": "soong_namespace{}",
|
||||||
|
})
|
||||||
|
|
||||||
|
ns1, _ := ctx.NameResolver.namespaceAt("dir1")
|
||||||
|
ns2, _ := ctx.NameResolver.namespaceAt("dir2")
|
||||||
|
ns3, _ := ctx.NameResolver.namespaceAt("dir3")
|
||||||
|
actualIds := []string{ns1.id, ns2.id, ns3.id}
|
||||||
|
expectedIds := []string{"1", "2", "3"}
|
||||||
|
if !reflect.DeepEqual(actualIds, expectedIds) {
|
||||||
|
t.Errorf("Incorrect namespace ids.\nactual: %s\nexpected: %s\n", actualIds, expectedIds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// some utils to support the tests
|
// some utils to support the tests
|
||||||
|
|
||||||
func mockFiles(bps map[string]string) (files map[string][]byte) {
|
func mockFiles(bps map[string]string) (files map[string][]byte) {
|
||||||
|
@@ -23,14 +23,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewTestContext() *TestContext {
|
func NewTestContext() *TestContext {
|
||||||
ctx := &TestContext{
|
|
||||||
Context: blueprint.NewContext(),
|
|
||||||
}
|
|
||||||
|
|
||||||
namespaceExportFilter := func(namespace *Namespace) bool {
|
namespaceExportFilter := func(namespace *Namespace) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
ctx.SetNameInterface(NewNameResolver(namespaceExportFilter))
|
|
||||||
|
nameResolver := NewNameResolver(namespaceExportFilter)
|
||||||
|
ctx := &TestContext{
|
||||||
|
Context: blueprint.NewContext(),
|
||||||
|
NameResolver: nameResolver,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.SetNameInterface(nameResolver)
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
@@ -44,6 +47,7 @@ func NewTestArchContext() *TestContext {
|
|||||||
type TestContext struct {
|
type TestContext struct {
|
||||||
*blueprint.Context
|
*blueprint.Context
|
||||||
preArch, preDeps, postDeps []RegisterMutatorFunc
|
preArch, preDeps, postDeps []RegisterMutatorFunc
|
||||||
|
NameResolver *NameResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) {
|
func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) {
|
||||||
|
Reference in New Issue
Block a user