)]}'
{
  "log": [
    {
      "commit": "b48d4aea8540a44355c7fe4cfbb2d835490bad72",
      "tree": "3034ad8fbc9372d79b029ef86f300a220b4a25d3",
      "parents": [
        "03355656777936dbac057bd43d2d8ef65434fb59"
      ],
      "author": {
        "name": "Jiyong Park",
        "email": "jiyong@google.com",
        "time": "Wed Feb 24 00:56:48 2021 +0900"
      },
      "committer": {
        "name": "Jiyong Park",
        "email": "jiyong@google.com",
        "time": "Wed Feb 24 01:02:59 2021 +0900"
      },
      "message": "propertyIndexesWithTag can handle slice of struct\n\nThe function now can traverse into a field whose type is slice of\nstruct. When reading field values from the returned indexes, Soong will\ncheck if the next field is a slice of struct or not. If so, it will\nrecurse into all the values in the slice.\n\nBug: 181018147\nTest: m nothing\nChange-Id: Ib8a7b7911a0be37a6dc03079adeb906497e60875\n"
    },
    {
      "commit": "e09509592d34f4491a371045c218fdf2bfbccd0d",
      "tree": "8b3db2eb0d71a7a734bdfcaa2730a98da2a6cbb3",
      "parents": [
        "22343ff42c4443ce84f86f147c46bf4200b0acd5",
        "1ac43bd65a55065fc9803af51344baa9d7fdff87"
      ],
      "author": {
        "name": "colincross",
        "email": "ccross@android.com",
        "time": "Thu Jan 28 10:28:04 2021 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jan 28 10:28:04 2021 -0800"
      },
      "message": "Merge pull request #338 from francois-berder/optimize-hastag\n\nOptimize HasTag function"
    },
    {
      "commit": "1ac43bd65a55065fc9803af51344baa9d7fdff87",
      "tree": "2e80128b02a256ebf82103270b7c6603cb8af4d9",
      "parents": [
        "53e92a0de6c2528401cbf5cf3b1be9958fbe99e9"
      ],
      "author": {
        "name": "Francois Berder",
        "email": "francois.berder@arm.com",
        "time": "Mon Jan 18 14:02:09 2021 +0000"
      },
      "committer": {
        "name": "Francois Berder",
        "email": "francois.berder@arm.com",
        "time": "Thu Jan 28 14:28:34 2021 +0000"
      },
      "message": "Optimize HasTag function\n\nThe commits optimizes HasTag function by avoiding\nthe call to strings.Split that allocates a list of strings.\n\nHasTag is called from the ExtendProperties family of functions.\nSo this new implementation would benefit any primary builder\nthat extensively uses property appending.\n\nAdd a small benchmark for HasTag function.\nIt shows that HasTag is speed up by a factor of 2-3 with the new\nimplementation.\n\nBefore:\ngoos: linux\ngoarch: amd64\nBenchmarkHasTag/NoTag-56         \t20000000\t       118 ns/op\nBenchmarkHasTag/EmptyTag-56      \t20000000\t       120 ns/op\nBenchmarkHasTag/OtherTag-56      \t10000000\t       131 ns/op\nBenchmarkHasTag/MatchingTag-56   \t10000000\t       177 ns/op\nBenchmarkHasTag/ExtraValues-56   \t 5000000\t       392 ns/op\nBenchmarkHasTag/ExtraTags-56     \t10000000\t       183 ns/op\n\nAfter:\ngoos: linux\ngoarch: amd64\nBenchmarkHasTag/NoTag-56         \t200000000\t        11.5 ns/op\nBenchmarkHasTag/EmptyTag-56      \t200000000\t        11.5 ns/op\nBenchmarkHasTag/OtherTag-56      \t50000000\t        25.2 ns/op\nBenchmarkHasTag/MatchingTag-56   \t20000000\t        61.4 ns/op\nBenchmarkHasTag/ExtraValues-56   \t20000000\t        94.3 ns/op\nBenchmarkHasTag/ExtraTags-56     \t20000000\t        79.1 ns/op\n\nSigned-off-by: Francois Berder \u003cfrancois.berder@arm.com\u003e\nChange-Id: Ib45498e9ad6aebeca2beddea63543da40c0b1a21\n"
    },
    {
      "commit": "3adb2409648d6f8b25354ac47f083dae87731f10",
      "tree": "c2a2bf6ce948954736c6b52033880045936b3f38",
      "parents": [
        "f6ef1558843fc847e15dd11516e20f098b1ad325"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jan 15 20:09:51 2021 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jan 15 22:21:28 2021 -0800"
      },
      "message": "Fix silently ignoring values assigned to map properties\n\nValues assigned to map properties were silently ignored instead of\nreported as an error.  Add a check when recursing into structs that\nthe value is a map.\n\nFixes: 177706602\nTest: m nothing\nTest: TestUnpackErrors\nChange-Id: Ic56aeb1b9da6d5c86b6d98adae7bddb60c450404\n"
    },
    {
      "commit": "f6ef1558843fc847e15dd11516e20f098b1ad325",
      "tree": "e1f0f69093fa1747d4dd1054bd08929d3beb9665",
      "parents": [
        "461d95061e8d6df642359fe202d71f8bd83b1d9d"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jan 15 22:04:38 2021 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jan 15 22:21:28 2021 -0800"
      },
      "message": "Use UnpackError for incorrect property type errors\n\nReturning a fmt.Errorf error causes Blueprint to identify the error\nas an \"internal error\", return an UnpackError instead.\n\nBug: 177706602\nTest: TestUnpackErrors\nChange-Id: I19fba134ad778d08d5a4d90a0335bdf8cbea6a20\n"
    },
    {
      "commit": "461d95061e8d6df642359fe202d71f8bd83b1d9d",
      "tree": "da5370f31b8fff287af6885622da7aa129c0210c",
      "parents": [
        "53e92a0de6c2528401cbf5cf3b1be9958fbe99e9"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu Jan 23 22:33:21 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jan 15 22:21:28 2021 -0800"
      },
      "message": "Improve unpack testing\n\nAdd more tests, give the tests names, run them as subtests, and add\nbenchmarks.\n\nTest: unpack_test.go\nChange-Id: Iff22538ce44ed503d5d088cfb55673448db998f1\n"
    },
    {
      "commit": "de4d9f94ac235bfe9d809733c19059841ba6b090",
      "tree": "d9529ff00c7437189f10fa3e36c607375dda3d47",
      "parents": [
        "29fdcad56c45d04ce50f1eacf7936396b8d81f7d"
      ],
      "author": {
        "name": "Sasha Smundak",
        "email": "asmundak@google.com",
        "time": "Tue Mar 03 17:36:00 2020 -0800"
      },
      "committer": {
        "name": "Sasha Smundak",
        "email": "asmundak@google.com",
        "time": "Tue Mar 03 17:42:38 2020 -0800"
      },
      "message": "Fix bug in buildPropertyMap in previous commit.\n\nProperty value should be evaluated before proeprty map is populated with\nit. Added the test for this case.\n"
    },
    {
      "commit": "29fdcad56c45d04ce50f1eacf7936396b8d81f7d",
      "tree": "1a1c3be5371dc7eecfeb903456b236407a73ea16",
      "parents": [
        "c42ef965a0b1d20efcf6d9bc3be001bef4e5199c"
      ],
      "author": {
        "name": "Sasha Smundak",
        "email": "asmundak@google.com",
        "time": "Tue Feb 11 22:39:47 2020 -0800"
      },
      "committer": {
        "name": "Sasha Smundak",
        "email": "asmundak@google.com",
        "time": "Mon Mar 02 17:26:20 2020 -0800"
      },
      "message": "Implement list of maps\n\nAllow property value to be a list of maps, e.g.\nmy_module {\n  my_list: [\n    { name: \"foo\", value: 42, something: true, },\n    { name: \"bar\", value: 34, something: false, },\n  ],\n}\n\nTest: internal\nChange-Id: I2fc37d692aac39f23c9aa7bda2859ab49f3bc672\n"
    },
    {
      "commit": "fc6efcb4a45c743d8a823da5a226d3c511a86328",
      "tree": "ceefd754dc9c0e9523da7b3f656822125db45634",
      "parents": [
        "d851df9adab099c234c6939110470e648493d9b8"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Feb 05 17:10:18 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Feb 05 17:13:08 2020 -0800"
      },
      "message": "Fix PropertyNameForField for X86.\n\nField \"X86\" has no lowercase runes and was being left uppercase.\nChange the new PropertyNameForField rules to lowercase the name unless\nit has any uppercase rune after the first rune (which is always\nuppercase) and no lowercase runes.\n\nBug: 148865218\nTest: proptools_test.go\nChange-Id: Ifd1c10fc03f5ae1765d25b3f73dba8fd61c5c956\n"
    },
    {
      "commit": "3bbbdf31e3128da64ebe87caf6715cde4173b8d2",
      "tree": "61d91f82245af11fc3232c4db71ca151d5d4d26e",
      "parents": [
        "38e095ae8a2a275909967ff8d771e59a71370505"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Feb 05 13:45:11 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Feb 05 13:50:28 2020 -0800"
      },
      "message": "Support unpacking capitalized property names\n\nSoong config variables may propagate an uppercase name from Make.\nBlueprint properties have traditionally been all lowercase, and\nusing an uppercase property struct field name resulted in a strange\nBlueprint property name with the first rune lowercase and the\nremaining runes uppercase.\n\nUpdate the rules for proptools.PropertyNameForField to not lowercase\nthe first rune if the field name has mulitple runes and is not all\nuppercase.\n\nFixes: 148865218\nTest: proptools_test.go\nChange-Id: I8de2f65ffb00e5a8ce0aea0caf09f5859315f6b8\n"
    },
    {
      "commit": "5d57b2d34751d7075f4968e7a512a70c82a49fcd",
      "tree": "cacc76f500086b85a4bd2a1ecd81095a7a0409d4",
      "parents": [
        "6898d26054b1be7dc3b774b7f5445726df4c3068"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Mon Jan 27 16:14:31 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Jan 28 09:51:19 2020 -0800"
      },
      "message": "Make proptools functions consistently take *struct types\n\nThe proptools functions took an inconsistent variety of\nstruct and *struct types.  Some methods even took a struct\nbut returned a *struct.  Make all the exported methods\ntake a *struct, with internal helpers for the ones that need\nto take a struct.\n\nTest: proptools tests\nChange-Id: I60ce212606e96adcef66c531d57f69c39e1a1638\n"
    },
    {
      "commit": "6898d26054b1be7dc3b774b7f5445726df4c3068",
      "tree": "750aa90f6f9c6be7a6e22ae6eb1f3c8710560341",
      "parents": [
        "0c4d1db0a0fd0affb77a9175872256ba4eea1524"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Mon Jan 27 16:48:30 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Jan 28 09:51:19 2020 -0800"
      },
      "message": "Add isStruct and isStructPtr helpers\n\nTest: proptools tests\nChange-Id: I7814b2138cd19b538a3a33036a15119e118d7644\n"
    },
    {
      "commit": "571f77a60d6be13362d1078d0866c5dbd72936b2",
      "tree": "bcc6cc0e2041e35d20079e0130c3cf6d9528d477",
      "parents": [
        "b89d91c67ccfefc8ff0293dbe1fa931c491137c1"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Mon Jan 20 17:12:29 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Jan 21 11:49:27 2020 -0800"
      },
      "message": "Remove blueprint:\"filter(*)\" tag support\n\nThe filter tag is unused, replaced with FilterPropertyStruct to\ngenerate a new type at runtime that only contains the filtered\nfields.\n\nTest: unpack_test.go\nChange-Id: Id91cf99290832094d05426f3263279836f0fea73\n"
    },
    {
      "commit": "b89d91c67ccfefc8ff0293dbe1fa931c491137c1",
      "tree": "48f93341777e932fd5ef45161b0f3b5ddae6a8ef",
      "parents": [
        "6ea3f9ddd2fc8ec9815c8e4c7095bff91f0714c8"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jan 17 16:52:47 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Jan 21 11:49:27 2020 -0800"
      },
      "message": "Make FilterPropertyStructSharded smarter\n\nFilterPropertyStructSharded was just sharding the top level\nproperties into groups of 10.  For nested property structs\nthis can be insufficient - there could be a single top level\nproperty with many properties below it.\n\nTake a maximum name size, and track the size used by parent\nstructs to determine when sharding a nested struct is necessary.\n\nBug: 146234651\nTest: filter_test.go\nChange-Id: I5b5ed11ea27a0325b2fd6c2c3fb427ea1e2af0c2\n"
    },
    {
      "commit": "f27c5e470bcc33c79fd46eb28d0c04bd87a5bff4",
      "tree": "add19ecf5d07636be2392e26ab86759cec4647f3",
      "parents": [
        "9672d86a8772216311a1bc4dede23c41664c8bc7"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu Jan 02 09:37:49 2020 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu Jan 02 20:32:51 2020 -0800"
      },
      "message": "Move unpackProperties to proptools and export it\n\nTest: unpack_test.go\nChange-Id: I145369323bd7d5003a261c13dfb8ed31d0be51b5\n"
    },
    {
      "commit": "10f27f8139d692f7b6e801cf8df691a10fe46469",
      "tree": "5863c8495f72b5245b4168faed406a8d741ff809",
      "parents": [
        "eda08050f37590ae3e5fe0da7cb1d9888f893643"
      ],
      "author": {
        "name": "Jiyong Park",
        "email": "jiyong@google.com",
        "time": "Fri Nov 15 18:31:56 2019 +0900"
      },
      "committer": {
        "name": "Jiyong Park",
        "email": "jiyong@google.com",
        "time": "Tue Nov 19 10:45:58 2019 +0900"
      },
      "message": "Slice properties can be replaced\n\noverride_* in Soong requires a module to override certain properties of\nother module. In that case, values of a slice property (e.g. []string)\nshould be replaced by the same property value in the overriding module.\nHowever, since proptools only supports Append and Prepend orders where\nthe original values are kept for slice properties, the behavior\ncouldn\u0027t be implemented. To support the use case, Replace order is\nintroduced, in which case slice property values are completely replaced.\nFor other types of properties, the Replace order behaves exactly the\nsame as the Append order.\n\nBug: 144338929\nTest: m\n\nChange-Id: Iae9feda035177fe6a22e6e8319c0fdaa9e08e85e\n"
    },
    {
      "commit": "1907836ad9dd955f361bd64091ca698bf883a4ea",
      "tree": "92e05954cdde1853ab47b24bf4acb519de4ff6cf",
      "parents": [
        "5639ec157c031da85c67d63432558d34c636c2f6"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Sep 25 11:23:13 2019 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu Sep 26 14:21:40 2019 -0700"
      },
      "message": "Add proptools.FilterPropertyStruct\n\nMove some code from Soong to support creating a property struct\nat runtime by filtering fields out of another property struct.\n\nTest: TestFilterPropertyStruct\nChange-Id: Ic5ae390a885195bebad6f3ecb7c752c0582a60b1\n"
    },
    {
      "commit": "66c0b13553afbf4d2482e274f542120c75a00339",
      "tree": "1b8a2a99e143e29bd643c0edaead40bce93ea834",
      "parents": [
        "884e7374fbb3f7d8e43ae9da5e9d2628a7e676f1"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Sep 25 11:25:04 2019 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Sep 25 14:52:54 2019 -0700"
      },
      "message": "Add proptools.Int and proptools.IntDefault\n\nAdd proptools.Int and proptools.IntDefault that behave analogously\nto proptools.String and proptools.StringDefault.\n\nChange-Id: I41fd3417c973c9ff4a5aa6680546b4b893784745\n"
    },
    {
      "commit": "c067251da0d423e2062acf8caaa53b6c7226b3c8",
      "tree": "db5e9aa641d13d60840e7ff867fd86cda3be5a28",
      "parents": [
        "1589d6586b53b75c51fd443a144f4e5a6a71c308"
      ],
      "author": {
        "name": "Jaewoong Jung",
        "email": "jungjw@google.com",
        "time": "Mon Jul 08 13:40:28 2019 -0700"
      },
      "committer": {
        "name": "Jaewoong Jung",
        "email": "jungjw@google.com",
        "time": "Mon Jul 08 14:07:45 2019 -0700"
      },
      "message": "Fix/improve comments on prepending/appending props\n\nTest: N/A\nChange-Id: Id95afbea7fbccddafb9f2f0e068967d5547cc469\n"
    },
    {
      "commit": "4764fa76fee447ff51ff8e26c9fbbb030bd850f8",
      "tree": "54038209e688f0fd740446bbace9f164404c0334",
      "parents": [
        "94423de30732512a4ffc1209c4fc20702046639d"
      ],
      "author": {
        "name": "Jaewoong Jung",
        "email": "jungjw@google.com",
        "time": "Sat Jun 22 11:19:34 2019 -0700"
      },
      "committer": {
        "name": "Jaewoong Jung",
        "email": "jungjw@google.com",
        "time": "Sat Jun 22 11:22:55 2019 -0700"
      },
      "message": "Make off-the-shelf order funcs public.\n\nThese are useful outside the package too when calling\nproptools.ExtendMatchingProperties.\n\nChange-Id: I054eb105e0dd5287aff99b8be137a8b09d52492d\n"
    },
    {
      "commit": "7d699c37ecbd6f02d245403464dcd815939a81c5",
      "tree": "bc3f1c20a60f8300175b838c545f132840e807ea",
      "parents": [
        "a9df65135910b587d20fcca22b330d492c20cf05"
      ],
      "author": {
        "name": "Jaewoong Jung",
        "email": "jungjw@google.com",
        "time": "Thu Mar 07 14:01:22 2019 -0800"
      },
      "committer": {
        "name": "Jaewoong Jung",
        "email": "jungjw@google.com",
        "time": "Thu Mar 07 16:24:56 2019 -0800"
      },
      "message": "Panic when copying private properties.\n\nWhen CopyProperties comes across private properties, it silently ignores\nthem. This is error-prone and can result in a bug very hard to debug if\nthe developer is unaware of the behavior.\n\nChange-Id: Id6a0752e384ec7fed35728c1e87dbfa95fea84f2\n"
    },
    {
      "commit": "a4f6a3bebfc2104625cac13946a9f2f45895f5b3",
      "tree": "88f6ace5fca1716c3230ef6a330eb8faeea8b177",
      "parents": [
        "17a0b9644053af3d227672901d662daf8b9f005c"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Mar 05 16:34:45 2019 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Mar 05 19:47:43 2019 -0800"
      },
      "message": "Add PropertyIndexesWithTag\n\nAdd a function that returns all of the indexes to properties in\na property struct that are tagged with `name:\"value\"`.\n\nTest: proptools/tag_test.go\nChange-Id: I00294934c1a0383c8b64ecaabc0e138682efb2e5\n"
    },
    {
      "commit": "284c742a3322e1f0a02df7aefb7a3be071bbcff2",
      "tree": "75912ae8cf6c2fda205429961c176176d7bd0a15",
      "parents": [
        "02c110735d44497cca7a2ca28956d815dddcd7c6",
        "cc1ec0fedc0e74183891973c327d21201734c585"
      ],
      "author": {
        "name": "colincross",
        "email": "github@colincross.com",
        "time": "Thu Feb 28 11:14:02 2019 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Feb 28 11:14:02 2019 -0800"
      },
      "message": "Merge pull request #219 from colincross/escape_list\n\nReplace *Escape with *EscapeList"
    },
    {
      "commit": "937efab2e60b0fdcb623b31032f6624bff792aa8",
      "tree": "1d8d46f7892b8eb115ffd312eebf2b6b9ab0bdb4",
      "parents": [
        "de7afaaf749957b3b7c03036e36c99a5ac7e3afb"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Jan 23 13:24:26 2019 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Jan 23 13:26:42 2019 -0800"
      },
      "message": "Use sync.Map for type field cache\n\nThe type field cache was using an atomic pointer to an immutable\nmap, which required copying the entire map each time a cache\nentry was added.  Profiling showed that this was a significant\nhot spot.  Use sync.Map instead.\n\nChange-Id: Ie7c779c5e9e2be1cd530747d74025dcfd206763a\n"
    },
    {
      "commit": "12392ca0f1e84f16f38e51060c0492f3e40b3dad",
      "tree": "955cac33363e8d915a3ab1acae49aea51bd02df3",
      "parents": [
        "c54f732470c40e79b3e1151c24936acdd787eca0"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Oct 02 21:57:47 2018 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Oct 03 14:29:12 2018 -0700"
      },
      "message": "Allow mutated property structs to contain slices of non-strings\n\nProperty structs can now contain slices of structs and other\nnon-strings as long as they are tagged with `blueprint:\"mutated\"`.\n\nTest: clone_test.go\nTest: unpack_test.go\nChange-Id: Ib77348dc6e7314a24f17caba10040f7d3ac54e54\n"
    },
    {
      "commit": "cc1ec0fedc0e74183891973c327d21201734c585",
      "tree": "bd035ec59d0845e95b0df9cada2fe9a87ce52bdd",
      "parents": [
        "0799fad550029be4109db6d81189edf20eb720c7"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Sep 19 16:05:43 2018 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Sep 19 16:17:10 2018 -0700"
      },
      "message": "Replace *Escape with *EscapeList\n\nNinjaEscape and ShellEscape operated on lists, which led to\nawkward NinjaEscape([]string{s})[0].  Replace NinjaEscape\nand ShellEscape with NinjaEscapeList and ShellEscapeList,\nand add new NinjaEscape and ShellEscape functions that\noperate on a string.\n\nTest: m checkbuild\nChange-Id: I283d92cdddc8e0066a300015863a3eab66f77c23\n"
    },
    {
      "commit": "de3ef3a66e2979e4390768f0b066d560844d69c3",
      "tree": "484cca0e9a288b94df5c7f543fc0a703468ebad5",
      "parents": [
        "ff2c5b4cc808246366338b6d31aa5616e08f113d"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Apr 10 14:53:40 2018 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Apr 10 16:51:47 2018 -0700"
      },
      "message": "Add proptools.BoolDefault and proptools.StringDefault\n\nI get the logic wrong every time I try to make a *bool property\nthat defaults to true.\n\nChange-Id: Idc409921c3a4baecf611acf348176f261712cb92\n"
    },
    {
      "commit": "f586544ab7711c1e50e26852d3a4005520cf3d0c",
      "tree": "f287ad39f59d3180cc58dc742b4d71320c009d30",
      "parents": [
        "eb6192cf669ca2a0db71dcd41674fdfc6a6563c4"
      ],
      "author": {
        "name": "Nan Zhang",
        "email": "nanzhang@google.com",
        "time": "Wed Nov 01 14:03:28 2017 -0700"
      },
      "committer": {
        "name": "Nan Zhang",
        "email": "nanzhang@google.com",
        "time": "Thu Nov 02 22:10:47 2017 -0700"
      },
      "message": "Support parsing int64 in Blueprint file.\n\nSupport int64 number instead of int to be more fixed to bit size so\nthat the underlying arch won\u0027t affect overflow cases. Besides,\nrefection: func (v Value) Int() int64 always cast to int64 no matter the\ninput is int, int16, int32. Currently we always treat \"-\" as negative\nsign to bind to next value, and \"+\" as plus operator to add operands\ntogether.\nSo we allow:\na \u003d 5 + -4 + 5 or a \u003d -4 + 5\nBut we don\u0027t allow:\na \u003d +5 + 4 + -4 since we don\u0027t treat \"+\" as a positive sign, otherwise,\na \u003d 5 + +5 would exist which looks pretty weird. In the future, we may\nwant fully support number calculator logic eg, \"+\"/\"-\" can be\npositive/negative sign or operator, and \"(\" and \")\" will be considered\nto group expressions with a higher precedence.\n\nint \u0026 uint properties within struct keeps unchanged, which is only\nallowed when tagged with \u0027blueprint:mutated\u0027. We only allow *int64\nproperty instead of int64 property within struct since it does\u0027t make\nsense to do prepending or appending to int64.\n\nChange-Id: I565e046dbd268af3538aee148cd7300037e56523\n"
    },
    {
      "commit": "05b3607c378dc6557d64ae6cecee3f7fe1b22b13",
      "tree": "c3f9c4383f7d31fdb03778283380e21893bb31bd",
      "parents": [
        "5fe225f5f976f191e0f9fd543e7b5b74ad388bd9"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jul 28 17:51:37 2017 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Aug 01 15:12:12 2017 -0700"
      },
      "message": "Replace unpack\u0027s replace semantics with append\n\nBlueprint was using \"replace\" semantics when unpacking properties\ninto property structs, meaning if a module factory pre-set property\nvalues they would be overwritten by whatever was in the Blueprint\nfile.  This is different than what would happen if the same property\nwas updated using the Append*Properties functions in proptools, which\nwould use \"append\" semantics, which append strings and lists,\nlogically ORs booleans and replaces pointers to strings and booleans.\nReplace unpack\u0027s semantics with append semantics for consistency.\nAny previous users of pre-set properties can move to using a pointer\nto a string or boolean if they want the old behavior.\n\nTest: unpack_test.go\nTest: extend_test.go\nChange-Id: I02eebe80916e578938142f8e76889bd985223afc\n"
    },
    {
      "commit": "41ca49ff91e2c7beb4d39b44ee6131aad7bb4106",
      "tree": "4a5806d21bb81a273a4aa7f843a0da04d6cbfb44",
      "parents": [
        "f5909d9cb5e309886007c4720f6b3d344cf0a479"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu Sep 29 13:19:34 2016 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu Sep 29 14:31:40 2016 -0700"
      },
      "message": "Add proptools functions to escape strings\n\nBlueprint properties that end up as command line arguments need to be\nboth ninja and shell escaped.  Provide helpers that primary builders can\nuse to appropriately escape them.\n\nChange-Id: Ifd697d87edb1c6f0a910377835c391bbe8f95b42\n"
    },
    {
      "commit": "bf2adbfee205902e5bc189e8f6f64d3554e15fd5",
      "tree": "95b7cfba55668041cbac0d1c6ad40c85032be4d1",
      "parents": [
        "7fda24e54b22831888ce5f2a6d168de2cf7cb006"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Aug 19 18:16:33 2016 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Mon Aug 22 15:35:17 2016 -0700"
      },
      "message": "Relax type requirements when extending properties\n\nAllow using ExtendMatchingProperties to extend pointer to a struct or an\ninterface containing a pointer to a struct using a struct, and\nvice-versa.\n\nAlso fixes a pre-existing bug where extending a nested structure could\nfail if there were multiple possible destnations and some of them did\nnot have a matching nested property.\n\nChange-Id: I6e69d78eb6595ba7dd2603e3aa7dd8de3f292744\n"
    },
    {
      "commit": "c3d731258a343d4b52dd91b873498a6d080e61f4",
      "tree": "3ba61e8353a63db77d92909ef4dff251f13abce5",
      "parents": [
        "aec881da86b7965a5c165f59117cc94bfb097717"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Aug 05 17:19:36 2016 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Aug 05 17:19:36 2016 -0700"
      },
      "message": "Support nil pointers to structs in properties\n\nAllow primary builders to reduce allocations of empty structures by\nallowing nil pointers to concrete struct types.  Property readers will\nnot recurse into nil pointers, property writers will replace the nil\npointer with a pointer to the zero value of the pointer element type.\n\nAllows a \u003e50% primary builder time improvement with a trivial change in\nSoong.\n\nChange-Id: If6ad674bf7bf2a694c335378a074643a97d3c50b\n"
    },
    {
      "commit": "01ee36eeeaf21fdb8517f63470de1e034dbecb66",
      "tree": "9cc04b97015d8ab3051f359d39e02b5713914197",
      "parents": [
        "9544a07d2f869e7f60e32f02d7d620a6aacc16d5"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue May 17 13:57:12 2016 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Aug 05 14:00:30 2016 -0700"
      },
      "message": "Optimize proptools\n\nproptools cloning and extending are a significant portion of the run\ntime for Soong.  Optimize out calls to reflect.Type.Field(), which must\nallocate a []int to store the index, by caching all the fields of each\ntype as it is seen, and by iterating over a slice of cached fields\ninstead of calling Field(i) for each one.  Also avoid calling\nreflect.Value.Interface() twice on the same Value.\n\nChange-Id: I4e13fc85f30d8614a5586283e928c0a6d7f24809\n"
    },
    {
      "commit": "75c4701ed279254350a86f1e9bfb9a22b173a283",
      "tree": "16a1d7752756b107c6bd7e3da6d6769c536f74ce",
      "parents": [
        "bfeb5df158e87f64d36b658d1c05a5452eadcfd9"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu May 05 15:58:02 2016 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu May 05 16:23:19 2016 -0700"
      },
      "message": "Support ExtendProperties that can append or prepend\n\nExtendProperties is the same as AppendProperties or PrependProperties,\nbut takes a function that determines whether each property should be\nappended or prepended.\n\nChange-Id: I26e400d56d75a88bab9c27c382ee5321bc623ee5\n"
    },
    {
      "commit": "4c00085f2dd3d2cd3cac61bfe9f8e5d84fe27bd0",
      "tree": "5d915f3939aca6912172f6960380673ec4d0cd82",
      "parents": [
        "bd93c9a39cec9854aa34979687c5c1a6d127b299"
      ],
      "author": {
        "name": "Dan Willemsen",
        "email": "dwillemsen@google.com",
        "time": "Tue Jan 05 14:16:04 2016 -0800"
      },
      "committer": {
        "name": "Dan Willemsen",
        "email": "dwillemsen@google.com",
        "time": "Tue Jan 05 14:16:04 2016 -0800"
      },
      "message": "AppendProperties: Replace *strings instead of appending\n\nThis makes *string values act like *bool values -- instead of appending\nor prepending the contents of the string, the entire string is replaced.\nThe use case here is for overriding filenames, where appending doesn\u0027t\nwork.\n"
    },
    {
      "commit": "9d1469d55967c45fc9b985efda9ceddd1a74a934",
      "tree": "9e4f7e19560352dc2d5e2e4b976322750a1df322",
      "parents": [
        "83cedbec8582347a12b4233a34b269eebab3b0e6"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Nov 20 17:03:25 2015 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Nov 20 17:26:52 2015 -0800"
      },
      "message": "Support embedded anonymous property structs\n\nAllow property structs to contain anonymous embedded structs and\ninterfaces.  Properties in an anonymous embedded struct or interface are\ntreated as if they were properties in the embedding struct.\n"
    },
    {
      "commit": "83cedbec8582347a12b4233a34b269eebab3b0e6",
      "tree": "ec18cfd7c6f071300642f0cd3312ba772a39b21c",
      "parents": [
        "5c11f817e1c09deaa0fc23b49d8defa679fc2f61"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Nov 20 17:01:25 2015 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Nov 20 17:26:52 2015 -0800"
      },
      "message": "Fix ZeroProperties bug on nested interfaces\n\nZeroProperties was setting nested structs to their zero value, even if\nthey contained an interface that should be recursed into, not replaced\nwith nil.\n"
    },
    {
      "commit": "e4b0d3596697858cfcf6dd3e4ab376a2905c8e2c",
      "tree": "3c9f9ef4f586e3c8b2aae37e131c7767e00718ec",
      "parents": [
        "80117687294aaebcdc1df11a456cd1655e58ab8d"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Mon Nov 02 14:58:10 2015 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Mon Nov 02 15:40:55 2015 -0800"
      },
      "message": "Add proptools.TypeEqual\n\nWhen appending properties, it may be necessary to determine if two\nproperty structs are the same \"type\".  A simple Go type comparison is\nnot sufficient, as there may be interface{} values in the property\nstructs that contain different types.  Add proptools.TypeEqual that\nreturns true if they have equal types and all embedded pointers to\nstructs and interfaces to pointers to structs have the same nilitude and\ntype.\n"
    },
    {
      "commit": "80117687294aaebcdc1df11a456cd1655e58ab8d",
      "tree": "31c3add8cd2d3de933a36e8e2b41e70e6a7b9d72",
      "parents": [
        "ecca05efb23c43093afeb97a922cdfdb7c6248f6"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Oct 30 15:53:55 2015 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Mon Nov 02 13:59:12 2015 -0800"
      },
      "message": "Add property support for pointers to bools and strings\n\nThe only append semantics for bool that result in a no-op when the zero\nvalue is appended is to OR the two values together, but that is rarely\nthe desired semantics.  Add support for *bool and *string as property\ntypes, where appending a nil pointer is a no-op.  For *bool, appending a\nnon-nil pointer replaces the destination with the value.  For *string,\nappending a non-nil pointer appends the value.\n\nThis also provides a more reliable replacement for\nModuleContext.ContainsProperty, as the  build logic can tell that the\nproperty was set, even if it was set by a  mutator and not by the\nblueprints file, by testing against nil.\n\n[]string already provides these semantics for lists.\n\nSetting a *bool or *string property from a blueprints file is the same\nsyntax as setting a bool or a string property.\n"
    },
    {
      "commit": "f72ef5023cd2554eb28bc9457c1d3b64575ecc43",
      "tree": "ec1344f2b9bedc30aaac45360413ebd91fc9be4e",
      "parents": [
        "8169500cddbbfc89dc62381aaaa6fcff4fd6b4cc"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Oct 30 11:42:57 2015 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Sat Oct 31 20:10:20 2015 -0700"
      },
      "message": "Fix bugs in CloneProperties and related functions\n\nAdd tests for CloneProperties, CloneEmptyProperties and ZeroProperties\nand fix detected bugs related to nil pointers to structs and interfaces\ncontaining nil pointers to structs.\n"
    },
    {
      "commit": "8169500cddbbfc89dc62381aaaa6fcff4fd6b4cc",
      "tree": "50be7f02288130ed8fc4e8a85194290d6ce7d99f",
      "parents": [
        "0bc7e077ebfe716c6353c6fe5b9c01087867ee12"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Oct 30 13:19:14 2015 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Sat Oct 31 20:10:20 2015 -0700"
      },
      "message": "Move CloneProperties to clone.go\n\nMove CloneProperties, CloneEmptyProperties, and ZeroProperties from\nproptools/proptools.go to proptools/clone.go.\n"
    },
    {
      "commit": "0bc7e077ebfe716c6353c6fe5b9c01087867ee12",
      "tree": "97397f676755e70ca8e9a133faa115b2f0afcde6",
      "parents": [
        "75c938b6ed6b97a2b7a695a37ba6af160c3289fb"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Tue Oct 27 18:15:15 2015 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Sat Oct 31 20:09:58 2015 -0700"
      },
      "message": "Add helpers for extending properties to proptools\n\nIt is common for a mutator to append or prepend property structs\ntogether.  Add helper functions to append or prepend properties in property\nstructs.  The append operation is defined as appending string and slices\nof strings normally, OR-ing bool values, and recursing into embedded\nstructs, pointers to structs, and interfaces containing pointers to\nstructs.  Appending or prepending the zero value of a property will\nalways be a no-op.\n"
    },
    {
      "commit": "4572edddfa0d6288bdf71208e29d9f99f58ae583",
      "tree": "ef54ec11adffa1b9ed3efdb963771eb664fef2f1",
      "parents": [
        "4adc8194905e72bcc240ef5bf5bbb2175c329c16"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed May 13 14:36:24 2015 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Fri Jun 26 10:51:44 2015 -0700"
      },
      "message": "Add self-documenting support\n\nThe primary builder will now generate a rule to call itself with\n--docs\u003d.bootstrap/docs/\u003cname\u003e.html to produce an automatically\ngenerated documentation file.\n\nThe documentation generation process is:\n - Call each factory once to get empty property structs associated\n   with the module type\n - Use reflection to determine the names of the type of each property\n   struct\n - Use the bootstrap_go_package modules from reading the Blueprints files\n   to find the source files for each Go package used to build the primary\n   builder\n - Use the go/parser module to find the type declaration for each\n   property struct\n - Extract comments for the property struct and each property declaration\n - Format all the comments into HTML\n\nChange-Id: Icae9307cc10549a30bfc14d6922824099de5a9b0\n"
    },
    {
      "commit": "802e9759cdd1919e4ec0e655d4ad25d52f6ed6a1",
      "tree": "81ef8ab03b11625d358109fce28f654fad93423a",
      "parents": [
        "36bb07cf3cb6563a5f3b6afeddb0e811444470df"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed May 13 18:59:07 2015 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Thu May 14 15:55:10 2015 -0700"
      },
      "message": "Add proptools.CloneEmptyProperties\n\nModules that want properties that vary by variant often need to create\nzeroed copies of property structs.  Add CloneEmptyProperties to proptools\nthat is the equivalent of calling CloneProperties and then ZeroProperties,\nbut is much faster because it directly creates zeroed objects.\n\nSaves 200ms in Context.ParseBlueprintsFiles and Context.ResolveDependencies\nin one case, which will be valuble when we start parsing Blueprints files\nfor cases where we are not regenerating the manifest, for example when\ngenerating documentation or doing context-aware bpfmt.\n\nChange-Id: I3d4a6af2f393886d95f27d15afc1a455d8dd5fc6\n"
    },
    {
      "commit": "62e681a288e8a047ccd5d03f676c7655731c9a7c",
      "tree": "af418f1cba7e3563e3c0e48da86d0514c5b3d084",
      "parents": [
        "969c70342ae4e47893226d47865abc6fc5a3cc2f"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Mar 11 14:36:03 2015 -0700"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@android.com",
        "time": "Wed Mar 11 16:09:00 2015 -0700"
      },
      "message": "Fix bug when copying slice to itself\n\nIf proptools.CopyProperties is passed two values that point same\nslice then setting the destination slice to a new slice will\noverwrite the source slice, and the properties struct that is both\nthe source and destination will have an empty slice.  Copy into\nthe new slice using a new reflect.Value, and then update the\ndestination.\n\nChange-Id: I1bfcdc51e4278ea7c7ed81dafc928a5471219f05\n"
    },
    {
      "commit": "8e0c51192a64a869779ce4441c931f7a5c826857",
      "tree": "44ba80318d7256061ac9a29e19e451cb62a5faf1",
      "parents": [
        "3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@google.com",
        "time": "Fri Jan 23 14:15:10 2015 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@google.com",
        "time": "Fri Jan 23 14:23:27 2015 -0800"
      },
      "message": "Add license headers and LICENSE file\n\nChange-Id: I6f7c7374093c0745ee4aa677480376a06648b358\n"
    },
    {
      "commit": "3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2",
      "tree": "2599d6ac3c3810a41a87a709a004fc1fab4a7b74",
      "parents": [
        "6bb4af9e208ea9769ae52933e8d9f42a4e75938e"
      ],
      "author": {
        "name": "Colin Cross",
        "email": "ccross@google.com",
        "time": "Fri Jan 23 13:38:48 2015 -0800"
      },
      "committer": {
        "name": "Colin Cross",
        "email": "ccross@google.com",
        "time": "Fri Jan 23 14:23:27 2015 -0800"
      },
      "message": "Move blueprint/* up a directory\n\nMake integrating with go tools easier by putting the blueprint package\nfiles in the top level directory of the git project instead of in a\nsubdirectory called blueprint.\n\nChange-Id: I35c144c5fe7ddf34e478d0c47c50b2f6c92c2a03\n"
    }
  ]
}
