Repository navigation
Diagnostics stop showing when some kinds of errors are produced (ex: invalid_constant with a missing required argument produces an invalid range) #5359
Description
Describe the bug
there is a specific file (lib/auth/auth_bloc.dart) where changes will not trigger analysis (ie. if I delete a semicolon, nothing happens). Code actions will suggest fixes for the problems, but the UI does not show the error itself.
I have opened the file as a txt just to make sure there weren’t any hidden annotations, and there are no files in the excluded folders for both user and workspace.
I have spent quite some time trying to solve this, and irritatingly copy and pasting the code into a new file even as separate blocks does not work. Running flutter analyze and dart analyze command in the terminal will notice the changes.
If I restart my computer, any errors that exist in the file are found: they are in the problems tab, and the visual ques in the editor work as expected. However, if I then introduce an error to the file or fix an existing error the changes are not reflected in the problems tab.
If I run analyze in the terminal, fixed problems no longer appear, but the error message persists in the problem tab. Restarting the language server will erase all of the problems, regardless of if they exist or not; in both the visual ques and the problems tab. The most baffling part is that for every other file the dev tools operate normally. And I have copied over the folder to a new project and the errors persist, which can be seen here, but i have scoured the files for anything that would tell the analyzer to ignore it and I cannot find any hidden files.
I have yet to test on a clean install of vs code and I copied the Auth folder over within vs code; I have not completely ruled out my VS code install and config being a problem. I have debugged to the point that to do so any further systematically would require a greater understanding of the internals of dart-code than I possess.
Restarting the following proved futile:
- dart analyser
- the language server
- vs code
- my computer
To Reproduce
This is a sneaky bug I am not sure how i broke it because it took a while for me to notice. I can copy the file into a new project and the behaviors persist, in identical fashion, which I will call reproduction. That copy is available here: https://github.com/klukshu/inconsistent_code_analysis.
Expected behavior
When i make an error (ie, delete a semi colon), i would expect that it would show up in the problems tab and a visual cue to appear on screen but it does not.
I am curious if this problem will persist on other people's machines, I have attached a bare-bones repository, with the problematic file and all it's direct dependencies, no effort was made to make the program buildable. The behavior of auth_bloc.dart in this project is the same as in the project I copied it over from.
Workspace Environment
Dart Code extension: 3.100.0
Flutter extension: 3.100.0 (activated)
App: Visual Studio Code
App Host: desktop
Version: linux 1.95.3
Workspace type: Flutter (LSP)
Workspace name: inconsistent_code_analysis
Dart (3.5.1): redacted
Flutter (3.24.1): redacted (Linux (linux-x64/linux))
Output from 'dart info'
If providing this information as part of reporting a bug, please review the information
below to ensure it only contains things you're comfortable posting publicly.
General info
- Dart 3.5.1 (stable) (Tue Aug 13 21:02:17 2024 +0000) on "linux_x64"
- on linux / Linux 6.8.0-49-generic Errors when opening "dart like" files outside of workspace root #49-Ubuntu SMP PREEMPT_DYNAMIC Mon Nov 4 02:06:24 UTC 2024
- locale is en_CA.UTF-8
Project info
- sdk constraint: '^3.5.1'
- dependencies: bloc, cupertino_icons, flutter
- dev_dependencies: flutter_lints, flutter_test
Process info
| Memory | CPU | Elapsed time | Command line |
|---|---|---|---|
| 68 MB | 0.1% | 04:16 | dart devtools --machine --allow-embedding --dtd-uri ws:/gg2YLdGUIGhJSDxj |
| 574 MB | 2.5% | 04:16 | dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.100.0 |
| 80 MB | 0.1% | 04:16 | dart tooling-daemon --machine |
Output from 'flutter doctor'
[✓] Flutter (Channel stable, 3.24.1, on Linux Mint 22 6.8.0-49-generic, locale en_CA.UTF-8)
• Flutter version 3.24.1
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 5874a72aa4 (3 months ago), 2024-08-20 16:46:00 -0500
• Engine revision c9b9d5780d
• Dart version 3.5.1
• DevTools version 2.37.2
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
• Android SDK at
• Platform android-35, build-tools 35.0.0
• ANDROID_HOME =
• Java binary at:
• Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
• All Android licenses accepted.
[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✗] Linux toolchain - develop for Linux desktop
✗ clang++ is required for Linux development.
It is likely available from your distribution (e.g.: apt install clang), or can be downloaded from https://releases.llvm.org/
✗ CMake is required for Linux development.
It is likely available from your distribution (e.g.: apt install cmake), or can be downloaded from https://cmake.org/download/
✗ ninja is required for Linux development.
It is likely available from your distribution (e.g.: apt install ninja-build), or can be downloaded from https://github.com/ninja-build/ninja/releases
• pkg-config version 1.8.1
✗ GTK 3.0 development libraries are required for Linux development.
They are likely available from your distribution (e.g.: apt install libgtk-3-dev)
[✓] Android Studio (version 2024.1)
• Android Studio at /usr/local/android-studio
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
[✓] VS Code (version 1.95.3)
• VS Code at /usr/share/code
• Flutter extension version 3.102.0
[✓] Connected device (1 available)
• Linux (desktop) • linux • linux-x64 • Linux Mint 22 6.8.0-49-generic
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 2 categories.
i was also using usernamehw.errorlens but enabling and disabling it did not change the behavior.
Activity
klukshu commentedon Dec 2, 2024
I've done some more digging, by editing the code in auth_bloc.dart, now I am able to effectively toggle the analyzer. This project uses bloc state management. Each bloc has states it can be in all being extensions of Abstract class AuthState, for convenience the AuthStates have a required parameter
isLoading. For reasons I have yet to understand: if theisLoadingfields are omitted from the expression, the analyzer freezes, but addisLoadingback in and the analyzer starts updating again immediately. This is only the case for the two specific uses below, the other places whereisLoadingis used do not cause this problem:Versus
I added isloading retroactively to the
abstract class AuthStateand I did not apply appropriate fixes until after I made that change.klukshu commentedon Dec 2, 2024
here are the changes i made, the changes in auth state are not important. The behavior only occurs if the emitted states in AuthChooseEmail and AuthChooseSMS do not have their required parameters.
klukshu/inconsistent_code_analysis@767ffae...8cf9525
DanTup commentedon Dec 3, 2024
I was able to reduce this to the following file:
However, changes outside of this file seemed to cause the issue to go away (for example deleting the empty
test.dartfile!). I can't explain that, but I found the following in the dev console:The issue is that in our diagnostics, we have an invalid negative number:
It appears that sometimes this error prevents any diagnostics showing, and other times it doesn't. That's a bit odd, but probably not relevant once we fix the underlying issue.
DanTup commentedon Dec 3, 2024
Ah, the reason sometimes it doesn't happen, is that we sometimes get a second
publishDiagnosticswhich has an also-incorrect, but not negative value:This one doesn't error (because it's not invalid), but is also not correct.
DanTup commentedon Dec 3, 2024
@bwilkerson I believe this is happening because of this code here:
https://github.com/dart-lang/sdk/blob/16742172774255f7be73b8d62bcf90c6309c4d32/pkg/analyzer/lib/src/dart/constant/evaluation.dart#L2987-L2995
It produces a diagnostic context message like this:
The value of
evaluationResult.offsetcomes from theargumentConstantinside_InstanceCreationEvaluator.evaluate:But in this case (where there is no argument), this returned object has an
offsetof-1and alengthof1. This -1 offset ultimately gets back to the client and the VS Code LSP client throws an exception because of the invalid position.I'm not sure where the best fix is for this..:
argumentConstanthere not use-1for the missing argument?evaluationResult.offsetfall back to using someting like_constructor.offsetif the evaluation result offset is-1?-1offsets?[-]Inconsistent error behavior[/-][+]Diagnostics stop showing when some kinds of errors are produced (ex: invalid_constant with a missing required argument produces an invalid range)[/+]bwilkerson commentedon Dec 6, 2024
Sorry for the long delay.
It's been a long time since I looked at this code, so I don't have a lot of context to answer these questions.
Is "The error is in the super constructor invocation ..." true in this case? It sounds like the message we ought to be generating is something to the effect that a required argument is missing (although that ought to already be reported, so maybe we just need to create a valid result of unknown value and not report anything).
If we should be reporting an evaluation error here, what is the offset when the argument exists? Is it the offset of the argument that was evaluated, or something else? If it's the former, then using the offset of the constructor invocation seems reasonable to me.
We shouldn't ever have a context message with a negative offset, and we generally try not to add defensive code without a good reason for it, so I'd rather we didn't do that, but if there aren't any better options ...
DanTup commentedon Dec 9, 2024
Yep, we currently produce two diagnostics, one for the missing argument, and one stating that the value is an invalid constant. It's the related information of the invalid_constant one that is trying to reference a location that's missing.
After some more digging, I realised that it wasn't trying to point at the argument at all, it was trying to point at the super parameter, but the constant evaluator creates some synthetic tokens (
_addImplicitArgumentsFromSuperFormals) and uses -1 as the offsets. Usingparameter.nameOffsetfor the name token would resolve the issue.I'll add some tests and open a CL for discussion. Thanks!
[analyzer] Use parameter.nameOffset for synthetic arguments for super…
DanTup commentedon Dec 9, 2024
Fixed by dart-lang/sdk@da13398. The change is in the Dart analysis server so will be included in a future Dart/Flutter SDK release (and not a VS Code extension release).