Includes rust_binary in rust-project.json

Until now, only rust_library (and their derivatives such as
rust_library_host) were reported in rust-project.json. Adds support for
rust_binary and rust_tests.

Bug: 174743191
Test: Validate auto-completion in keystore2_main.rs
Change-Id: I17b3ec29e233f29b7abd16dc771070ada48d17fb
This commit is contained in:
Thiébaud Weksteen
2020-12-03 20:58:32 +01:00
parent f202e4e793
commit 064f6e957e
2 changed files with 86 additions and 34 deletions

View File

@@ -75,12 +75,16 @@ func init() {
android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton) android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
} }
// librarySource finds the main source file (.rs) for a crate. // crateSource finds the main source file (.rs) for a crate.
func librarySource(ctx android.SingletonContext, rModule *Module, rustLib *libraryDecorator) (string, bool) { func crateSource(ctx android.SingletonContext, rModule *Module, comp *baseCompiler) (string, bool) {
srcs := rustLib.baseCompiler.Properties.Srcs srcs := comp.Properties.Srcs
if len(srcs) != 0 { if len(srcs) != 0 {
return path.Join(ctx.ModuleDir(rModule), srcs[0]), true return path.Join(ctx.ModuleDir(rModule), srcs[0]), true
} }
rustLib, ok := rModule.compiler.(*libraryDecorator)
if !ok {
return "", false
}
if !rustLib.source() { if !rustLib.source() {
return "", false return "", false
} }
@@ -132,8 +136,15 @@ func (singleton *projectGeneratorSingleton) appendLibraryAndDeps(ctx android.Sin
if rModule.compiler == nil { if rModule.compiler == nil {
return 0, "", false return 0, "", false
} }
rustLib, ok := rModule.compiler.(*libraryDecorator) var comp *baseCompiler
if !ok { switch c := rModule.compiler.(type) {
case *libraryDecorator:
comp = c.baseCompiler
case *binaryDecorator:
comp = c.baseCompiler
case *testDecorator:
comp = c.binaryDecorator.baseCompiler
default:
return 0, "", false return 0, "", false
} }
moduleName := ctx.ModuleName(module) moduleName := ctx.ModuleName(module)
@@ -146,12 +157,12 @@ func (singleton *projectGeneratorSingleton) appendLibraryAndDeps(ctx android.Sin
return cInfo.ID, crateName, true return cInfo.ID, crateName, true
} }
crate := rustProjectCrate{Deps: make([]rustProjectDep, 0), Cfgs: make([]string, 0)} crate := rustProjectCrate{Deps: make([]rustProjectDep, 0), Cfgs: make([]string, 0)}
rootModule, ok := librarySource(ctx, rModule, rustLib) rootModule, ok := crateSource(ctx, rModule, comp)
if !ok { if !ok {
return 0, "", false return 0, "", false
} }
crate.RootModule = rootModule crate.RootModule = rootModule
crate.Edition = rustLib.baseCompiler.edition() crate.Edition = comp.edition()
deps := make(map[string]int) deps := make(map[string]int)
singleton.mergeDependencies(ctx, module, &crate, deps) singleton.mergeDependencies(ctx, module, &crate, deps)

View File

@@ -67,6 +67,37 @@ func validateJsonCrates(t *testing.T, rawContent []byte) []interface{} {
return crates return crates
} }
// validateCrate ensures that a crate can be parsed as a map.
func validateCrate(t *testing.T, crate interface{}) map[string]interface{} {
c, ok := crate.(map[string]interface{})
if !ok {
t.Fatalf("Unexpected type for crate: %v", c)
}
return c
}
// validateDependencies parses the dependencies for a crate. It returns a list
// of the dependencies name.
func validateDependencies(t *testing.T, crate map[string]interface{}) []string {
var dependencies []string
deps, ok := crate["deps"].([]interface{})
if !ok {
t.Errorf("Unexpected format for deps: %v", crate["deps"])
}
for _, dep := range deps {
d, ok := dep.(map[string]interface{})
if !ok {
t.Errorf("Unexpected format for dependency: %v", dep)
}
name, ok := d["name"].(string)
if !ok {
t.Errorf("Dependency is missing the name key: %v", d)
}
dependencies = append(dependencies, name)
}
return dependencies
}
func TestProjectJsonDep(t *testing.T) { func TestProjectJsonDep(t *testing.T) {
bp := ` bp := `
rust_library { rust_library {
@@ -85,6 +116,29 @@ func TestProjectJsonDep(t *testing.T) {
validateJsonCrates(t, jsonContent) validateJsonCrates(t, jsonContent)
} }
func TestProjectJsonBinary(t *testing.T) {
bp := `
rust_binary {
name: "liba",
srcs: ["a/src/lib.rs"],
crate_name: "a"
}
`
jsonContent := testProjectJson(t, bp)
crates := validateJsonCrates(t, jsonContent)
for _, c := range crates {
crate := validateCrate(t, c)
rootModule, ok := crate["root_module"].(string)
if !ok {
t.Fatalf("Unexpected type for root_module: %v", crate["root_module"])
}
if rootModule == "a/src/lib.rs" {
return
}
}
t.Errorf("Entry for binary %q not found: %s", "a", jsonContent)
}
func TestProjectJsonBindGen(t *testing.T) { func TestProjectJsonBindGen(t *testing.T) {
bp := ` bp := `
rust_library { rust_library {
@@ -116,10 +170,7 @@ func TestProjectJsonBindGen(t *testing.T) {
jsonContent := testProjectJson(t, bp) jsonContent := testProjectJson(t, bp)
crates := validateJsonCrates(t, jsonContent) crates := validateJsonCrates(t, jsonContent)
for _, c := range crates { for _, c := range crates {
crate, ok := c.(map[string]interface{}) crate := validateCrate(t, c)
if !ok {
t.Fatalf("Unexpected type for crate: %v", c)
}
rootModule, ok := crate["root_module"].(string) rootModule, ok := crate["root_module"].(string)
if !ok { if !ok {
t.Fatalf("Unexpected type for root_module: %v", crate["root_module"]) t.Fatalf("Unexpected type for root_module: %v", crate["root_module"])
@@ -133,16 +184,8 @@ func TestProjectJsonBindGen(t *testing.T) {
} }
// Check that libbindings1 does not depend on itself. // Check that libbindings1 does not depend on itself.
if strings.Contains(rootModule, "libbindings1") { if strings.Contains(rootModule, "libbindings1") {
deps, ok := crate["deps"].([]interface{}) for _, depName := range validateDependencies(t, crate) {
if !ok { if depName == "bindings1" {
t.Errorf("Unexpected format for deps: %v", crate["deps"])
}
for _, dep := range deps {
d, ok := dep.(map[string]interface{})
if !ok {
t.Errorf("Unexpected format for dep: %v", dep)
}
if d["name"] == "bindings1" {
t.Errorf("libbindings1 depends on itself") t.Errorf("libbindings1 depends on itself")
} }
} }
@@ -171,20 +214,18 @@ func TestProjectJsonMultiVersion(t *testing.T) {
` `
jsonContent := testProjectJson(t, bp) jsonContent := testProjectJson(t, bp)
crates := validateJsonCrates(t, jsonContent) crates := validateJsonCrates(t, jsonContent)
for _, crate := range crates { for _, c := range crates {
c := crate.(map[string]interface{}) crate := validateCrate(t, c)
if c["root_module"] == "b/src/lib.rs" { rootModule, ok := crate["root_module"].(string)
deps, ok := c["deps"].([]interface{}) if !ok {
if !ok { t.Fatalf("Unexpected type for root_module: %v", crate["root_module"])
t.Errorf("Unexpected format for deps: %v", c["deps"]) }
} // Make sure that b has 2 different dependencies.
if rootModule == "b/src/lib.rs" {
aCount := 0 aCount := 0
for _, dep := range deps { deps := validateDependencies(t, crate)
d, ok := dep.(map[string]interface{}) for _, depName := range deps {
if !ok { if depName == "a" {
t.Errorf("Unexpected format for dep: %v", dep)
}
if d["name"] == "a" {
aCount++ aCount++
} }
} }