The Flutter Widget Preview feature is currently implemented within
Flutter Tools, which is responsible for detecting widget preview
annotations in the user's project. When previews are detected, the
Flutter Tool injects code generated based on the detected previews into an artificial widget_preview_scaffold project and performs a hot reload to render updates to the preview set in the scaffold application.
`package:analyzer` is currently being used to detect previews, but this comes with a significant amount of memory overhead. Since widget
previews are mostly being used from within IDEs which already have an
active analysis server, moving widget preview detection into the DAS
will remove the need for creating an additional analysis context in the Flutter Tool itself.
This change includes the initial work to move widget preview detection
into the DAS. It utilizes a pull-based mechanism, where the Flutter Tool listens for file system events and then queries the DAS using the `dart/textDocument/getFlutterWidgetPreviews` and `dart/workspace/getFlutterWidgetPreviews` LSP methods.
Each reported preview contains some generated code based on the annotation used to define the preview. This code has all constants from the original annotation evaluated to either primitive values or constant expressions with namespaces applied to each symbol, allowing for the Flutter Tool to inject this code directly when updating the generated code in the scaffold project.
Towards https://github.com/flutter/flutter/issues/179584
Change-Id: I043cb3235a66b25dda3f852ca7f147bff0e1e537
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/478100
Auto-Submit: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
The `Match.operator[]` does the same thing and is
generally recommended (and shorter).
(I want to deprecate `group` and `groups`)
Tested: Refactoring.
CoreLibraryReviewExempt: Calling equivalent function.
Change-Id: I4c758968ae622fe16b7322be1b29b05b91e7fcd9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489021
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
The test has become flaky for me recently. I believe the issue is that analysis is completing too quickly and `waitForAnalysisComplete()` starts waiting for a future analysis that never comes.
Change-Id: Ie76dffd3fbaef50eb27d5fc9692131d38553d4b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489180
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
We don't appear to have any end-to-end tests of the rename refactor (and
maybe not of other legacy refactors). We need to fix that, but that's a
bigger task than I want to include in this CL. For now I've locally built
and tested the rename on a primary constructor and verified that it
works as expected.
Change-Id: Icec20f3204c58fa219ff7df117511ed47629bd1f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489120
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
The broad idea here is that ContextLocatorImpl was not so much a
_class_ as a collection of functions with
`ContextLocatorImpl.locateRoots` as an entrypoint. This "class" had one
field (a ResourceProvider), and one public method. That public method
was 220 lines long (inscrutable to me). That method was then forced to
pass around a handful of objects to all of the internal methods, which
were all computed in `locateRoots`, and not mutated afterwards.
Secondly, `Workspace.createSourceFactory(null, null)` was called in a
half dozen positions. In order to wire up a caching mechanism, and for
tidiness, and to satisfy a TODO, we add a late final field on Workspace
for retrieving a "partial source factory."
So, the change is to make a new top-level function,
`locateContextRoots`, which does some pre-computing, instantiates a
_ContextLocator with 4 pieces of data, and calls it's `locateRoots`
method, returning the result. In extracting this pre-computing code, a
few helper functions also had to be extracted into top-level functions:
* `_resourcesFromPaths`
* `_uniqueSortedPaths`
Otherwise, the code is mostly in-tact. I made a few small cleanups to
improve readability here and there, where I was already making changes:
* In `_createContextRootsIn`, there was a giant try-catch (which was
very deep as well, try/for/if/if), but the catch was only there to
catch something thrown from the _first_ statement. So I shrunk the
size of the try-catch.
* Similarly, `_getExcludedGlobs` has a if/try/if/if/local-function that
I simplified a little.
* `_locateRoots` was renamed to `_locateRoots`, and so is sorted
different; it remains mostly intact, but is now only 140 lines,
reduced via the pre-computing code moved to `locateContextRoots`.
Change-Id: I9f95bbddd546d55b206c77112247c1a6bc770626
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488940
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
In order to support primary constructors we need to have two new
refactors that will add and remove a constructor name. Rather than
duplicate the logic in the RenameConstructor class, I want to reuse it.
In order to do that, I need to be able to pass in a ChangeBuilder.
This CL accomplishes that goal by making it possible to pass in a
ChangeBuilder to any refactoring, even though in most cases the
ChangeBuilder will be ignored. In the future I intend that all of the
refactors will be updated to use the passed in ChangeBuilder, but that
would have been too big for a single CL.
Beyond that, I did make one other change, which is that the refactor
now supports classes with an empty body (`;`). I added a test for the
new functionality, but I believe that the existing tests should be
adequate to ensure that there was no loss of functionality.
This does not add support to RenameConstructor to deal with primary
constructors. That will also happen in a follow-on CL.
Change-Id: I51749e9cd1d775744dc6e64c1dc67967ef492d45
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488527
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Add `ClassBody.members` and `EnumBody.constants`/`members` so callers
can access class and enum contents through the common body interfaces
instead of pattern matching on `BlockClassBody` and `BlockEnumBody`.
Implement empty node lists for empty class and enum bodies, update the
public API, and migrate analyzer, analysis_server, analyzer_plugin, and
linter code to use the new accessors directly. This removes the ad hoc
`members2` helper extensions and a large amount of repeated `tryCast`
and `switch` logic, making body traversal more uniform.
Change-Id: I51d75f2253c7e6f75efecae84bf0443ff5eb6788
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488263
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
We need to think about utilities we can add to `ChangeBuilder` to make
this kind of edit easier. I thought about an `addInitializer` utility,
but wasn't sure it would have other uses. I also thought about an
`addMember`, which would probably be good, but not for this use case.
More thinking is probably needed.
Change-Id: Ie30d9f4a47007b03b22a290e2ba6c72f3c5423bf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488361
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Work towards https://github.com/dart-lang/sdk/issues/61868
This adds a new notification type, 'PluginPrint'. There are several
fields and variables then named 'pluginPrint' or 'print', and I am
definitely open to changing these names, but this is the best one that
I thought of.
PluginPrint has three fields: The name of the plugin that printed, the
message that was printed, and the timestamp.
We wrap each plugin's AnalysisRule invocations with a zone, so that
the `print` handler can know the name of the plugin. The prints are
caught and sent to the server isolate as Notifications. The
PluginIsolate then stores the collected prints. The Plugins Insights
page can then retrieve them and display them.
Manual testing, with 1000 libraries that get new lint reported once per
file, I did not observe a negative performance impact.
Change-Id: Id800ae41781c15ce89d06b563878c2b0edae43d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486827
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
The main piece to this CL is to add more links in the diagnostics pages.
We add links to pubspec files in a context, and to the generated package
config files for plugins.
I also rename `writeOption` to `formatOption` as it doesn't actually
write (it just returns a String).
I also fix a few small UX issues:
* Contents page titles should break on slashes, so I just updated all
page titles to break on slashes.
* A small bug where a context with zero library cycles of size > 1
display the text "They contain" and then no more text.
Change-Id: I7c505b006872e70884bf4c59a34e0625c7663a6c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/487946
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This allows the formatter to be both ahead or behind the SDK version and still format correctly. We should not use a newer language version than the SDK is using, and we cannot use a newer version than the formatter supports.
Change-Id: I5ef27363d213f570b2eb0d3b428752aef8e76af1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/487580
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Kallen Tu <kallentu@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
The RegEx engine in the VM was updated in
e443b89f23 which caused the analyzer
analyzing the CFE to use ~150 mio instructions more.
Part of this was an increased cost in ignore comment processing which
relied on regex. Using regex before the updated engine made
`processPrecedingComments` have a cost of ~240 mio instructions,
updating the regex engine took that to ~264 mio instructions.
This CL gets rid of the regex and takes the cost of
`processPrecedingComments` to ~74.4 mio instructions a saving of about
189 mio instructions (all then analyzing the CFE and looking at output
from `valgrind --tool=callgrind`).
Benchmarking with `perf stat` with normal GC gives:
```
task-clock:u: -2.1760% +/- 1.6063% (-265608341.80 +/- 196062087.98) (12206056036.20 -> 11940447694.40)
page-faults:u: 0.2301% +/- 0.0313% (448.20 +/- 60.88) (194764.60 -> 195212.80)
cycles:u: -2.2906% +/- 1.6090% (-1180119481.60 +/- 828994273.75) (51521138476.00 -> 50341018994.40)
instructions:u: -0.3325% +/- 0.0032% (-196547942.60 +/- 1874215.18) (59120651337.60 -> 58924103395.00)
seconds time elapsed: -2.1715% +/- 1.6011% (-0.27 +/- 0.20) (12.21 -> 11.95)
seconds user: -2.2487% +/- 1.7816% (-0.27 +/- 0.21) (11.87 -> 11.60)
Comparing GC data:
'No' GC change.
```
Note that it must push the GC - the savings isn't really 2% in time.
And with GC disabled:
```
instructions:u: -0.4562% +/- 0.0029% (-185499444.00 +/- 1189012.77) (40663084597.80 -> 40477585153.80)
```
So here a saving of ~185 mio which fits okay with the data from
valgrind.
Change-Id: Ib203baeac6a93f5e37c737080fed342dbd0740a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/487021
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
The question was raised recently about whether refactors should change
the semantics of the code, and if so under what conditions. There aren't
any hard-and-fast rules, but I wanted to capture the criteria I believe
we've generally used when making this decision.
Let me know if you think I've missed, or misrepresented, something.
Change-Id: I2d02dc35aa17386ff2ae8aa73ff0dc1271170ba4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/487220
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This passes any experiments that are both enabled, and marked as "future" through to the formatter.
I extracted most uses of the formatter to use the same shared `createFormatter()` helper that sets the appropriate values. Those that didn't already have a Result to pass I added TODOs to (though one is g3 so probably would require some internal migration).
See https://github.com/dart-lang/sdk/issues/55125
Change-Id: I8f4ef4242614dc240e217cdaf99105f2a5b49dc9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486840
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This copies much of the logic from the normalize.dart standalone script.
It normalizes "workspace folders," context roots, and the Dart SDK path.
I tweaked the SessionLogger constructor to instantiate its own
`SessionLoggerInMemorySink` rather than the caller needing to call it.
And then the `SessionLoggerInMemorySink` instantiates the
`SessionLoggerFileSink` so that the caller doesn't need to worry about that. This lets the sink and the nextLogger each be final, and removes
details about what I consider "SessionLogger implementation details"
from the caller's concern.
When a SessionLogger is instantiated, it creates a LogNormalizer which
the SessionLoggerSinks use to normalize log entries.
I almost used
`WorkspacePackage.packagesAvailableTo(String libraryPath)`, but it
seemed unnecessary to require a file path (there is a TODO about
considering files in/out of the 'lib' folder, but not necessary for this
work). So I made `Workspace.packages`, as most of the subclasses
already implemented this concept.
Bug: https://github.com/dart-lang/sdk/issues/62697
Change-Id: Ic57fec490414cef7028c290614363623e88f5c15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/485260
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This adds a fix to replace the `final` with `var` in cases where the
defined field needs to be covariant because it overrides an inherited
member.
Change-Id: I2dc57253beedb89ce942ba38e7d0855a43bb3308
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486700
Reviewed-by: Samuel Rawlins <srawlins@google.com>
In addition to wiring up the fix for this one diagnostic I also changed
the naming convention for the constructors so that they will be
consistent as we add support for keywords that can't be used as a name.
Change-Id: Icf83bc7d3f33fea14165acd755889233ac8797b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486480
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This replaces the removeAwait correction producer with the awaitKeyword
producer.
The tests were moved to their new location. The test methods were not
changed, but the classes were renamed to be more appropriate.
In the process I noticed a performance improvement I could make to the
replaceKeyword producer, so I included that change here.
Change-Id: Ibff1e61762fa6d4d750d39f130d23681fee766ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486400
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This adds a fix for a newly added diagnostic.
I wrote another correction producer that removes a single keyword, but
the intent is for this one to be general enough that it can replace all
of the previous ones. I decided, however, not to try to replace all of
them in a single CL.
Change-Id: I1191021a81f3c1532235316aab6e47cf0b7c9957
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486320
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This changes `unnecessary_null_aware_operator_on_extension_on_nullable` to stop also triggering for non-null nodes because we already report `invalid_null_aware_operator` in that case, and having two diagnostics for the same problem is not useful and would make the fix run twice.
This also `exports 'package:linter/src/lint_names.dart'`, where we declare `FixProcessorLintTest`. This way, we don't need many existing `imports` for it, and this also removes those unnecessary imports.
Fixes: https://github.com/dart-lang/sdk/issues/62766
Change-Id: Iadb460e8db8eb8e020f413f371df424d768fa768
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/485500
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Auto-Submit: Felipe Morschel <git@fmorschel.dev>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This is the first CL in what will probably turn out to be a fairly large
number of CLs. The goal is to get the relevance table generator up to
date so that we could then use it to generate new tables, thereby,
hopefully, improving the ranking of completion suggestions.
It includes two sets of changes, and if it would be easier to review I
can split it into two CLs.
The first set of changes is to add visit methods for all of the AST
node classes. While the use of a recursive visitor doesn't allow the
compiler to let us know about missing visit methods, I temporarily
changed the superclass in order to ensure that all of them are
overridden. I want to do that so that we can know when a lack of data
collection is intentional vs. just an oversight.
Which is where the second set of changes comes in. This adds a
mechanism to report if the generator ever sees a keyword or identifier
for which data should have been collected but wasn't. It does this by
recording all such tokens before visiting the AST, and then removing
tokens for which data is collected and tokens that we've explicitly
decided we didn't need data for.
In future CLs I want to get it to a place where we can validate that
the generator and the code completion passes are using the same set of
keys for the generated tables. I also want to add reporting if we have
failed to record data for an expected key because that would indicate
that the corpus used to build the tables is incomplete in its coverate.
Change-Id: I9cb4b729f558884e7321abd741e7b8dc85c997ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486260
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
The fix was failing to fire for primary constructors, but this CL fixes
that. It also adds tests for primary constructors.
Along the way I was able to clean up some repeated subexpressions.
Change-Id: I1870ad7c83478b141ab2099c26b9a719f1de7468
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/485602
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This ensures that the lint that suggests the converion to a field formal
parameter doesn't fire for super parameters, and also that the assist
isn't offered in those cases.
We can consider allowing both if we find a good way to perform the
conversion, but at the moment the tools can create invalid code.
Fixes: https://github.com/dart-lang/sdk/issues/62807
Change-Id: I7b4b2011059afc8ae0fc9649d012c51a37c64472
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/485121
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>