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 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>
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>
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>
Now that JS exceptions are caught as JS interop values in Dart,
we should warn users on the pitfalls of including a JS interop
type in the catch clause, and instead advise them to use `isA`
to do type-checks.
dart2wasm dry-run is updated to capture this lint.
There's also some minor wording changes in the lint guidance now
that `isA` can be executed on any value.
Change-Id: I65779951f2ff3f7dacfb915f3b105541c1f9a9b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483960
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
The previous set of tests missed two cases:
- a primary constructor with a private named parameter
- constructors introduced by `new`
The latter had some bugs, which are fixed in this CL.
Change-Id: I872a3948dd1b0f791dbea1354c8377e83048e618
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/484227
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This introduces a specialized message when an invocation of a
constructor with a private named parameter uses the private name in the
argument list.
It also removes the '_test' suffix from a couple of import prefixes in
the `test_all.dart` file as the use of the suffix is not the convention.
Fixes https://github.com/dart-lang/sdk/issues/62749
Change-Id: I0d2d586c2131df6d7bfe45a3e6bdf9c14c33470c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483866
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Previously, changing an ordinary formal parameter like `required int
x`, to an initializing formal parameter like `required this.x`, was
done using a single edit that replaced the entire AST node with a
newly constructed one.
This had the unfortunate disadvantage that if the formal parameter had
any annotations, (like `@visibleForTesting`), they would be removed.
The new technique is to make 3 edits:
- Insert `this.` before the name.
- If the field name is different, replace the parameter name with the
field name (this handles migration to the "private named parameters"
feature).
- If the parameter has an explicit type, and that type is the same as
the field's type, delete it.
Since I was in the neighborhood, I also generalized the code so that
it handles old-style function-typed parameters. Even though those have
fallen out of favor, the generalization was pretty easy: I just
changed the code to handle `NormalFormalParameter` rather than
`SimpleFormalParameter`, and in the case where the parameter is a
`FunctionTypedFormalParameter`, make sure to delete the parameters as
well.
Fixes https://github.com/dart-lang/sdk/issues/62764.
Change-Id: I6a6a69642291c5c4cc639725f6a36cb884f6d9bd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483841
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
When the field is private and the parameter is named, the assist will
change the name of the parameter, but this requires a change to all
references to the parameter. Most were being handled, but the comment
references were not. This CL fixes that.
Change-Id: I9607eb8aa01a100e1c0015019c862838bd2eccb7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483842
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Primary constructors introduces the ability to use `new` in place of
a class name in a constructor. The previous changes to code completion
missed this, but this CL causes `new` to be suggested at the beginning
of a member.
Change-Id: I56ac6d3d8649e55de264f6e4f91b4c5db2e37c92
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483322
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
ConvertToInitializingFormal can convert an initializer to an initializing formal, or an assignment statement in the body:
```dart
class C {
int x;
C(int x) {
this.x = x;
}
}
```
When converting from an assignment statement, if there are no statements left in the block, it deletes the entire function body.
Prior to this CL, it would also erroneously delete any initializers that happened to be on the constructor:
```dart
// Before:
class C {
int? x;
int? y;
C(int? x) : y = 1 {
this.x = x;
}
}
// Result of applying fix:
class C {
int? x;
int? y;
C(this.x); // Oops! Where did ": y = 1" go?
}
```
Change-Id: I5bd27e925509adc82056b71f4c96432c819bc954
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/482966
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Auto-Submit: Bob Nystrom <rnystrom@google.com>
This handles the most of the cases I could think of. Please review with
an eye toward catching holes. I also left a couple of questions in the
tests as there are a couple of cases I wasn't sure we wanted to support.
This doesn't handle fields with an initializer, though I think we could.
If you think we ought to handle it before shipping the feature I can either
update this CL or do it in a follow-on.
Change-Id: Ia9ac5d86853bc907fdce10e31f03714eeb89f1af
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/481621
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>