Add support for unset select branches
Currently, with the arch/os mutator, you can override a property using the default value for just a few arch types, for example: cc_defaults { name: "my_defaults", target: { windows: { enabled: true, } } } cc_binary { name: "foo", enabled: false, defaults: ["my_defaults"], } You could make a select statment that acts like the above if it were all in one module, but currently with select statements you can't make a defaults module that can be generically applied to any other module and have the same behavior as the above. After this cl, the defaults module could look like: cc_defaults { name: "my_defaults", enabled: select(variant("arch"), { "windows": true, _: unset, }), } Which would have the same behavior. Unset may also be useful for setting the property under some configurations, but wanting to leave the implementation-specific default value in others. Bug: 323382414 Test: m nothing --no-skip-soong-tests Change-Id: I3ea3277ea8b9a0ac5e613b4378945388b9df036a
This commit is contained in:
parent
a6074ea049
commit
021cc8f5b8
8 changed files with 252 additions and 78 deletions
|
@ -189,6 +189,7 @@ const (
|
|||
ListType
|
||||
MapType
|
||||
NotEvaluatedType
|
||||
UnsetType
|
||||
)
|
||||
|
||||
func (t Type) String() string {
|
||||
|
@ -205,6 +206,8 @@ func (t Type) String() string {
|
|||
return "map"
|
||||
case NotEvaluatedType:
|
||||
return "notevaluated"
|
||||
case UnsetType:
|
||||
return "unset"
|
||||
default:
|
||||
panic(fmt.Errorf("Unknown type %d", t))
|
||||
}
|
||||
|
@ -596,13 +599,14 @@ func (s SelectType) String() string {
|
|||
}
|
||||
|
||||
type Select struct {
|
||||
KeywordPos scanner.Position // the keyword "select"
|
||||
Typ SelectType
|
||||
Condition String
|
||||
LBracePos scanner.Position
|
||||
RBracePos scanner.Position
|
||||
Cases []*SelectCase // the case statements
|
||||
Append Expression
|
||||
KeywordPos scanner.Position // the keyword "select"
|
||||
Typ SelectType
|
||||
Condition String
|
||||
LBracePos scanner.Position
|
||||
RBracePos scanner.Position
|
||||
Cases []*SelectCase // the case statements
|
||||
Append Expression
|
||||
ExpressionType Type
|
||||
}
|
||||
|
||||
func (s *Select) Pos() scanner.Position { return s.KeywordPos }
|
||||
|
@ -629,16 +633,10 @@ func (s *Select) String() string {
|
|||
}
|
||||
|
||||
func (s *Select) Type() Type {
|
||||
if len(s.Cases) == 0 {
|
||||
panic("select with no cases")
|
||||
if s.ExpressionType == UnsetType && s.Append != nil {
|
||||
return s.Append.Type()
|
||||
}
|
||||
ty := s.Cases[0].Value.Type()
|
||||
for _, c := range s.Cases[1:] {
|
||||
if c.Value.Type() != ty {
|
||||
panic(fmt.Sprintf("Found select statement with differing types %q and %q in its cases", ty.String(), c.Value.Type().String()))
|
||||
}
|
||||
}
|
||||
return ty
|
||||
return s.ExpressionType
|
||||
}
|
||||
|
||||
type SelectCase struct {
|
||||
|
@ -660,3 +658,36 @@ func (c *SelectCase) String() string {
|
|||
|
||||
func (c *SelectCase) Pos() scanner.Position { return c.Pattern.LiteralPos }
|
||||
func (c *SelectCase) End() scanner.Position { return c.Value.End() }
|
||||
|
||||
// UnsetProperty is the expression type of the "unset" keyword that can be
|
||||
// used in select statements to make the property unset. For example:
|
||||
//
|
||||
// my_module_type {
|
||||
// name: "foo",
|
||||
// some_prop: select(soong_config_variable("my_namespace", "my_var"), {
|
||||
// "foo": unset,
|
||||
// "default": "bar",
|
||||
// })
|
||||
// }
|
||||
type UnsetProperty struct {
|
||||
Position scanner.Position
|
||||
}
|
||||
|
||||
func (n UnsetProperty) Copy() Expression {
|
||||
return UnsetProperty{Position: n.Position}
|
||||
}
|
||||
|
||||
func (n UnsetProperty) String() string {
|
||||
return "unset"
|
||||
}
|
||||
|
||||
func (n UnsetProperty) Type() Type {
|
||||
return UnsetType
|
||||
}
|
||||
|
||||
func (n UnsetProperty) Eval() Expression {
|
||||
return UnsetProperty{Position: n.Position}
|
||||
}
|
||||
|
||||
func (n UnsetProperty) Pos() scanner.Position { return n.Position }
|
||||
func (n UnsetProperty) End() scanner.Position { return n.Position }
|
||||
|
|
|
@ -289,7 +289,12 @@ func (p *parser) parseModule(typ string, typPos scanner.Position) *Module {
|
|||
func (p *parser) parsePropertyList(isModule, compat bool) (properties []*Property) {
|
||||
for p.tok == scanner.Ident {
|
||||
property := p.parseProperty(isModule, compat)
|
||||
properties = append(properties, property)
|
||||
|
||||
// If a property is set to an empty select or a select where all branches are "unset",
|
||||
// skip emitting the property entirely.
|
||||
if property.Value.Type() != UnsetType {
|
||||
properties = append(properties, property)
|
||||
}
|
||||
|
||||
if p.tok != ',' {
|
||||
// There was no comma, so the list is done.
|
||||
|
@ -350,7 +355,14 @@ func (p *parser) parseExpression() (value Expression) {
|
|||
}
|
||||
|
||||
func (p *parser) evaluateOperator(value1, value2 Expression, operator rune,
|
||||
pos scanner.Position) (*Operator, error) {
|
||||
pos scanner.Position) (Expression, error) {
|
||||
|
||||
if value1.Type() == UnsetType {
|
||||
return value2, nil
|
||||
}
|
||||
if value2.Type() == UnsetType {
|
||||
return value1, nil
|
||||
}
|
||||
|
||||
value := value1
|
||||
|
||||
|
@ -454,7 +466,7 @@ func (p *parser) addMaps(map1, map2 []*Property, pos scanner.Position) ([]*Prope
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseOperator(value1 Expression) *Operator {
|
||||
func (p *parser) parseOperator(value1 Expression) Expression {
|
||||
operator := p.tok
|
||||
pos := p.scanner.Position
|
||||
p.accept(operator)
|
||||
|
@ -595,6 +607,7 @@ func (p *parser) parseSelect() Expression {
|
|||
return nil
|
||||
}
|
||||
|
||||
hasNonUnsetValue := false
|
||||
for p.tok == scanner.String {
|
||||
c := &SelectCase{}
|
||||
if s := p.parseStringValue(); s != nil {
|
||||
|
@ -610,7 +623,13 @@ func (p *parser) parseSelect() Expression {
|
|||
if !p.accept(':') {
|
||||
return nil
|
||||
}
|
||||
c.Value = p.parseExpression()
|
||||
if p.tok == scanner.Ident && p.scanner.TokenText() == "unset" {
|
||||
c.Value = UnsetProperty{Position: p.scanner.Position}
|
||||
p.accept(scanner.Ident)
|
||||
} else {
|
||||
hasNonUnsetValue = true
|
||||
c.Value = p.parseExpression()
|
||||
}
|
||||
if !p.accept(',') {
|
||||
return nil
|
||||
}
|
||||
|
@ -633,13 +652,42 @@ func (p *parser) parseSelect() Expression {
|
|||
if !p.accept(':') {
|
||||
return nil
|
||||
}
|
||||
c.Value = p.parseExpression()
|
||||
if p.tok == scanner.Ident && p.scanner.TokenText() == "unset" {
|
||||
c.Value = UnsetProperty{Position: p.scanner.Position}
|
||||
p.accept(scanner.Ident)
|
||||
} else {
|
||||
hasNonUnsetValue = true
|
||||
c.Value = p.parseExpression()
|
||||
}
|
||||
if !p.accept(',') {
|
||||
return nil
|
||||
}
|
||||
result.Cases = append(result.Cases, c)
|
||||
}
|
||||
|
||||
// If all branches have the value "unset", then this is equivalent
|
||||
// to an empty select.
|
||||
if !hasNonUnsetValue {
|
||||
result.Typ = SelectTypeUnconfigured
|
||||
result.Condition.Value = ""
|
||||
result.Cases = nil
|
||||
}
|
||||
|
||||
ty := UnsetType
|
||||
for _, c := range result.Cases {
|
||||
otherTy := c.Value.Type()
|
||||
// Any other type can override UnsetType
|
||||
if ty == UnsetType {
|
||||
ty = otherTy
|
||||
}
|
||||
if otherTy != UnsetType && otherTy != ty {
|
||||
p.errorf("Found select statement with differing types %q and %q in its cases", ty.String(), otherTy.String())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
result.ExpressionType = ty
|
||||
|
||||
result.RBracePos = p.scanner.Position
|
||||
if !p.accept('}') {
|
||||
return nil
|
||||
|
|
|
@ -187,7 +187,11 @@ func (p *printer) printSelect(s *Select) {
|
|||
}
|
||||
p.printToken(":", c.ColonPos)
|
||||
p.requestSpace()
|
||||
p.printExpression(c.Value)
|
||||
if unset, ok := c.Value.(UnsetProperty); ok {
|
||||
p.printToken(unset.String(), unset.Pos())
|
||||
} else {
|
||||
p.printExpression(c.Value)
|
||||
}
|
||||
p.printToken(",", c.Value.Pos())
|
||||
}
|
||||
p.requestNewline()
|
||||
|
|
|
@ -635,6 +635,73 @@ foo {
|
|||
_: "f2",
|
||||
}),
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Select with unset property",
|
||||
input: `
|
||||
foo {
|
||||
stuff: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||
"foo": unset,
|
||||
_: "c2",
|
||||
}),
|
||||
}
|
||||
`,
|
||||
output: `
|
||||
foo {
|
||||
stuff: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||
"foo": unset,
|
||||
_: "c2",
|
||||
}),
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Select with only unsets is removed",
|
||||
input: `
|
||||
foo {
|
||||
stuff: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||
"foo": unset,
|
||||
_: unset,
|
||||
}),
|
||||
}
|
||||
`,
|
||||
output: `
|
||||
foo {
|
||||
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Additions of unset selects are removed",
|
||||
input: `
|
||||
foo {
|
||||
stuff: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||
"foo": "a",
|
||||
_: "b",
|
||||
}) + select(soong_config_variable("my_namespace", "my_variable2"), {
|
||||
"foo": unset,
|
||||
_: unset,
|
||||
}) + select(soong_config_variable("my_namespace", "my_variable3"), {
|
||||
"foo": "c",
|
||||
_: "d",
|
||||
}),
|
||||
}
|
||||
`,
|
||||
// TODO(b/323382414): This is not good formatting, revisit later.
|
||||
// But at least it removes the useless middle select
|
||||
output: `
|
||||
foo {
|
||||
stuff: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||
"foo": "a",
|
||||
_: "b",
|
||||
}) +
|
||||
|
||||
select(soong_config_variable("my_namespace", "my_variable3"), {
|
||||
"foo": "c",
|
||||
_: "d",
|
||||
}),
|
||||
}
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ type Configurable[T ConfigurableElements] struct {
|
|||
propertyName string
|
||||
typ parser.SelectType
|
||||
condition string
|
||||
cases map[string]T
|
||||
cases map[string]*T
|
||||
appendWrapper *appendWrapper[T]
|
||||
}
|
||||
|
||||
|
@ -119,12 +119,12 @@ func (c *Configurable[T]) evaluateNonTransitive(evaluator ConfigurableEvaluator)
|
|||
}
|
||||
panic(fmt.Sprintf("Expected the single branch of an unconfigured select to be %q, got %q", default_select_branch_name, actual))
|
||||
}
|
||||
return &result
|
||||
return result
|
||||
}
|
||||
val, defined := evaluator.EvaluateConfiguration(c.typ, c.propertyName, c.condition)
|
||||
if !defined {
|
||||
if result, ok := c.cases[default_select_branch_name]; ok {
|
||||
return &result
|
||||
return result
|
||||
}
|
||||
evaluator.PropertyErrorf(c.propertyName, "%s %q was not defined", c.typ.String(), c.condition)
|
||||
return nil
|
||||
|
@ -133,10 +133,10 @@ func (c *Configurable[T]) evaluateNonTransitive(evaluator ConfigurableEvaluator)
|
|||
panic("Evaluator cannot return the default branch")
|
||||
}
|
||||
if result, ok := c.cases[val]; ok {
|
||||
return &result
|
||||
return result
|
||||
}
|
||||
if result, ok := c.cases[default_select_branch_name]; ok {
|
||||
return &result
|
||||
return result
|
||||
}
|
||||
evaluator.PropertyErrorf(c.propertyName, "%s %q had value %q, which was not handled by the select statement", c.typ.String(), c.condition, val)
|
||||
return nil
|
||||
|
@ -212,7 +212,7 @@ func (c *Configurable[T]) initialize(propertyName string, typ parser.SelectType,
|
|||
c.propertyName = propertyName
|
||||
c.typ = typ
|
||||
c.condition = condition
|
||||
c.cases = cases.(map[string]T)
|
||||
c.cases = cases.(map[string]*T)
|
||||
c.appendWrapper = &appendWrapper[T]{}
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ func (c *Configurable[T]) clone() *Configurable[T] {
|
|||
}
|
||||
}
|
||||
|
||||
casesCopy := make(map[string]T, len(c.cases))
|
||||
casesCopy := make(map[string]*T, len(c.cases))
|
||||
for k, v := range c.cases {
|
||||
casesCopy[k] = copyConfiguredValue(v)
|
||||
}
|
||||
|
@ -265,10 +265,14 @@ func (c *Configurable[T]) clone() *Configurable[T] {
|
|||
}
|
||||
}
|
||||
|
||||
func copyConfiguredValue[T ConfigurableElements](t T) T {
|
||||
switch t2 := any(t).(type) {
|
||||
func copyConfiguredValue[T ConfigurableElements](t *T) *T {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
switch t2 := any(*t).(type) {
|
||||
case []string:
|
||||
return any(slices.Clone(t2)).(T)
|
||||
result := any(slices.Clone(t2)).(T)
|
||||
return &result
|
||||
default:
|
||||
return t
|
||||
}
|
||||
|
|
|
@ -1262,7 +1262,7 @@ func appendPropertiesTestCases() []appendPropertyTestCase {
|
|||
S: Configurable[[]string]{
|
||||
typ: parser.SelectTypeSoongConfigVariable,
|
||||
condition: "foo",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"a": {"1", "2"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{},
|
||||
|
@ -1272,7 +1272,7 @@ func appendPropertiesTestCases() []appendPropertyTestCase {
|
|||
S: Configurable[[]string]{
|
||||
typ: parser.SelectTypeReleaseVariable,
|
||||
condition: "bar",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"b": {"3", "4"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{},
|
||||
|
@ -1282,14 +1282,14 @@ func appendPropertiesTestCases() []appendPropertyTestCase {
|
|||
S: Configurable[[]string]{
|
||||
typ: parser.SelectTypeSoongConfigVariable,
|
||||
condition: "foo",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"a": {"1", "2"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{
|
||||
append: Configurable[[]string]{
|
||||
typ: parser.SelectTypeReleaseVariable,
|
||||
condition: "bar",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"b": {"3", "4"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{},
|
||||
|
@ -1305,7 +1305,7 @@ func appendPropertiesTestCases() []appendPropertyTestCase {
|
|||
S: Configurable[[]string]{
|
||||
typ: parser.SelectTypeSoongConfigVariable,
|
||||
condition: "foo",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"a": {"1", "2"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{},
|
||||
|
@ -1315,7 +1315,7 @@ func appendPropertiesTestCases() []appendPropertyTestCase {
|
|||
S: Configurable[[]string]{
|
||||
typ: parser.SelectTypeReleaseVariable,
|
||||
condition: "bar",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"b": {"3", "4"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{},
|
||||
|
@ -1325,14 +1325,14 @@ func appendPropertiesTestCases() []appendPropertyTestCase {
|
|||
S: Configurable[[]string]{
|
||||
typ: parser.SelectTypeReleaseVariable,
|
||||
condition: "bar",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"b": {"3", "4"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{
|
||||
append: Configurable[[]string]{
|
||||
typ: parser.SelectTypeSoongConfigVariable,
|
||||
condition: "foo",
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
"a": {"1", "2"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{},
|
||||
|
|
|
@ -357,8 +357,8 @@ func (ctx *unpackContext) unpackToConfigurable(propertyName string, property *pa
|
|||
result := Configurable[string]{
|
||||
propertyName: property.Name,
|
||||
typ: parser.SelectTypeUnconfigured,
|
||||
cases: map[string]string{
|
||||
default_select_branch_name: v.Value,
|
||||
cases: map[string]*string{
|
||||
default_select_branch_name: &v.Value,
|
||||
},
|
||||
appendWrapper: &appendWrapper[string]{},
|
||||
}
|
||||
|
@ -375,8 +375,8 @@ func (ctx *unpackContext) unpackToConfigurable(propertyName string, property *pa
|
|||
result := Configurable[bool]{
|
||||
propertyName: property.Name,
|
||||
typ: parser.SelectTypeUnconfigured,
|
||||
cases: map[string]bool{
|
||||
default_select_branch_name: v.Value,
|
||||
cases: map[string]*bool{
|
||||
default_select_branch_name: &v.Value,
|
||||
},
|
||||
appendWrapper: &appendWrapper[bool]{},
|
||||
}
|
||||
|
@ -392,9 +392,9 @@ func (ctx *unpackContext) unpackToConfigurable(propertyName string, property *pa
|
|||
}
|
||||
switch configuredType.Elem().Kind() {
|
||||
case reflect.String:
|
||||
var cases map[string][]string
|
||||
var cases map[string]*[]string
|
||||
if v.Values != nil {
|
||||
cases = map[string][]string{default_select_branch_name: make([]string, 0, len(v.Values))}
|
||||
value := make([]string, 0, len(v.Values))
|
||||
itemProperty := &parser.Property{NamePos: property.NamePos, ColonPos: property.ColonPos}
|
||||
for i, expr := range v.Values {
|
||||
itemProperty.Name = propertyName + "[" + strconv.Itoa(i) + "]"
|
||||
|
@ -404,8 +404,9 @@ func (ctx *unpackContext) unpackToConfigurable(propertyName string, property *pa
|
|||
ctx.addError(err)
|
||||
return reflect.ValueOf(Configurable[[]string]{}), false
|
||||
}
|
||||
cases[default_select_branch_name] = append(cases[default_select_branch_name], exprUnpacked.Interface().(string))
|
||||
value = append(value, exprUnpacked.Interface().(string))
|
||||
}
|
||||
cases = map[string]*[]string{default_select_branch_name: &value}
|
||||
}
|
||||
result := Configurable[[]string]{
|
||||
propertyName: property.Name,
|
||||
|
@ -423,16 +424,21 @@ func (ctx *unpackContext) unpackToConfigurable(propertyName string, property *pa
|
|||
case *parser.Select:
|
||||
resultPtr := reflect.New(configurableType)
|
||||
result := resultPtr.Elem()
|
||||
cases := reflect.MakeMapWithSize(reflect.MapOf(reflect.TypeOf(""), configuredType), len(v.Cases))
|
||||
cases := reflect.MakeMapWithSize(reflect.MapOf(reflect.TypeOf(""), reflect.PointerTo(configuredType)), len(v.Cases))
|
||||
for i, c := range v.Cases {
|
||||
p := &parser.Property{
|
||||
Name: property.Name + "[" + strconv.Itoa(i) + "]",
|
||||
NamePos: c.ColonPos,
|
||||
Value: c.Value,
|
||||
}
|
||||
// Map the "unset" keyword to a nil pointer in the cases map
|
||||
if _, ok := c.Value.(parser.UnsetProperty); ok {
|
||||
cases.SetMapIndex(reflect.ValueOf(c.Pattern.Value), reflect.Zero(reflect.PointerTo(configuredType)))
|
||||
continue
|
||||
}
|
||||
switch configuredType.Kind() {
|
||||
case reflect.String, reflect.Bool:
|
||||
p := &parser.Property{
|
||||
Name: property.Name + "[" + strconv.Itoa(i) + "]",
|
||||
NamePos: c.ColonPos,
|
||||
Value: c.Value,
|
||||
}
|
||||
val, err := propertyToValue(configuredType, p)
|
||||
val, err := propertyToValue(reflect.PointerTo(configuredType), p)
|
||||
if err != nil {
|
||||
ctx.addError(&UnpackError{
|
||||
err,
|
||||
|
@ -445,12 +451,7 @@ func (ctx *unpackContext) unpackToConfigurable(propertyName string, property *pa
|
|||
if configuredType.Elem().Kind() != reflect.String {
|
||||
panic("This should be unreachable because ConfigurableElements only accepts slices of strings")
|
||||
}
|
||||
p := &parser.Property{
|
||||
Name: property.Name + "[" + strconv.Itoa(i) + "]",
|
||||
NamePos: c.ColonPos,
|
||||
Value: c.Value,
|
||||
}
|
||||
val, ok := ctx.unpackToSlice(p.Name, p, configuredType)
|
||||
val, ok := ctx.unpackToSlice(p.Name, p, reflect.PointerTo(configuredType))
|
||||
if !ok {
|
||||
return reflect.New(configurableType), false
|
||||
}
|
||||
|
@ -504,8 +505,27 @@ func (ctx *unpackContext) reportSelectOnNonConfigurablePropertyError(
|
|||
return true
|
||||
}
|
||||
|
||||
// unpackSlice creates a value of a given slice type from the property which should be a list
|
||||
// unpackSlice creates a value of a given slice or pointer to slice type from the property,
|
||||
// which should be a list
|
||||
func (ctx *unpackContext) unpackToSlice(
|
||||
sliceName string, property *parser.Property, sliceType reflect.Type) (reflect.Value, bool) {
|
||||
if sliceType.Kind() == reflect.Pointer {
|
||||
sliceType = sliceType.Elem()
|
||||
result := reflect.New(sliceType)
|
||||
slice, ok := ctx.unpackToSliceInner(sliceName, property, sliceType)
|
||||
if !ok {
|
||||
return result, ok
|
||||
}
|
||||
result.Elem().Set(slice)
|
||||
return result, true
|
||||
}
|
||||
return ctx.unpackToSliceInner(sliceName, property, sliceType)
|
||||
}
|
||||
|
||||
// unpackToSliceInner creates a value of a given slice type from the property,
|
||||
// which should be a list. It doesn't support pointers to slice types like unpackToSlice
|
||||
// does.
|
||||
func (ctx *unpackContext) unpackToSliceInner(
|
||||
sliceName string, property *parser.Property, sliceType reflect.Type) (reflect.Value, bool) {
|
||||
propValueAsList, ok := property.Value.Eval().(*parser.List)
|
||||
if !ok {
|
||||
|
|
|
@ -735,8 +735,8 @@ var validUnpackTestCases = []struct {
|
|||
Foo: Configurable[string]{
|
||||
propertyName: "foo",
|
||||
typ: parser.SelectTypeUnconfigured,
|
||||
cases: map[string]string{
|
||||
default_select_branch_name: "bar",
|
||||
cases: map[string]*string{
|
||||
default_select_branch_name: StringPtr("bar"),
|
||||
},
|
||||
appendWrapper: &appendWrapper[string]{},
|
||||
},
|
||||
|
@ -757,8 +757,8 @@ var validUnpackTestCases = []struct {
|
|||
Foo: Configurable[bool]{
|
||||
propertyName: "foo",
|
||||
typ: parser.SelectTypeUnconfigured,
|
||||
cases: map[string]bool{
|
||||
default_select_branch_name: true,
|
||||
cases: map[string]*bool{
|
||||
default_select_branch_name: BoolPtr(true),
|
||||
},
|
||||
appendWrapper: &appendWrapper[bool]{},
|
||||
},
|
||||
|
@ -779,7 +779,7 @@ var validUnpackTestCases = []struct {
|
|||
Foo: Configurable[[]string]{
|
||||
propertyName: "foo",
|
||||
typ: parser.SelectTypeUnconfigured,
|
||||
cases: map[string][]string{
|
||||
cases: map[string]*[]string{
|
||||
default_select_branch_name: {"a", "b"},
|
||||
},
|
||||
appendWrapper: &appendWrapper[[]string]{},
|
||||
|
@ -806,10 +806,10 @@ var validUnpackTestCases = []struct {
|
|||
propertyName: "foo",
|
||||
typ: parser.SelectTypeSoongConfigVariable,
|
||||
condition: "my_namespace:my_variable",
|
||||
cases: map[string]string{
|
||||
"a": "a2",
|
||||
"b": "b2",
|
||||
default_select_branch_name: "c2",
|
||||
cases: map[string]*string{
|
||||
"a": StringPtr("a2"),
|
||||
"b": StringPtr("b2"),
|
||||
default_select_branch_name: StringPtr("c2"),
|
||||
},
|
||||
appendWrapper: &appendWrapper[string]{},
|
||||
},
|
||||
|
@ -839,20 +839,20 @@ var validUnpackTestCases = []struct {
|
|||
propertyName: "foo",
|
||||
typ: parser.SelectTypeSoongConfigVariable,
|
||||
condition: "my_namespace:my_variable",
|
||||
cases: map[string]string{
|
||||
"a": "a2",
|
||||
"b": "b2",
|
||||
default_select_branch_name: "c2",
|
||||
cases: map[string]*string{
|
||||
"a": StringPtr("a2"),
|
||||
"b": StringPtr("b2"),
|
||||
default_select_branch_name: StringPtr("c2"),
|
||||
},
|
||||
appendWrapper: &appendWrapper[string]{
|
||||
append: Configurable[string]{
|
||||
propertyName: "foo",
|
||||
typ: parser.SelectTypeSoongConfigVariable,
|
||||
condition: "my_namespace:my_2nd_variable",
|
||||
cases: map[string]string{
|
||||
"d": "d2",
|
||||
"e": "e2",
|
||||
default_select_branch_name: "f2",
|
||||
cases: map[string]*string{
|
||||
"d": StringPtr("d2"),
|
||||
"e": StringPtr("e2"),
|
||||
default_select_branch_name: StringPtr("f2"),
|
||||
},
|
||||
appendWrapper: &appendWrapper[string]{},
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue