Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[analytics] include vscode editor settings in our diagnostics report #60259

Open
pq opened this issue Mar 5, 2025 · 10 comments
Open

[analytics] include vscode editor settings in our diagnostics report #60259

pq opened this issue Mar 5, 2025 · 10 comments
Labels
area-devexp Developer experience items (DevTools, IDEs, analysis server, completions, refactorings, ...). P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug type-performance Issue relates to performance or code size

Comments

@pq
Copy link
Member

pq commented Mar 5, 2025

There have been a number of hypotheses around slowness associated w/ enablement of things like format and fix on-save actions and it would be great to find any correlations in user reports.

Settings in particular that are currently not known by server (but could help):

  • editor.formatOnSave
  • editor.codeActionsOnSave

/fyi @DanTup

@pq pq added area-devexp Developer experience items (DevTools, IDEs, analysis server, completions, refactorings, ...). P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug type-performance Issue relates to performance or code size labels Mar 5, 2025
@DanTup
Copy link
Collaborator

DanTup commented Mar 6, 2025

I started looking at this and there are two options:

  1. Request the whole editor configuration and just read the values we care about
  2. Request only the values we care about individually (editor.formatOnSave, editor.codeActionsOnSave etc.)

The first one results in all of the editor settings be included in the payload (once for global, once for each workspace folder) which isn't terrible, but also means this shows up in instrumentation logs (where it didn't before).

The second seems better, however it currently fails because in the Dart-Code extension we have middleware to set enableSnippets that assumes that the only configuration we ever fetch is an object (eg. the dart section). When requesting editor.formatOnSave (which results in a boolean), we'll try to set a field named enableSnippets on a boolean and fail.

I've opened Dart-Code/Dart-Code#5433 and will fix Dart-Code's middleware to not fail if we do (2), however it does mean we can't do (2) until that fix has been out enough time that we're happy to break compatibility with older versions of the extension (or, we use the version of the extension as an indicator of whether to request these values).

@DanTup
Copy link
Collaborator

DanTup commented Mar 6, 2025

Another idea is that we send a separate configuration request for the values we care about for the report here, and handle if the request fails (eg. because the middleware throws). That should give us the best of both worlds (although we still need to fix the Dart-Code middleware for the second request to succeed).

@DanTup
Copy link
Collaborator

DanTup commented Mar 6, 2025

I found another problem with this... It seems we are unable to fetch language-specific configuration with this API. Eg. if the user has:

"editor.formatOnSave": false,
"[dart]": {
	"editor.formatOnSave": true
}

By fetching editor.formatOnSave we get false, and fetching [dart].editor.formatOnSave just returns null. I think the only way to get the real value would be to fetch the configuration in the context of a Dart file, but that means finding a valid Dart file to use (we could pick the first from the known files list, but it's starting to feel quite hacky).

Given these settings are VS Code-specific anyway (there's nothing in LSP that suggests an editor should use editor.formatOnSave as the key for storing such a setting), another option could be for Dart-Code to pass this data to the server instead (it can easily read settings from the Dart-language-specific settings without a specific file and already does this in some places).

There are a few different ways this could be passed to the server:

  1. Call a custom method to provide diagnostic info that will be included in the report (and displayed somewhere on the diagnostic pages)
  2. Include it in a new key inside initializationOptions (we already show these in the diagnostic pages, and arguably should include these values in the report too)
  3. Include it in ClientCapabilities.experimental (where we put some other non-standard LSP data, such as enabling the non-standard snippet syntax for CodeActions), which again already shows up in the diagnostic pages, and could also be added to the collected report

My feeling is that (3) is probably the better of those three, but since I suggest we add initializationOptions to the report anyway, including it there could be convenient (even if it doesn't actually affect initialization).

@bwilkerson interested in your thoughts too.

@DanTup
Copy link
Collaborator

DanTup commented Mar 6, 2025

Another option:

  1. We copy any useful editor settings into the "dart" settings in the Dart-Code middleware that handles the configuration request from the server. That is, when the LSP server asks Dart-Code for configuration, we provide a synthetic "dart.formatOnSave", "dart.codeActionsOnSave", etc. - which are the values from the Dart-scoped editor settings. Then we extract those values (or if they're in a sub-object, that whole sub-object) for the report.

@FMorschel
Copy link
Contributor

Note: I'm not sure if this is relevant because I'm not sure I fully understand where this info will be.

Since running the analyzer from source is slower than from the snapshot, maybe informing that setting is defined, can be good for us to review the data gathered for timings.

@DanTup
Copy link
Collaborator

DanTup commented Mar 6, 2025

Note: I'm not sure if this is relevant because I'm not sure I fully understand where this info will be.

There's a "Collect Report" button at the top of the diagnostic site (which you can launch from VS Code with the Dart: Open Analyzer Diagnostics command) that creates a json report that can be shared to help debug issues.

Since running the analyzer from source is slower than from the snapshot, maybe informing that setting is defined, can be good for us to review the data gathered for timings.

If we were to include this, I would guess there's a more reliable way to know we're running from the snapshot (for ex. Platform.script?) - although given the steps involved to set up an SDK and run from source, I suspect the number of people who do so could be counted on a small number of fingers.

@pq
Copy link
Member Author

pq commented Mar 7, 2025

Options 3 and 4 seem reasonable to me but don't feel super strongly.

Anyway, thanks for digging in! I do think this will be really useful in diagnosing issues.

@DanTup
Copy link
Collaborator

DanTup commented Mar 11, 2025

I'm thinking that maybe it could be useful in future to include additional non-setting information in that diagnostic report that is known to Dart-Code but not the server, so maybe adding something to capabilities.experimental specifically for this purpose that can hold configuration and non-configuration would be best?

For example:

"experimental": {
  "diagnosticInfo": {
    "foo": "bar",
    "settings": {
      "global": { // global settings
        "editor.formatOnSave": true,
      },
      "workspaceFolders": [ // settings for each workspace folder in the workspace (if different to global)
        {
          "editor.formatOnSave": false,
        },
        {
          "editor.formatOnSave": false,
        }
      ]
    }
  }
}

One slight drawback of doing it up-front like this is that if the user modifies it during the session, we'll have stale values. That's probably not terrible though?

@bwilkerson
Copy link
Member

Assuming that we care about these settings for debugging purposes, then we should probably do this in a way that allows the server to get updated information when it changes. That probably means a custom notification?

@pq
Copy link
Member Author

pq commented Mar 11, 2025

I love the idea of capabilities.experimental to capture things like this.

we should probably do this in a way that allows the server to get updated information when it changes

It's more work but I'm inclined to agree. It could be really confusing for debugging if the data we were working with was stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-devexp Developer experience items (DevTools, IDEs, analysis server, completions, refactorings, ...). P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug type-performance Issue relates to performance or code size
Projects
None yet
Development

No branches or pull requests

4 participants