Commit graph

41 commits

Author SHA1 Message Date
Sasha Smundak
de4d9f94ac Fix bug in buildPropertyMap in previous commit.
Property value should be evaluated before proeprty map is populated with
it. Added the test for this case.
2020-03-03 17:42:38 -08:00
Sasha Smundak
29fdcad56c Implement list of maps
Allow property value to be a list of maps, e.g.
my_module {
  my_list: [
    { name: "foo", value: 42, something: true, },
    { name: "bar", value: 34, something: false, },
  ],
}

Test: internal
Change-Id: I2fc37d692aac39f23c9aa7bda2859ab49f3bc672
2020-03-02 17:26:20 -08:00
Colin Cross
fc6efcb4a4 Fix PropertyNameForField for X86.
Field "X86" has no lowercase runes and was being left uppercase.
Change the new PropertyNameForField rules to lowercase the name unless
it has any uppercase rune after the first rune (which is always
uppercase) and no lowercase runes.

Bug: 148865218
Test: proptools_test.go
Change-Id: Ifd1c10fc03f5ae1765d25b3f73dba8fd61c5c956
2020-02-05 17:13:08 -08:00
Colin Cross
3bbbdf31e3 Support unpacking capitalized property names
Soong config variables may propagate an uppercase name from Make.
Blueprint properties have traditionally been all lowercase, and
using an uppercase property struct field name resulted in a strange
Blueprint property name with the first rune lowercase and the
remaining runes uppercase.

Update the rules for proptools.PropertyNameForField to not lowercase
the first rune if the field name has mulitple runes and is not all
uppercase.

Fixes: 148865218
Test: proptools_test.go
Change-Id: I8de2f65ffb00e5a8ce0aea0caf09f5859315f6b8
2020-02-05 13:50:28 -08:00
Colin Cross
5d57b2d347 Make proptools functions consistently take *struct types
The proptools functions took an inconsistent variety of
struct and *struct types.  Some methods even took a struct
but returned a *struct.  Make all the exported methods
take a *struct, with internal helpers for the ones that need
to take a struct.

Test: proptools tests
Change-Id: I60ce212606e96adcef66c531d57f69c39e1a1638
2020-01-28 09:51:19 -08:00
Colin Cross
6898d26054 Add isStruct and isStructPtr helpers
Test: proptools tests
Change-Id: I7814b2138cd19b538a3a33036a15119e118d7644
2020-01-28 09:51:19 -08:00
Colin Cross
571f77a60d Remove blueprint:"filter(*)" tag support
The filter tag is unused, replaced with FilterPropertyStruct to
generate a new type at runtime that only contains the filtered
fields.

Test: unpack_test.go
Change-Id: Id91cf99290832094d05426f3263279836f0fea73
2020-01-21 11:49:27 -08:00
Colin Cross
b89d91c67c Make FilterPropertyStructSharded smarter
FilterPropertyStructSharded was just sharding the top level
properties into groups of 10.  For nested property structs
this can be insufficient - there could be a single top level
property with many properties below it.

Take a maximum name size, and track the size used by parent
structs to determine when sharding a nested struct is necessary.

Bug: 146234651
Test: filter_test.go
Change-Id: I5b5ed11ea27a0325b2fd6c2c3fb427ea1e2af0c2
2020-01-21 11:49:27 -08:00
Colin Cross
f27c5e470b Move unpackProperties to proptools and export it
Test: unpack_test.go
Change-Id: I145369323bd7d5003a261c13dfb8ed31d0be51b5
2020-01-02 20:32:51 -08:00
Jiyong Park
10f27f8139 Slice properties can be replaced
override_* in Soong requires a module to override certain properties of
other module. In that case, values of a slice property (e.g. []string)
should be replaced by the same property value in the overriding module.
However, since proptools only supports Append and Prepend orders where
the original values are kept for slice properties, the behavior
couldn't be implemented. To support the use case, Replace order is
introduced, in which case slice property values are completely replaced.
For other types of properties, the Replace order behaves exactly the
same as the Append order.

Bug: 144338929
Test: m

Change-Id: Iae9feda035177fe6a22e6e8319c0fdaa9e08e85e
2019-11-19 10:45:58 +09:00
Colin Cross
1907836ad9 Add proptools.FilterPropertyStruct
Move some code from Soong to support creating a property struct
at runtime by filtering fields out of another property struct.

Test: TestFilterPropertyStruct
Change-Id: Ic5ae390a885195bebad6f3ecb7c752c0582a60b1
2019-09-26 14:21:40 -07:00
Colin Cross
66c0b13553 Add proptools.Int and proptools.IntDefault
Add proptools.Int and proptools.IntDefault that behave analogously
to proptools.String and proptools.StringDefault.

Change-Id: I41fd3417c973c9ff4a5aa6680546b4b893784745
2019-09-25 14:52:54 -07:00
Jaewoong Jung
c067251da0 Fix/improve comments on prepending/appending props
Test: N/A
Change-Id: Id95afbea7fbccddafb9f2f0e068967d5547cc469
2019-07-08 14:07:45 -07:00
Jaewoong Jung
4764fa76fe Make off-the-shelf order funcs public.
These are useful outside the package too when calling
proptools.ExtendMatchingProperties.

Change-Id: I054eb105e0dd5287aff99b8be137a8b09d52492d
2019-06-22 11:22:55 -07:00
Jaewoong Jung
7d699c37ec Panic when copying private properties.
When CopyProperties comes across private properties, it silently ignores
them. This is error-prone and can result in a bug very hard to debug if
the developer is unaware of the behavior.

Change-Id: Id6a0752e384ec7fed35728c1e87dbfa95fea84f2
2019-03-07 16:24:56 -08:00
Colin Cross
a4f6a3bebf Add PropertyIndexesWithTag
Add a function that returns all of the indexes to properties in
a property struct that are tagged with `name:"value"`.

Test: proptools/tag_test.go
Change-Id: I00294934c1a0383c8b64ecaabc0e138682efb2e5
2019-03-05 19:47:43 -08:00
colincross
284c742a33
Merge pull request #219 from colincross/escape_list
Replace *Escape with *EscapeList
2019-02-28 11:14:02 -08:00
Colin Cross
937efab2e6 Use sync.Map for type field cache
The type field cache was using an atomic pointer to an immutable
map, which required copying the entire map each time a cache
entry was added.  Profiling showed that this was a significant
hot spot.  Use sync.Map instead.

Change-Id: Ie7c779c5e9e2be1cd530747d74025dcfd206763a
2019-01-23 13:26:42 -08:00
Colin Cross
12392ca0f1 Allow mutated property structs to contain slices of non-strings
Property structs can now contain slices of structs and other
non-strings as long as they are tagged with `blueprint:"mutated"`.

Test: clone_test.go
Test: unpack_test.go
Change-Id: Ib77348dc6e7314a24f17caba10040f7d3ac54e54
2018-10-03 14:29:12 -07:00
Colin Cross
cc1ec0fedc Replace *Escape with *EscapeList
NinjaEscape and ShellEscape operated on lists, which led to
awkward NinjaEscape([]string{s})[0].  Replace NinjaEscape
and ShellEscape with NinjaEscapeList and ShellEscapeList,
and add new NinjaEscape and ShellEscape functions that
operate on a string.

Test: m checkbuild
Change-Id: I283d92cdddc8e0066a300015863a3eab66f77c23
2018-09-19 16:17:10 -07:00
Colin Cross
de3ef3a66e Add proptools.BoolDefault and proptools.StringDefault
I get the logic wrong every time I try to make a *bool property
that defaults to true.

Change-Id: Idc409921c3a4baecf611acf348176f261712cb92
2018-04-10 16:51:47 -07:00
Nan Zhang
f586544ab7 Support parsing int64 in Blueprint file.
Support int64 number instead of int to be more fixed to bit size so
that the underlying arch won't affect overflow cases. Besides,
refection: func (v Value) Int() int64 always cast to int64 no matter the
input is int, int16, int32. Currently we always treat "-" as negative
sign to bind to next value, and "+" as plus operator to add operands
together.
So we allow:
a = 5 + -4 + 5 or a = -4 + 5
But we don't allow:
a = +5 + 4 + -4 since we don't treat "+" as a positive sign, otherwise,
a = 5 + +5 would exist which looks pretty weird. In the future, we may
want fully support number calculator logic eg, "+"/"-" can be
positive/negative sign or operator, and "(" and ")" will be considered
to group expressions with a higher precedence.

int & uint properties within struct keeps unchanged, which is only
allowed when tagged with 'blueprint:mutated'. We only allow *int64
property instead of int64 property within struct since it does't make
sense to do prepending or appending to int64.

Change-Id: I565e046dbd268af3538aee148cd7300037e56523
2017-11-02 22:10:47 -07:00
Colin Cross
05b3607c37 Replace unpack's replace semantics with append
Blueprint was using "replace" semantics when unpacking properties
into property structs, meaning if a module factory pre-set property
values they would be overwritten by whatever was in the Blueprint
file.  This is different than what would happen if the same property
was updated using the Append*Properties functions in proptools, which
would use "append" semantics, which append strings and lists,
logically ORs booleans and replaces pointers to strings and booleans.
Replace unpack's semantics with append semantics for consistency.
Any previous users of pre-set properties can move to using a pointer
to a string or boolean if they want the old behavior.

Test: unpack_test.go
Test: extend_test.go
Change-Id: I02eebe80916e578938142f8e76889bd985223afc
2017-08-01 15:12:12 -07:00
Colin Cross
41ca49ff91 Add proptools functions to escape strings
Blueprint properties that end up as command line arguments need to be
both ninja and shell escaped.  Provide helpers that primary builders can
use to appropriately escape them.

Change-Id: Ifd697d87edb1c6f0a910377835c391bbe8f95b42
2016-09-29 14:31:40 -07:00
Colin Cross
bf2adbfee2 Relax type requirements when extending properties
Allow using ExtendMatchingProperties to extend pointer to a struct or an
interface containing a pointer to a struct using a struct, and
vice-versa.

Also fixes a pre-existing bug where extending a nested structure could
fail if there were multiple possible destnations and some of them did
not have a matching nested property.

Change-Id: I6e69d78eb6595ba7dd2603e3aa7dd8de3f292744
2016-08-22 15:35:17 -07:00
Colin Cross
c3d731258a Support nil pointers to structs in properties
Allow primary builders to reduce allocations of empty structures by
allowing nil pointers to concrete struct types.  Property readers will
not recurse into nil pointers, property writers will replace the nil
pointer with a pointer to the zero value of the pointer element type.

Allows a >50% primary builder time improvement with a trivial change in
Soong.

Change-Id: If6ad674bf7bf2a694c335378a074643a97d3c50b
2016-08-05 17:19:36 -07:00
Colin Cross
01ee36eeea Optimize proptools
proptools cloning and extending are a significant portion of the run
time for Soong.  Optimize out calls to reflect.Type.Field(), which must
allocate a []int to store the index, by caching all the fields of each
type as it is seen, and by iterating over a slice of cached fields
instead of calling Field(i) for each one.  Also avoid calling
reflect.Value.Interface() twice on the same Value.

Change-Id: I4e13fc85f30d8614a5586283e928c0a6d7f24809
2016-08-05 14:00:30 -07:00
Colin Cross
75c4701ed2 Support ExtendProperties that can append or prepend
ExtendProperties is the same as AppendProperties or PrependProperties,
but takes a function that determines whether each property should be
appended or prepended.

Change-Id: I26e400d56d75a88bab9c27c382ee5321bc623ee5
2016-05-05 16:23:19 -07:00
Dan Willemsen
4c00085f2d AppendProperties: Replace *strings instead of appending
This makes *string values act like *bool values -- instead of appending
or prepending the contents of the string, the entire string is replaced.
The use case here is for overriding filenames, where appending doesn't
work.
2016-01-05 14:16:04 -08:00
Colin Cross
9d1469d559 Support embedded anonymous property structs
Allow property structs to contain anonymous embedded structs and
interfaces.  Properties in an anonymous embedded struct or interface are
treated as if they were properties in the embedding struct.
2015-11-20 17:26:52 -08:00
Colin Cross
83cedbec85 Fix ZeroProperties bug on nested interfaces
ZeroProperties was setting nested structs to their zero value, even if
they contained an interface that should be recursed into, not replaced
with nil.
2015-11-20 17:26:52 -08:00
Colin Cross
e4b0d35966 Add proptools.TypeEqual
When appending properties, it may be necessary to determine if two
property structs are the same "type".  A simple Go type comparison is
not sufficient, as there may be interface{} values in the property
structs that contain different types.  Add proptools.TypeEqual that
returns true if they have equal types and all embedded pointers to
structs and interfaces to pointers to structs have the same nilitude and
type.
2015-11-02 15:40:55 -08:00
Colin Cross
8011768729 Add property support for pointers to bools and strings
The only append semantics for bool that result in a no-op when the zero
value is appended is to OR the two values together, but that is rarely
the desired semantics.  Add support for *bool and *string as property
types, where appending a nil pointer is a no-op.  For *bool, appending a
non-nil pointer replaces the destination with the value.  For *string,
appending a non-nil pointer appends the value.

This also provides a more reliable replacement for
ModuleContext.ContainsProperty, as the  build logic can tell that the
property was set, even if it was set by a  mutator and not by the
blueprints file, by testing against nil.

[]string already provides these semantics for lists.

Setting a *bool or *string property from a blueprints file is the same
syntax as setting a bool or a string property.
2015-11-02 13:59:12 -08:00
Colin Cross
f72ef5023c Fix bugs in CloneProperties and related functions
Add tests for CloneProperties, CloneEmptyProperties and ZeroProperties
and fix detected bugs related to nil pointers to structs and interfaces
containing nil pointers to structs.
2015-10-31 20:10:20 -07:00
Colin Cross
8169500cdd Move CloneProperties to clone.go
Move CloneProperties, CloneEmptyProperties, and ZeroProperties from
proptools/proptools.go to proptools/clone.go.
2015-10-31 20:10:20 -07:00
Colin Cross
0bc7e077eb Add helpers for extending properties to proptools
It is common for a mutator to append or prepend property structs
together.  Add helper functions to append or prepend properties in property
structs.  The append operation is defined as appending string and slices
of strings normally, OR-ing bool values, and recursing into embedded
structs, pointers to structs, and interfaces containing pointers to
structs.  Appending or prepending the zero value of a property will
always be a no-op.
2015-10-31 20:09:58 -07:00
Colin Cross
4572edddfa Add self-documenting support
The primary builder will now generate a rule to call itself with
--docs=.bootstrap/docs/<name>.html to produce an automatically
generated documentation file.

The documentation generation process is:
 - Call each factory once to get empty property structs associated
   with the module type
 - Use reflection to determine the names of the type of each property
   struct
 - Use the bootstrap_go_package modules from reading the Blueprints files
   to find the source files for each Go package used to build the primary
   builder
 - Use the go/parser module to find the type declaration for each
   property struct
 - Extract comments for the property struct and each property declaration
 - Format all the comments into HTML

Change-Id: Icae9307cc10549a30bfc14d6922824099de5a9b0
2015-06-26 10:51:44 -07:00
Colin Cross
802e9759cd Add proptools.CloneEmptyProperties
Modules that want properties that vary by variant often need to create
zeroed copies of property structs.  Add CloneEmptyProperties to proptools
that is the equivalent of calling CloneProperties and then ZeroProperties,
but is much faster because it directly creates zeroed objects.

Saves 200ms in Context.ParseBlueprintsFiles and Context.ResolveDependencies
in one case, which will be valuble when we start parsing Blueprints files
for cases where we are not regenerating the manifest, for example when
generating documentation or doing context-aware bpfmt.

Change-Id: I3d4a6af2f393886d95f27d15afc1a455d8dd5fc6
2015-05-14 15:55:10 -07:00
Colin Cross
62e681a288 Fix bug when copying slice to itself
If proptools.CopyProperties is passed two values that point same
slice then setting the destination slice to a new slice will
overwrite the source slice, and the properties struct that is both
the source and destination will have an empty slice.  Copy into
the new slice using a new reflect.Value, and then update the
destination.

Change-Id: I1bfcdc51e4278ea7c7ed81dafc928a5471219f05
2015-03-11 16:09:00 -07:00
Colin Cross
8e0c51192a Add license headers and LICENSE file
Change-Id: I6f7c7374093c0745ee4aa677480376a06648b358
2015-01-23 14:23:27 -08:00
Colin Cross
3e8e74f276 Move blueprint/* up a directory
Make integrating with go tools easier by putting the blueprint package
files in the top level directory of the git project instead of in a
subdirectory called blueprint.

Change-Id: I35c144c5fe7ddf34e478d0c47c50b2f6c92c2a03
2015-01-23 14:23:27 -08:00