{"payload":{"feedbackUrl":"https://github.com/orgs/community/discussions/53140","repo":{"id":24516823,"defaultBranch":"main","name":"dart_style","ownerLogin":"dart-lang","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2014-09-26T22:04:21.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/1609975?v=4","public":true,"private":false,"isOrgOwned":true},"refInfo":{"name":"","listCacheKey":"v0:1716009772.0","currentOid":""},"activityList":{"items":[{"before":null,"after":"4f0d88a3b67172bc61eb9c34d36c6a9ee87b6d49","ref":"refs/heads/multiple-expand-pieces","pushedAt":"2024-05-18T05:22:52.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Use all unsolved pieces on the offending line as expand pieces.\n\nThe solver works by incrementally building a up a solution by binding pieces to states one at a time. To avoid wasting time exploring solutions that are pointless, it only looks at unbound pieces in play when the first line containing overflow characters or an invalid newline as written.\n\nBefore this PR, it only looked at the *first* unbound piece on that line. Often, the first piece on the line is not the one that actually needs to split. For example, in:\n\n```dart\n// |\nvariable = function(argument);\n```\n\nHere, the first piece on the overflowing line is the AssignPiece for the `=`, but the piece we actually want to split at is the ListPiece for the argument list.\n\nTo handle that, the solver currently tries binding the first piece to all values, including State.unsplit, even though that's effectively the value the current solution used, since unbound pieces behave like they have State.unsplit. The only reason it makes a new solution and binds the piece to State.unsplit is that if that piece turns out to *not* be the one that needs to split, we can now find the *next* piece on that same line. Now that the first piece is *bound* to State.unsplit, the second piece will be the first *unbound* one.\n\nBut the end result is that we end up generating a lot of more or less redundant solutions that just bind a bunch of pieces to State.unsplit and then produce the exact same formatted result.\n\nInstead, this PR collects *all* of the unbound pieces on the first overflowing line. When it expands, it expands them all, but *doesn't* bind any of them to State.unsplit. The old formatter works the same way, but it wasn't clear to me that doing so was important for perf. It is!\n\n```\n\nBenchmark (tall) fastest median slowest average baseline\n----------------------------- -------- ------- ------- ------- --------\nblock 0.065 0.067 0.131 0.070 96.3%\nchain 1.515 1.540 1.629 1.547 172.2%\ncollection 0.169 0.173 0.189 0.175 98.6%\ncollection_large 0.896 0.926 0.959 0.925 96.5%\nconditional 0.088 0.089 0.104 0.091 179.9%\ncurry 1.651 1.667 1.689 1.668 147.9%\nflutter_popup_menu_test 0.409 0.422 0.448 0.423 116.8%\nflutter_scrollbar_test 0.154 0.159 0.176 0.159 94.2%\nfunction_call 1.428 1.457 1.625 1.463 98.1%\ninfix_large 0.680 0.702 0.776 0.708 144.4%\ninfix_small 0.163 0.167 0.193 0.169 97.5%\ninterpolation 0.090 0.093 0.120 0.094 107.0%\nlarge 4.552 4.631 4.987 4.650 90.6%\ntop_level 0.180 0.183 0.214 0.185 135.0%\n```\n\nMy goal is to get the new formatter as fast as the old one on a real-world corpus. Here's the results for formatting the Flutter repo:\n\n```\nCurrent formatter 15.890 ========================================\nOptimized 14.309 ====================================\nOld formatter 7.131 =================\nThe current formatter is 55.12% slower than the old formatter.\nThe optimized is 11.05% faster than the current formatter.\nThe optimized is 50.16% slower than the old formatter.\nThe optimization gets the formatter 18.05% of the way to the old one.\n```\n\nSo not a huge improvement, but a big step in the right direction.","shortMessageHtmlLink":"Use all unsolved pieces on the offending line as expand pieces."}},{"before":"25fa6adf5f8d3a52b0244720e5d94cd7a879c19e","after":null,"ref":"refs/heads/instrument-short-style","pushedAt":"2024-05-17T22:29:51.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"}},{"before":"6641bde54a9e8ed2f7091aad5596398b05a78bcf","after":"0160142b3444e956936388010ac2bb1294dda8b9","ref":"refs/heads/main","pushedAt":"2024-05-17T22:29:50.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Add some profiling instrumentation to the old formatter. (#1492)\n\nThis helps comparing the different phases in the two implementations\r\nagainst each other.\r\n\r\nAlso, I added support to benchmark/directory.dart to run in tall or\r\nshort style.","shortMessageHtmlLink":"Add some profiling instrumentation to the old formatter. (#1492)"}},{"before":null,"after":"976fe44d5bc21220f91b6a7c34c187cc98cbb07d","ref":"refs/heads/revamp-function-types","pushedAt":"2024-05-17T22:28:13.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Rework how function types, type annotations, and typedefs are handled.\n\nIn the process of trying to simplify the number of Piece classes, I noticed that FunctionPiece basically exists to split between the return type annotation and the rest of a function. That's pretty similar to how VariablePiece handles splitting between a variable's type annotation and name.\n\nI unified those, but then it made typedefs format funny. Looking into\nit, it's because typedefs have `=` but weren't using AssignPiece. Instead, they just never allowed splitting at the `=`. So I made that uniform with the rest of the style and used AssignPiece here.\n\nThat led to some weird looking code in cases like:\n\n Function(int someParameter) someVariable;\n\nIf that line doesn't fit, the formatter has to decide whether to split inside the type annotation or between the type and variable. There were different heuristics for return types followed by function names versus type annotations followed by variable names. Unifying those led to some weird output like:\n\n Function(\n int someParameter,\n ) Function(\n int someParameter,\n ) someVariable;\n\nThis is a variable whose type is a function that returns another function. Admittedly, no one writes code like this. Ultimately, I felt like the weirdness was from allowing the variable name to hang off the end of a split annotation. In most places in the style, if an inner construct splits, the outer one does too.\n\nSo I changed that. If a type annotation splits, then we also split after the type annotation too. That means after a return type before a function name, or after a variable type before a variable. So instead of allowing:\n\n SomeGenericClass<\n LongTypeArgument,\n AnotherLongTypeArgument\n > variable;\n\nThe split in the type argument list forces the variable name to split too:\n\n SomeGenericClass<\n LongTypeArgument,\n AnotherLongTypeArgument\n >\n variable;\n\nI think I like how this looks a little more but I'm not sure. In practice, it doesn't matter much because it's rare for a type annotation to be long enough to split, but it does happen. For what it's worth, it's consistent with metadata on variables. If the metadata splits, we also split before the variable too:\n\n @SomeMetadata(\n 'annotation argument',\n 'another argument',\n )\n variable;\n\nThoughts?","shortMessageHtmlLink":"Rework how function types, type annotations, and typedefs are handled."}},{"before":null,"after":"25fa6adf5f8d3a52b0244720e5d94cd7a879c19e","ref":"refs/heads/instrument-short-style","pushedAt":"2024-05-17T22:02:24.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Add some profiling instrumentation to the old formatter.\n\nThis helps comparing the different phases in the two implementations\nagainst each other.\n\nAlso, I added support to benchmark/directory.dart to run in tall or\nshort style.","shortMessageHtmlLink":"Add some profiling instrumentation to the old formatter."}},{"before":null,"after":"de001bf8cf99568d72c38d9376d0efcf948ee297","ref":"refs/heads/unneeded-pieces","pushedAt":"2024-05-17T21:58:11.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Reorganize ForPiece.\n\nMake that Piece just for the header part of a for statement or element.\n(We can almost get rid of this entirely and use AdjacentPiece, but it\ndoes some indentation that isn't otherwise supported.)\n\nThen to handle the body, we either write it inline if it's a block (the\nmost common), or we use IfPiece, which has the same logic. Rename\nIfPiece to ControlFlowPiece to emphasize its more general use. It was\nalready used for while statements, so this makes sense.","shortMessageHtmlLink":"Reorganize ForPiece."}},{"before":"64f24944e8f88dd3227c0d0e345a03d5d1eb83e5","after":null,"ref":"refs/heads/conditional-chain","pushedAt":"2024-05-16T00:15:59.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"}},{"before":"ce04d3834bc85b97b6cbcdec051e07a530a76c0d","after":"6641bde54a9e8ed2f7091aad5596398b05a78bcf","ref":"refs/heads/main","pushedAt":"2024-05-16T00:15:58.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Flatten chained conditionals. (#1489)\n\nWhen testing the new formatter on a large corpus, I noticed the solver\r\nwould get stuck on large conditional chains because (unfortunately), we\r\ncan't separately format the else clause of a split conditional\r\nexpression. By merging long conditional chains into a single InfixPiece,\r\nwe can separately format all but the very last dangling else clause.\r\n\r\nWhile I was at it, I also put a hard cap in the number of solutions the\r\nsolver will try in case it still gets stuck. The old formatter has a\r\nsimilar limit. It's rare for real-world code to hit this limit in the\r\nnew solver, but it's better than getting totally stuck when it happens.","shortMessageHtmlLink":"Flatten chained conditionals. (#1489)"}},{"before":"9d268da05099886058bb3922744a4d5f07e555e3","after":null,"ref":"refs/heads/subtree-merge-test","pushedAt":"2024-05-16T00:15:04.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"}},{"before":"93d2068e5e8a1abe795d2b6245d36ac5110c35f3","after":"ce04d3834bc85b97b6cbcdec051e07a530a76c0d","ref":"refs/heads/main","pushedAt":"2024-05-16T00:15:03.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Add test that tickles subtree merging. (#1488)\n\nAn important optimization in the formatter is that it will format a\r\nsubtree of the Piece tree separately and weave the result back into the\r\nparent Solution when possible. Part of that process is adding in any\r\nbound states, overflow characters, and costs determined in the subtree.\r\n\r\nSurprisingly, those rarely actually come into play in terms of affecting\r\nthe outermost winning solution. I'm not sure exactly why, but if you\r\njust merge in the subtree solution's text and discard the bound states,\r\noverflow, and cost... all the tests still pass.\r\n\r\nBut after testing on a large corpus, it turns out that in more complex\r\nreal-world examples, it *is* important to copy that data back over. So\r\nI grabbed an example whose formatting was affected and added this as a\r\nsort of regression test.","shortMessageHtmlLink":"Add test that tickles subtree merging. (#1488)"}},{"before":"5ddd749a7d24e201eb4b30defd02f5f6e8ce1879","after":"93d2068e5e8a1abe795d2b6245d36ac5110c35f3","ref":"refs/heads/main","pushedAt":"2024-05-15T20:50:54.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"scheglov","name":"Konstantin Scheglov","path":"/scheglov","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/384794?s=80&v=4"},"commit":{"message":"Require analyzer 6.5.0 and stop using deprecated nodes. (#1490)\n\n* Require analyzer 6.5.0 and stop using deprecated nodes.\r\n\r\n* Update CHANGELOG.md\r\n\r\n* Replace SDK 3.0.0 with 3.4.0 in two places.","shortMessageHtmlLink":"Require analyzer 6.5.0 and stop using deprecated nodes. (#1490)"}},{"before":null,"after":"64f24944e8f88dd3227c0d0e345a03d5d1eb83e5","ref":"refs/heads/conditional-chain","pushedAt":"2024-05-15T19:55:59.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Flatten chained conditionals.\n\nWhen testing the new formatter on a large corpus, I noticed the solver\nwould get stuck on large conditional chains because (unfortunately), we\ncan't separately format the else clause of a split conditional\nexpression. By merging long conditional chains into a single InfixPiece,\nwe can separately format all but the very last dangling else clause.\n\nWhile I was at it, I also put a hard cap in the number of solutions the\nsolver will try in case it still gets stuck. The old formatter has a\nsimilar limit. It's rare for real-world code to hit this limit in the\nnew solver, but it's better than getting totally stuck when it happens.","shortMessageHtmlLink":"Flatten chained conditionals."}},{"before":null,"after":"9d268da05099886058bb3922744a4d5f07e555e3","ref":"refs/heads/subtree-merge-test","pushedAt":"2024-05-15T18:44:16.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Add test that tickles subtree merging.\n\nAn important optimization in the formatter is that it will format a\nsubtree of the Piece tree separately and weave the result back into the\nparent Solution when possible. Part of that process is adding in any\nbound states, overflow characters, and costs determined in the subtree.\n\nSurprisingly, those rarely actually come into play in terms of affecting\nthe outermost winning solution. I'm not sure exactly why, but if you\njust merge in the subtree solution's text and discard the bound states,\noverflow, and cost... all the tests still pass.\n\nBut after testing on a large corpus, it turns out that in more complex\nreal-world examples, it *is* important to copy that data back over. So\nI grabbed an example whose formatting was affected and added this as a\nsort of regression test.","shortMessageHtmlLink":"Add test that tickles subtree merging."}},{"before":"43634ec6e8620ec29675acb688c0319c61bf961a","after":null,"ref":"refs/heads/dependabot/pub/dart_flutter_team_lints-3.0.0","pushedAt":"2024-05-15T13:31:33.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"dependabot[bot]","name":null,"path":"/apps/dependabot","primaryAvatarUrl":"https://avatars.githubusercontent.com/in/29110?s=80&v=4"}},{"before":null,"after":"52db4dfc85f44bfef375354253ef024271c2fec7","ref":"refs/heads/dependabot/pub/dart_flutter_team_lints-3.1.0","pushedAt":"2024-05-15T13:31:29.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"dependabot[bot]","name":null,"path":"/apps/dependabot","primaryAvatarUrl":"https://avatars.githubusercontent.com/in/29110?s=80&v=4"},"commit":{"message":"Bump dart_flutter_team_lints from 2.1.1 to 3.1.0\n\nBumps [dart_flutter_team_lints](https://github.com/dart-lang/ecosystem/tree/main/pkgs) from 2.1.1 to 3.1.0.\n- [Release notes](https://github.com/dart-lang/ecosystem/releases)\n- [Commits](https://github.com/dart-lang/ecosystem/commits/dart_flutter_team_lints-v3.1.0/pkgs)\n\n---\nupdated-dependencies:\n- dependency-name: dart_flutter_team_lints\n dependency-type: direct:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] ","shortMessageHtmlLink":"Bump dart_flutter_team_lints from 2.1.1 to 3.1.0"}},{"before":"4355c1c356697110c6a2b1a6473a559ba2747677","after":null,"ref":"refs/heads/aot-benchmark","pushedAt":"2024-05-15T03:04:05.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"}},{"before":"25dcdbbfed86bf49db9e46c37ce3743dc38c309f","after":"5ddd749a7d24e201eb4b30defd02f5f6e8ce1879","ref":"refs/heads/main","pushedAt":"2024-05-15T03:04:04.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Support running benchmarks in AOT mode. (#1486)\n\nSupport running benchmarks in AOT mode.\r\n\r\nMany of the optimizations I'm trying have a relatively small\r\nimprovement. That can make it hard to tell if they are actually an\r\nimprovement if there is enough variance in the runs that they are lost\r\nin the noise.\r\n\r\nAOT builds don't need warm-up time and seem to have generally lower\r\nvariance than JIT runs. Also, they are how the shipped formatter is\r\nrun in `dart format`. So this adds support to the two benchmark scripts\r\nfor running themselves in AOT snapshot mode.\r\n\r\nI added support for this directly to the scripts instead of just\r\nmanually compiling and running them on the command line (which works\r\nfine) because this way it's less error-prone. I don't have to remember\r\nto re-compile the AOT snapshot and risk using an old build which is an\r\neasy mistake to make when the only behavioral difference is (possibly)\r\nperformance.\r\n\r\nAlso, tweaked the profiler output a little.","shortMessageHtmlLink":"Support running benchmarks in AOT mode. (#1486)"}},{"before":"8a2bc0af0e3225ec94675a0239274d3fc88d74e8","after":"4355c1c356697110c6a2b1a6473a559ba2747677","ref":"refs/heads/aot-benchmark","pushedAt":"2024-05-15T01:39:10.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Fix typo.","shortMessageHtmlLink":"Fix typo."}},{"before":"8452fa7c2cc1996547b2333ced0f1505e49bbf28","after":"8a2bc0af0e3225ec94675a0239274d3fc88d74e8","ref":"refs/heads/aot-benchmark","pushedAt":"2024-05-14T22:40:04.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Use sortBy().","shortMessageHtmlLink":"Use sortBy()."}},{"before":"30fa9bbc33c259242916d3a205855680454d6037","after":null,"ref":"refs/heads/for-in-piece","pushedAt":"2024-05-14T21:44:55.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"}},{"before":"222f670f40a1b3f10e15df936b25793454d9b900","after":"25dcdbbfed86bf49db9e46c37ce3743dc38c309f","ref":"refs/heads/main","pushedAt":"2024-05-14T21:44:54.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Don't use AssignPiece for for-in loop \"in\" clauses. (#1485)\n\nDon't use AssignPiece for for-in loop \"in\" clauses.\r\n\r\nOne of the reasons that AssignPiece is so hairy is because it handles\r\nboth splitting after the operator (\"=\", \":\", etc.) and before \"in\".\r\n\r\nSplitting out for-in loops to their own Piece class lets us get rid of\r\na little of that complexity.\r\n\r\nAlso, I thought that was the only reason that the operator is a separate\r\nPiece. That's actually not true because we also need the LHS to be its\r\nown piece for applyConstraints().\r\n\r\nEven so, I still think it's a little easier to understand with for-in\r\nloops being their own piece.\r\n\r\nI also slightly tweaked the formatting of for-in loops. In the rare\r\ncase where the left side block splits, we now indent it and split at\r\n\"in\". This is consistent with the old style. I don't have a strong\r\npreference, but I think it looks a little neater this way.\r\n\r\nCo-authored-by: Nate Bosch ","shortMessageHtmlLink":"Don't use AssignPiece for for-in loop \"in\" clauses. (#1485)"}},{"before":"da86b7283522d51ad392c9c5f2771a7f85756467","after":"30fa9bbc33c259242916d3a205855680454d6037","ref":"refs/heads/for-in-piece","pushedAt":"2024-05-14T21:26:17.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Update lib/src/piece/assign.dart\n\nCo-authored-by: Nate Bosch ","shortMessageHtmlLink":"Update lib/src/piece/assign.dart"}},{"before":null,"after":"8452fa7c2cc1996547b2333ced0f1505e49bbf28","ref":"refs/heads/aot-benchmark","pushedAt":"2024-05-14T21:25:58.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Support running benchmarks in AOT mode.\n\nMany of the optimizations I'm trying have a relatively small\nimprovement. That can make it hard to tell if they are actually an\nimprovement if there is enough variance in the runs that they are lost\nin the noise.\n\nAOT builds don't need warm-up time and seem to have generally lower\nvariance than JIT runs. Also, they are how the shipped formatter is\nrun in `dart format`. So this adds support to the two benchmark scripts\nfor running themselves in AOT snapshot mode.\n\nI added support for this directly to the scripts instead of just\nmanually compiling and running them on the command line (which works\nfine) because this way it's less error-prone. I don't have to remember\nto re-compile the AOT snapshot and risk using an old build which is an\neasy mistake to make when the only behavioral difference is (possibly)\nperformance.\n\nAlso, tweaked the profiler output a little.","shortMessageHtmlLink":"Support running benchmarks in AOT mode."}},{"before":null,"after":"da86b7283522d51ad392c9c5f2771a7f85756467","ref":"refs/heads/for-in-piece","pushedAt":"2024-05-14T01:46:07.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Don't use AssignPiece for for-in loop \"in\" clauses.\n\nOne of the reasons that AssignPiece is so hairy is because it handles\nboth splitting after the operator (\"=\", \":\", etc.) and before \"in\".\n\nSplitting out for-in loops to their own Piece class lets us get rid of\na little of that complexity.\n\nAlso, I thought that was the only reason that the operator is a separate\nPiece. That's actually not true because we also need the LHS to be its\nown piece for applyConstraints().\n\nEven so, I still think it's a little easier to understand with for-in\nloops being their own piece.\n\nI also slightly tweaked the formatting of for-in loops. In the rare\ncase where the left side block splits, we now indent it and split at\n\"in\". This is consistent with the old style. I don't have a strong\npreference, but I think it looks a little neater this way.","shortMessageHtmlLink":"Don't use AssignPiece for for-in loop \"in\" clauses."}},{"before":"be665ebb2726cd08890e617adca61e9e9aa9930d","after":null,"ref":"refs/heads/remove-todos","pushedAt":"2024-05-13T21:30:26.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"}},{"before":"e49a9f33f52aac68661e96997c33eb537e846dcc","after":"222f670f40a1b3f10e15df936b25793454d9b900","ref":"refs/heads/main","pushedAt":"2024-05-13T21:30:25.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Remove a bunch of TODO(tall) and TODO(perf) comments that aren't needed. (#1484)\n\nThese are all things we have either done already, have filed issues, or\r\nI don't have any plans to do at this point.","shortMessageHtmlLink":"Remove a bunch of TODO(tall) and TODO(perf) comments that aren't need…"}},{"before":null,"after":"be665ebb2726cd08890e617adca61e9e9aa9930d","ref":"refs/heads/remove-todos","pushedAt":"2024-05-13T21:21:27.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Remove a bunch of TODO(tall) and TODO(perf) comments that aren't needed.\n\nThese are all things we have either done already, have filed issues, or\nI don't have any plans to do at this point.","shortMessageHtmlLink":"Remove a bunch of TODO(tall) and TODO(perf) comments that aren't needed."}},{"before":"201d5a50f8a15d6c8b232d4441d8b5ff0ec0234c","after":null,"ref":"refs/heads/1469-blank-line-in-list","pushedAt":"2024-05-13T21:19:50.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"}},{"before":"acbe67dade983f409b6723a82f1eb30d893d9b58","after":"e49a9f33f52aac68661e96997c33eb537e846dcc","ref":"refs/heads/main","pushedAt":"2024-05-13T21:19:49.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Preserve one blank line between elements in delimited lists. (#1483)\n\nThis is consistent with the old formatter and lets users break groups\r\nof elements into \"sections\" inside basically all delimited constructs:\r\nlists, maps, objects, argument lists, enums, etc.","shortMessageHtmlLink":"Preserve one blank line between elements in delimited lists. (#1483)"}},{"before":null,"after":"201d5a50f8a15d6c8b232d4441d8b5ff0ec0234c","ref":"refs/heads/1469-blank-line-in-list","pushedAt":"2024-05-13T20:44:39.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"munificent","name":"Bob Nystrom","path":"/munificent","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/46275?s=80&v=4"},"commit":{"message":"Preserve one blank line between elements in delimited lists.\n\nThis is consistent with the old formatter and lets users break groups\nof elements into \"sections\" inside basically all delimited constructs:\nlists, maps, objects, argument lists, enums, etc.","shortMessageHtmlLink":"Preserve one blank line between elements in delimited lists."}}],"hasNextPage":true,"hasPreviousPage":false,"activityType":"all","actor":null,"timePeriod":"all","sort":"DESC","perPage":30,"cursor":"djE6ks8AAAAETXeh9QA","startCursor":null,"endCursor":null}},"title":"Activity · dart-lang/dart_style"}