Merge "Support generating docs for Configurable properties" into main am: 0a1533d786

Original change: https://android-review.googlesource.com/c/platform/build/blueprint/+/3076047

Change-Id: Ie8ad757f8545ef53a13bf0bfdebbd8e496b4ce5c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Cole Faust 2024-05-06 23:50:48 +00:00 committed by Automerger Merge Worker
commit 7b12605468
7 changed files with 48 additions and 2 deletions

View file

@ -204,6 +204,10 @@ func nestedPropertyStructs(s reflect.Value) []nestedProperty {
if proptools.HasTag(field, "blueprint", "mutated") {
continue
}
if proptools.IsConfigurable(field.Type) {
// Don't recurse into configurable properties, they're structs but not property structs
continue
}
fieldValue := structValue.Field(i)

View file

@ -112,6 +112,10 @@ func TestAllPackages(t *testing.T) {
name: "list_of_nested",
typ: "list of structToNest",
},
propInfo{
name: "configurable_bool",
typ: "configurable bool",
},
propInfo{
name: "nested_in_other_embedded",
typ: "otherStructToNest",

View file

@ -272,6 +272,21 @@ func getType(expr ast.Expr) (typ string, innerProps []Property, err error) {
if err != nil {
return "", nil, err
}
case *ast.IndexExpr:
// IndexExpr is used to represent generic type arguments
if !isConfigurableAst(a.X) {
var writer strings.Builder
if err := ast.Fprint(&writer, nil, expr, nil); err != nil {
return "", nil, err
}
return "", nil, fmt.Errorf("unknown type %s", writer.String())
}
var innerType string
innerType, innerProps, err = getType(a.Index)
if err != nil {
return "", nil, err
}
typ = "configurable " + innerType
default:
typ = fmt.Sprintf("%T", expr)
}
@ -279,6 +294,20 @@ func getType(expr ast.Expr) (typ string, innerProps []Property, err error) {
return typ, innerProps, nil
}
func isConfigurableAst(expr ast.Expr) bool {
switch e := expr.(type) {
case *ast.Ident:
return e.Name == "Configurable"
case *ast.SelectorExpr:
if l, ok := e.X.(*ast.Ident); ok && l.Name == "proptools" {
if e.Sel.Name == "Configurable" {
return true
}
}
}
return false
}
func (ps *PropertyStruct) ExcludeByTag(key, value string) {
filterPropsByTag(&ps.Properties, key, value, true)
}

View file

@ -25,6 +25,8 @@ import (
"runtime"
"strings"
"sync"
"github.com/google/blueprint/proptools"
)
// Handles parsing and low-level processing of Blueprint module source files. Note that most getter
@ -119,7 +121,7 @@ func (r *Reader) PropertyStruct(pkgPath, name string, defaults reflect.Value) (*
var props []Property
// Base case: primitive type
if defaults.Kind() != reflect.Struct {
if defaults.Kind() != reflect.Struct || proptools.IsConfigurable(defaults.Type()) {
props = append(props, Property{Name: name,
Type: defaults.Type().String()})
return &PropertyStruct{Properties: props}, nil

View file

@ -22,6 +22,7 @@ import (
"testing"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
type factoryFn func() (blueprint.Module, []interface{})
@ -81,6 +82,8 @@ type complexProps struct {
List_of_ints []int
List_of_nested []structToNest
Configurable_bool proptools.Configurable[bool]
}
// props docs.

View file

@ -3899,7 +3899,7 @@ func (c *Context) OutDir() (string, error) {
// ModuleTypePropertyStructs returns a mapping from module type name to a list of pointers to
// property structs returned by the factory for that module type.
func (c *Context) ModuleTypePropertyStructs() map[string][]interface{} {
ret := make(map[string][]interface{})
ret := make(map[string][]interface{}, len(c.moduleFactories))
for moduleType, factory := range c.moduleFactories {
_, ret[moduleType] = factory()
}

View file

@ -156,3 +156,7 @@ func isMapOfStruct(t reflect.Type) bool {
func isConfigurable(t reflect.Type) bool {
return isStruct(t) && t.NumField() > 0 && typeFields(t)[0].Type == configurableMarkerType
}
func IsConfigurable(t reflect.Type) bool {
return isConfigurable(t)
}