This does a few optimizations to improve the performance of the analyzer
when watching for generated files:
- We do all the polling in a separate isolate.
- We detect when Bazel finished running and only poll afterwards.
- We use a batch interface and deliver all changes at once (instead of
one by one). This allows us to avoid resetting caches more often than
necessary.
I had to remove one of the larger tests and created an integration test
instead, since the code for detecting the Bazel builds relies on
`dart:io` directly (`ResourceProvider` does not expose a way to
check for symlink targets).
Since this required a bit more code, I've decided to create a separate
file for it (`bazel_watcher.dart`).
Change-Id: I6c2383e7fd4348ab8af1af639b10db519c7a2f33
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183010
Commit-Queue: Michal Terepeta <michalt@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This CL implements the core flow analysis infrastructure for tracking
reasons why an expression was not promoted. It supports the following
reasons:
- Expression was a property access
- Expression has been written to since it was promoted
I expect to add support for other non-promotion reasons in the future,
for example:
- `this` cannot be promoted
- Expression has been write captured
- Expression was a reference to a static field or top level variable
These non-promotion reasons are plumbed through to the CFE and
analyzer for the purpose of making errors easier for the user to
understand. For example, given the following code:
class C {
int? i;
f() {
if (i == null) return;
print(i.isEven);
}
}
The front end now prints:
../../tmp/test.dart:5:13: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
Try accessing using ?. instead.
print(i.isEven);
^^^^^^
Context: 'i' refers to a property so it could not be promoted.
Much work still needs to be done to round out this feature, for example:
- Currently the analyzer only shows the new "why not promoted"
messages when the "--verbose" flag is specified; this means the
feature is unlikely to be noticed by users.
- Currently the analyzer doesn't show a "why not promoted" message
when the non-promotion reason is that the expression is a property
access.
- We need one or more web pages explaining non-promotion reasons in
more detail so that the error messages can contain pointers to them.
- The analyzer and front end currently only show non-promotion reasons
for expressions of the form `x.y` where `x` fails to be promoted to
non-nullable. There are many other scenarios that should be
handled.
Change-Id: I0a12df74d0fc6274dfb3cb555abea81a75884231
Bug: https://github.com/dart-lang/sdk/issues/38773
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181741
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This introduces a way to see what paths have been searched for by
the `BazelWorkspace` and adds a polling-based watcher to detect
when files generated by Bazel appear (or have changed). This allows
us to re-analyze things automatically instead of, e.g., restarting
the server.
Change-Id: I60eae29b0e4fcc3a91d8d2275c6898e45548ea03
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168649
Commit-Queue: Michal Terepeta <michalt@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Previously, we were assuming that each path in `binPaths` was just one
level deeper than the corresponding source code path, and therefore we
could map a path in `binPaths` to the corresponding source code path
by just removing the first directory (e.g. map `bazel-out/foo/bar` to
`foo/bar`). But this isn't correct: the paths in `binPaths` are more
deeply nested, e.g. `bazel-out/k8-fastbuild/bin`. This CL changes the
algorithm to use `context.relative`, so that we get the correct path
mapping regardless of the nesting depth.
Change-Id: I870a7fca18e689691efcc32da527135643255eca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168127
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Generated files can exist outside of `lib`. In a Bazel workspace
these are referred to using `file:` URIs that point to the generated
code directory. We need to be able to resolve references both from
the generated code to non-generated code and vice versa.
This is blocking the use of the migration tool in Bazel workspaces,
since the migration tool doesn't have the same level of error recovery
as the rest of the analyzer, so it needs to be able to resolve all
files including generated ones. But it should also improve the user
experience for using the analysis server in general in Bazel
workspaces, by reducing the number of nuisance "URI not resolved"
errors.
Change-Id: I38dababd29f4490746cc6e1eeede9f438526a815
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153520
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
An alternative fix to https://dart-review.googlesource.com/c/sdk/+/94356
In this case, `library.source.fullName` results in a String representation
of a library's package: URI. :(
To accomplish this, each *Workspace's contains() method is refactored from
taking a `String path` to taking a `Source source`, so as to use package: URIs
as much as possible, avoiding looking at the filesystem and poking around for
Workspace markers (BUILD, BUILD.gn, WORKSPACE, .jiri-root, etc). This avoids
the issue with InSummarySource sources, which have a non-path `.fullName`, but
have a valid `.uri`.
These issues were found when trying to enforce @sealed internally.
Change-Id: Ia46f28aa7aad0fc4483a180fa47f1e509402da6a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/94985
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This implementation did not check whether the path was actually contained
in the package:build workspace. It also made an assumption about how a
resource which is a directory would be treated, which was masked by an
unconditional-and-silenced catch.
The existing test which should have caught this had a hidden exception,
caught by the same unconditional-and-silenced catch. :(
Bug: https://github.com/dart-lang/linter/issues/1393
Change-Id: I0a6ecb584e06877463a47681830eed8f6f914030
Reviewed-on: https://dart-review.googlesource.com/c/91441
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Also add a superclass to BasicWorkspace and PubWorkspace, since the bulk of their
implementation is shared; Only find() and findPackageFor() need to be separate;
the package mapping and resolving can be shared.
Change-Id: I13932d6947d6dc28fc7223594e5bd2526f12f573
Reviewed-on: https://dart-review.googlesource.com/c/89167
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>