Commit graph

57 commits

Author SHA1 Message Date
Cole Faust
738bb54ded
Support variable bindings in selects
This allows us to recreate soong config value variables in selects.

This adds a new "any" pattern to selects, which is the same as "default"
except that it doesn't match undefined variables, and it's (currently)
the only pattern that can accept a binding.

The syntax looks like:
```
select(soong_config_variable("my_namespace", "my_variable"), {
    any @ my_binding: "foo" + my_binding,
    default: "other value",
})
```

Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I4feb4073172d8797dee5472f43f9c248a76c3f1f
2024-10-24 19:18:21 +02:00
Cole Faust
1e62c68bfe
Separate blueprint parsing and evaluating
Before this cl, blueprint expressions were evaluated as they were
parsed. We want to add a feature to select statements where we can
bind the value of soome value from soong into a blueprint variable,
that then can be used like a regular variable in the .bp file. This
means that select statements need to hold whole unevalated expression
trees, and have the ability to evaluate them later on when the value
of the bound variable is known.

This cl doesn't implement the new select syntax, but it does split
blueprint's parsing and evaluating into two separate stages. We also
store expressions in selects and evaluate them when the select is
resolved.

I didn't do extensive performance evaluation, but a simple comparison
of the time of `touch Android.bp && m nothing` before/after this cl
showed a 1 second speedup. (That was probably just noise)

Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I12f373719991afeb4aec76517153f32229d97ff2
2024-10-24 19:18:21 +02:00
Cole Faust
63acbad058 Fix extra newline after multiline select case bodies
Bug: 346922064
Test: go test
Change-Id: I0587ab04d463a1923440564647d0f1e1bf6d216b
2024-06-13 15:12:04 -07:00
Cole Faust
86a7abd927 Preserve type when promoting non-selects to selects
Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I1ad7e891f5422bb3587ebac1f8bda7dd5792ae3b
2024-05-22 13:40:57 -07:00
Cole Faust
3311debbb3 Support multi-variable selects and typed selects
This adds support for selecting on multiple variables at once, so that
you can do AND/OR combindations of them. For example:

select((
    arch(),
    os(),
), {
    ("arm64", "linux"): ["libfoo64"],
    (default, "linux"): ["libfoo"],
    (default, "windows"): ["libfoowindows"],
    (default, default): ["libbar"],
})

It also allows for select conditions to be boolean-typed. You can
write literal true and false without quotes to select on them. Currently
we don't have any boolean-typed variables though, so a fake one was
added for testing.

Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: Ibe586e7b21865b8734027848cc421594cbd1d8cc
2024-04-12 16:33:01 -07:00
Cole Faust
0173a2268b Rename default select branch to 'default' keyword
Previously I was using an underscore to denote the default branch
because I was thinking that I would allow variable bindings in the
select branches, and 'default' could be mistaken for the name of a
variable. But I think it's better to just introduce alternate syntax,
like `default @ my_var: "foo" + my_var,` to do the variable bindings,
so that we can have a clearer name for the default case.

Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: Ied762694e453855c03dd471898ebb52e97a5a671
2024-04-04 12:02:46 -07:00
Cole Faust
021cc8f5b8 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
2024-04-02 16:35:33 -07:00
Cole Faust
d2f1141871 Get rid of some extra newlines in bpfmt
Bug: 323382414
Test: go tests, and I also ran both the old/new bpfmts on the whole aosp source tree, and the only difference between the results was one extra removed line in external/uwb
Change-Id: I4942c9247a66f1de5028de39caa5cd34b66093c3
2024-03-19 17:07:00 -07:00
Cole Faust
6437d4e737 Select statements
Select statements are a new blueprint feature inspired by bazel's select
statements. They are essentially alternative syntax for soong config
variables that require less boilerplate. In addition, they support
making decisions based on a module's variant, which will eliminate
the need for manual property struct manipulation, such as the arch
mutator's arch: and target: properties.

In order to support decisions based on the variant, select statements
cannot be evaluated as soon as they're parsed. Instead, they must be
stored in the property struct unevaluated. This means that individual
properties need to change their type from say, string, to
Configurable[string]. Currently, only configurable strings, bools, and
string slices are supported, but more types can be added later.
The module implementation must call my_property.Evaluate(ctx) in order
to get the final, resolved value of the select statement.

Bug: 323382414
Test: go tests
Change-Id: I62f8721d7f0ac3d1df4a06d7eaa260a5aa7fcba3
2024-03-06 15:00:39 -08:00
William Escande
a74d05b939 bpfmt: Test comment line while sorting arrays
Test: bpfmt test
Change-Id: I4a11ac200a7b10d3abb76db78f4be2ef772763cf
2023-05-17 15:17:49 -07:00
David Duarte
65aa5a505f bpfmt: Preserve line of comment when sorting arrays
When given as an input
```
array: [
    "a",
    // Unicorn
    "b",
]
```
bpfmt with `-s` option was outputing
```
array: [
    "a", // Unicorn
    "b",
]
```

Which is not ideal because the comment was targetting
the second value and now it seems to be targetting the
first one

This patch preserve the difference in line number between
the value and the comment to give the same output when
```
array: [
    "a",
    // Unicorn
    "b",
]
```
is given as input

Test: Manual tests + run bpfmt -w -s on packages/modules/Bluetooth
Change-Id: I2b58f20da463bea77c22a4e6978aa9beb4b4fcc8
2023-05-17 13:36:13 -07:00
Sam Delmerico
08bd504b62 ignore bp files from PRODUCT_SOURCE_ROOT_DIRS
Soong analyzes the entire source tree even though not every lunch target
needs to know about every module. For example, OEM sources can be
ignored for cuttlefish products. This functionality allows blueprint to
ignore a list of undesired directories.

Bug: 269457150
Change-Id: Icbbf8f3b66813ad639a7ebd27b1a3ec153cbf269
2023-03-27 14:43:07 -04:00
Colin Cross
31c10a12c8 Fix panic in parser when first token is invalid
newParser was calling p.next(), which could trigger a scanner error
that results in a panic.  Move the first p.next() into parse(p), which
correctly converts the paanic into a reportable error.

Bug: 254831383
Test: TestParserError
Change-Id: I2a427010379bb8dd5087550c7f159499cbb84066
2022-10-21 14:38:52 -07:00
Usta Shrestha
49cd656217 Merge "Fix misspelling. Oversight from the CL split after rebasing. Test: N/A" 2022-08-09 14:40:35 +00:00
MarkDacek
14349ea8b8 Fix misspelling. Oversight from the CL split after rebasing.
Test: N/A

Change-Id: I164990624e54bc234f5b9802345addd459e2c249
2022-08-09 14:38:16 +00:00
Mark Dacek
562ed0d84f Merge "Add multiple property and replace functionality to bpmodify. Test: go run bpmodify.go -w -m=libcore-memory-metrics-tests -property=something,static_libs,deps,required,test_suites -replace-property=ahat:ahat_lib,general-tests:something -s ~/aosp-master-with-phones/libcore/metrictests/memory/host/Android.bp go test -v" 2022-08-09 14:37:00 +00:00
MarkDacek
856507f4d2 Add multiple property and replace functionality to bpmodify.
Test: go run bpmodify.go -w -m=libcore-memory-metrics-tests -property=something,static_libs,deps,required,test_suites -replace-property=ahat:ahat_lib,general-tests:something -s ~/aosp-master-with-phones/libcore/metrictests/memory/host/Android.bp
go test -v

Change-Id: I005b6dd675beb205f544e89c729fe9191e6470c2
2022-08-08 17:58:11 +00:00
Usta Shrestha
290e675625 Revert "Add support for maps in blueprint files."
This reverts commit 42cb28f66e.

Reason for revert: Dead code - map type properties in Module

Change-Id: Ie944a311963cc54258cbc4ba3fc974882e5539ce
2022-08-02 10:55:21 -04:00
Alix
145d5a8c83 added moveProperty contents functionality to bpmodify
bpmodify can know move the contents of a property into another
property using moveProperty. After moving the contents, the original
property is deleted.

Bug: 226636335
Change-Id: Id68d11d59f00909b4c93aa78666d14f433f236fb
Test: manually ran on several Android.bp files in bug 226636335
2022-07-25 19:38:40 +00:00
Jooyung Han
451dd63611 bpmodify: -add-literal to add a value to the list
-a works with only string values. When we need to add numbers, booleans,
or even structs, -add-literal can be used now.

  bpmodify -m foo -property list-of-ints -add-literal 123
  bpmodify -m foo -property list-of-structs \
    -add-literal "{key: \"value\"}"

Bug: 146436251
Test: go test ./bpmodify
Change-Id: I91d23d7bf89491643aa595f5ebccd9410a9cbb09
2022-02-09 11:16:02 +09:00
Jooyung Han
0cb1064428 Add newlines around list of structs
Since a struct(parser.Map) occupies multiple lines, adding newlines
around brackets([]) looks better even the list has only a single value.

  prop: [ {
    name: "foo",
  }],

vs

  prop: [
    {
      name: "foo",
    },
  ],

Bug: n/a
Test: go test ./parser
Change-Id: I1a574aa038a26235848b6c9b5b4f01a0ab2c8c00
2022-02-09 11:10:12 +09:00
Treehugger Robot
00895de89a Merge "Add support for maps in blueprint files." 2022-01-27 21:36:45 +00:00
Liz Kammer
42cb28f66e Add support for maps in blueprint files.
This limits support to allow-listed property names to prevent
proliferation of map types requiring additional support to migrate.

Test: go test blueprint tests
Test: m nothing && diff build.ninja & Android-aosp_arm.mk -- no changes
Change-Id: Id12637462f19ac5de1b562f63507de989a51600d
2022-01-26 12:18:31 -05:00
Usta Shrestha
53bc344a81 Blueprint to support multiline (Go style raw) strings
Bug: 206961391
Test: m nothing and diff the ninja files
Change-Id: I9a7ffafe6a3992bf05180a032f4b277cbecb7dc6
2022-01-19 22:58:01 +00:00
Usta Shrestha
ee7a5d7a16 Typos and missing parameter names use in doc comment
Test: N/A
Bug: N/A
Change-Id: I01331365925decef22502da02a23ed4ce610da98
2022-01-18 16:46:30 -05:00
Colin Cross
eb15c126c3 Fix numericStringLess and add tests
numericStringLess("1a", "11a") would strip the equal prefix "1" and
then compare the bytes "a" and "1", when it should have compared the
numbers 1 and 11.  Fix it by handling the case where the last equal
byte was numeric and the first differing byte is numeric in one
string and non-numeric in the other.

numericStringLess("12", "101") would strip the equal prefix "1" and
then compare the numbers 2 and 01, when it should have compared the
numbers 12 and 101.  Fix it by tracking the beginning of the sequence
of numeric bytes containing the differing byte.

Test: sort_test.go
Change-Id: I8d9252a64625ba6a3c75d09bb1429dcb1115e3e1
2021-03-08 17:59:55 -08:00
Jooyung Han
53e92a0de6
bpmodify: support numerical sort (#332)
bpmodify sorts touched list respecting numbers embedded in strings. For
example, "foo-2" comes before "foo-10".

Test: bpmodify_test.go
Change-Id: If2fe9bc871a463a47dd3c0b52982b34c9fde05f0

Co-authored-by: Jooyung Han <jooyung@google.com>
2020-12-14 11:30:48 -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
Sasha Smundak
77418b70b4 Fix null pointer dereference printing an expression.
Parser.parseVariable method should always set the value of the variable
it creates. Failure to do so may end up in the following:

```
$ androidmk  <(printf "FOO:=(X)\nFOO:=bar\n")
parse error:
<input>:3:1: variable already set, previous assignment: FOO@<input>:1:5 = %!s(PANIC=String method: runtime error: invalid memory address or nil pointer dereference) (%!s(PANIC=String method: runtime error: invalid memory address or nil pointer dereference)) false
```

The cause is that calling Parser.Parse to parse `FOO=abc` created
a Variable instance with nil value, causing panic on print attempt.

Test: m androidmk && androidmk  <(printf "FOO:=(X)\nFOO:=bar\n")
(should print:
ERROR:  parse error:
<input>:3:1: variable already set, previous assignment: FOO@<input>:1:5 = X = Not Evaluated (X = Not Evaluated) false)

Change-Id: I296d7984df6d8796e0075f9eb692b234f8c94f08
2020-01-23 13:32:43 -08:00
Logan Chien
3deba3df45 Emit errors on mixed property syntax
This commit refines `compat` condition in `parseProperty()` so that a
module definition would either use the new syntax or the old syntax,
but not something in the between, such as

    cc_library {
        name: "bad_example",
        srcs= ["bad.c"],
    }

Test: lunch aosp_arm64-userdebug; make  # runs unit test
Change-Id: If2d3e5d55edccc28d314d99b83b0f54e5c53ac35
2018-06-26 12:20:08 +08:00
Dan Willemsen
d2c8162ca9 Improve indentation for multi-line expressions
When someone used a multiline string:

    cmd: "..." +
         "...",

bpfmt used to print this out as:

    cmd: "..." +
    "...",

This change doesn't do the quote alignment like I see in some of our
user-created instances of this, but it does indent a single level:

    cmd: "..." +
        "...",

Test: unit tests
Test: Compared bpfmt results before and after across AOSP
Change-Id: I61bf790be9d08a187857b2725facf71e8b38e372
2018-05-07 16:15:33 -07:00
Colin Cross
957b39cba5 Add Patch and PatchList for making textual changes
Patch and PatchList provide an API for making changes to substrings
of a Blueprint file by parsing the AST and using the token positions
to perform text replacements.

Test: modify_test.go
Change-Id: Ibb8993221982b54602ba5a05486198fab8d35a67
2018-04-10 16:50:39 -07:00
Colin Cross
fdeaf881f4 Make End() return the position after the node
End() was previously only used to determine if a comment was within
a Node, so it used the expedient definition of the position of the
last token in the node.  In the next patch it will be used for
capturing substrings of the Blueprint file, so make it point to
the character after the last token instead.

Also add tests for it.

Test: parser_test.go
Change-Id: Icaff3915b41e251ef9d0aad5615021bf37406aee
2018-04-10 16:43:51 -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
Jeff Gaston
a1dae80bbb Utils to support removing duplicate shared_libs
Bug: 62957047
Test: m -j
Change-Id: I50d61d2c4a15af571d3bd5ca95f8ff7e3f18c382
2017-06-28 14:38:05 -07:00
Jeff Gaston
5d4b9d8fde Some util functions to support bpfix
Change-Id: If53f696fbe937e007b902434f62d0d92435846dd
2017-05-23 17:51:44 -07:00
Colin Cross
ba5bf880bf Fix error messages containing variable types
value.Type and value.Pos changed to methods, change the users that were
not caught by error checking to use Type() or Pos().

Change-Id: I295a658c007fa2de68c89fb85ee367fbea5ed1aa
2016-07-15 16:43:42 -07:00
Colin Cross
6b6735d3be printer: support multiple skipped comments
There may be multiple skipped comments in a row, convert
p.skippedComments to a list and add a test.

Change-Id: I30dcff269bee56fd51ef9513dab7c7885c44b7d7
2016-07-12 16:12:09 -07:00
Colin Cross
1e73794d42 Add CommentGroups
Determining which comments are contiguous is difficult once they have
been parsed into an out-of-band comment list, as any intervening nodes
are in a separate structure.  Group the comments into CommentGroups
during the parsing stage instead.

Change-Id: I9444c58e75333b7521b58dbfbd36ff29d139b6e3
2016-06-14 15:26:49 -07:00
Colin Cross
1ead6452b5 Make everything a Node
Make File, Assignment, and Module implement Node.  Nodes will be used
later for traversing a File.

Change-Id: I938a5d39d48aee7fe174180b12a2870ecf756b34
2016-06-14 15:26:49 -07:00
Colin Cross
b3d0b8dab4 Rename Pos members
Pos is going to be part of the Node interface, rename the Pos member
of structs to be more specific.

Change-Id: Ibd31119863b96d38bf8dac216e026200a54bbe18
2016-06-14 15:26:49 -07:00
Colin Cross
c32c47938f Remove blueprint/parser.Ident
It wasn't adding anything useful, and it resulted in Name.Name to get to
the identifier.  Replace Name Ident with Name string; NamePos
scanner.Position.

Change-Id: Idf9b18b31dd563a18f27c602c2d14298955af371
2016-06-14 15:26:49 -07:00
Colin Cross
e32cc80f20 Refactor blueprint parser nodes to an interface
Refactor the blueprint parser Value object, which contained a Type enum
and members to hold every possible type, into an interface (now called
Expression).  Rename the existing Expression object that represented a binary
operator Operator.

Also adds and fixes some new printer test cases with mulitline expressions.

Change-Id: Icf4a20f92c8c2a27f18df8ca515a9d7f282ff133
2016-06-08 14:48:53 -07:00
Colin Cross
6d8780f724 Fix bugs related to local vs. inherited variables
The Go race detector found a race condition in the parser, which
 highlighted a few related bugs. A variable could be defined but
not referenced in a Blueprints file, then appended to in multiple
subdirs= Blueprints files.  The race detector caught the multiple
writes to assignment.Referenced from the parsers for the subdirs
Blueprints files, but multiple appends would be much more serious.

To fix this, keep local and inherited variables separate in the
Scope object and export that info to the parser.  Disallow
appending to non-local variables, which was already the intended
behavior.  Only update the referenced boolean for local variables.
Together, this should prevent all writes to Assignment objects
from parsers other than the one that created them.

Also improves the error handling code and some error messages.

Change-Id: Idb4f7d2e61bbe28d90b93074764e64e60d1eba8f
2015-08-03 16:08:16 -07:00
Dan Willemsen
38b0630a2a Add deep Copy() for parser types
Change-Id: I94bca46d6d30da683cacb0f6ea1fdf26a5a46bc8
2015-07-06 12:49:23 -07:00
Colin Cross
23d7aa1b68 Refactor parsing to allow reuse
Refactor parsing Blueprints and walking the Blueprints tree to
allow reuse for tasks that don't involve creating moduleInfo
structures.

Change-Id: I677857a3462999426c8306432074ea97fdcb86c8
2015-06-30 16:43:32 -07:00
Colin Cross
2108971145 Add convenience methods to Comment objects
Add String() to print out the Comment, Text() to print out the
Comment while stripping /*, //, and */, and EndLine() to return
the line number of the last line of the comment.

Change-Id: I076bc0990143acfc03c42a8cc569894fced8ee24
2015-06-30 14:33:38 -07:00
Jamie Gennis
6cafc2cddc Update import paths to include github 2015-03-21 01:03:36 -04:00
Colin Cross
96e5670496 Allow parsing Blueprints files without evaluating
Running bpfmt or bpmodify on a Blueprints file that references
variables defined in a parent Blueprints file causes parse errors
on unknown variables.  Modify the parser to parse in two modes,
parser.Parse and parser.ParseAndEval.  The first parses without
attempting to evaluate variables and expressions, the second
performs a full evaluation.

Change-Id: Ic11948ea77c8e65379d7260591ada15db0e4f5b9
2015-03-20 16:55:32 -07:00
Colin Cross
85398a916a Simplify printer whitespace and newline handling
Trying to handle all the whitespace and newline printing inside
printToken got overly complicated, and resulted in a few bugs in
the layout around comments and indentation that were hard to fix.
Rewrite the whitespace and newline handling to be handled directly
by the object printers, using requestSpace() to ensure whitespace
is inserted and requestNewline() to ensure a newline is inserted.

Also fixes unnecessarily left aligning all comments that contain
indentation, and fixes accidentally unindenting comments that are
the last token in their indented block.

Change-Id: I18707802726107cf0b6ec7de9b542d0ec1d2c0dd
2015-03-20 16:55:32 -07:00