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

Dart formatter Keeps running endlessly #3270

Closed
dewbambs opened this issue Apr 10, 2021 · 89 comments
Closed

Dart formatter Keeps running endlessly #3270

dewbambs opened this issue Apr 10, 2021 · 89 comments
Labels
awaiting info Requires more information from the customer to progress in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is bug stale Will be closed soon if no response.
Milestone

Comments

@dewbambs
Copy link

Issue Type: Bug

It's random.
At times when you save dart code. Dart formatter starts running and do not stops for several minutes (around 5 minutes minimum). I have to cancel it and save again and same thing happens.
Only solution is restart VScode or sometimes restart the PC.

Extension version: 3.21.1
VS Code version: Code 1.55.1 (08a217c4d27a02a5bcde898fd7981bda5b49391b, 2021-04-07T15:06:02.360Z)
OS version: Windows_NT x64 10.0.19041

System Info
Item Value
CPUs Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz (8 x 1992)
GPU Status 2d_canvas: enabled
gpu_compositing: enabled
multiple_raster_threads: enabled_on
oop_rasterization: enabled
opengl: enabled_on
protected_video_decode: enabled
rasterization: enabled
skia_renderer: enabled_on
video_decode: enabled
vulkan: disabled_off
webgl: enabled
webgl2: enabled
Load (avg) undefined
Memory (System) 7.89GB (1.46GB free)
Process Argv --crash-reporter-id fd9ee2dd-443c-41b6-b90c-1cb615a784b2
Screen Reader no
VM 0%
A/B Experiments
vsliv368:30146709
vsreu685:30147344
python383cf:30185419
vspor879:30202332
vspor708:30202333
vspor363:30204092
vstry244:30276681
pythonvsdeb440:30248342
pythonvsded773:30248341
pythonvspyt875:30259475
pythontb:30283811
openwsldoc:30282072
vspre833cf:30267465
pythonptprofiler:30281270
vshan820cf:30276953
pythondataviewer:30285071
vscus158:30286553

@DanTup
Copy link
Member

DanTup commented Apr 13, 2021

Can you confirm which Flutter SDK version you're on, and whether LSP is enabled (hover over the SDK version in the status bar to see whether it says "DAS" or "LSP").

I've seen this before (and a few others have noted it), although I've never been able to get a log file or repro it. If you're able to get a log when this occurs, that may be useful in tracking it down. Thanks!

@DanTup DanTup added awaiting info Requires more information from the customer to progress in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is bug labels Apr 13, 2021
@DanTup DanTup added this to the On Deck milestone Apr 13, 2021
@DanTup
Copy link
Member

DanTup commented Apr 13, 2021

FWIW - some performance improvements have landed in Flutter master recently that may impact this, though it's hard to be sure since I haven't been able to repro.

@dewbambs
Copy link
Author

Recently the same issue did not come up. It used to happen when I used Alt + shift + f in VScode. Anytime soon I get the same Issue I will post the logs.

@DanTup
Copy link
Member

DanTup commented Apr 15, 2021

I may have a repro for this.

I'm using SDK:

Loc: /Users/danny/Dev/Dart SDKs/nightly-2021-04-06
Ver: 2.13.0-edge.fc349bdbb5f9c6d4680c11858459abcb96670227

I'm opening the SDK analysis_server + analyzer packages from the SDK at version e0bfa18c7c6 (using my usual .code-workspace) then opening lib/lsp_protocol/protocol_generated.dart and making any change and pressing Save.

The file is very large (35k lines) so it might not be the same issue seen on smaller files, but it's definitely way slower than I would expect - 22 seconds in this example (which produced 0 edits because the change was in a comment):

https://gist.github.com/DanTup/05e61e341998ab2c94aed3053899c997

# client request formatting (10:23:21.982)
1618478601982:Req:{"jsonrpc"::"2.0","id"::12,"method"::"textDocument/formatting","params"::{"textDocument"::{"uri"::"file::///Users/danny/Dev/Google/dart-sdk/sdk/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart"},"options"::{"tabSize"::2,"insertSpaces"::true,"insertFinalNewline"::true}}}

# formatting response (10:23:43.529 = 22 seconds)
1618478623529:Res:{"id"::12,"jsonrpc"::"2.0","result"::null}

@DanTup
Copy link
Member

DanTup commented Apr 15, 2021

Looks like this time is actually spent in the formatting and not where I thought it might be (generating minimal edits). I'm not sure if this is expected performance though.

@munificent I'm not sure what the expected timings are for a large file like this - it's about 20 seconds for 35k lines. It's definitely a large file (and therefore may be unrelated to the original issue raised here), but I thought it worth checking. It's the same on stable 2.12.0 SDK (v1.3.11 of the formatter) and a recent nightly with v2.0.0 of the formatter.

Repo:

~/Dev/Dart\ SDKs/nightly-2021-04-06/bin/dart format --version
# 2.0.0

cd /tmp

curl https://raw.githubusercontent.com/dart-lang/sdk/fc349bdbb5f9c6d4680c11858459abcb96670227/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart > test.dart

~/Dev/Dart\ SDKs/nightly-2021-04-06/bin/dart format -o none test.dart
# Formatted 1 file (0 changed) in 20.71 seconds.

Edit: A comment at dart-lang/dart_style#864 (comment) suggests the whole Flutter repo could be formatted in around 10-12 seconds, so it does seem like this might not be expected.

Here's a CPU profile trace exported from DevTools:

https://gist.github.com/DanTup/567ebca5f20c3cd4c647dfdc6a3b56cf

Which looks like this:

Screenshot 2021-04-15 at 11 01 33

Perhaps this 1903 character statement isn't helping (I'm now more convinced this is unrelated to the original issue - I don't think most people have code like this!):

final documentChanges = (json['documentChanges'] is List && (json['documentChanges'].every((item) => TextDocumentEdit.canParse(item, nullLspJsonReporter))))
        ? Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t1(
            json['documentChanges']
                ?.map((item) =>
                    item != null ? TextDocumentEdit.fromJson(item) : null)
                ?.cast<TextDocumentEdit>()
                ?.toList())
        : ((json['documentChanges'] is List && (json['documentChanges'].every((item) => (TextDocumentEdit.canParse(item, nullLspJsonReporter) || CreateFile.canParse(item, nullLspJsonReporter) || RenameFile.canParse(item, nullLspJsonReporter) || DeleteFile.canParse(item, nullLspJsonReporter)))))
            ? Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t2(json['documentChanges']
                ?.map((item) => TextDocumentEdit.canParse(item, nullLspJsonReporter)
                    ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t1(
                        item != null ? TextDocumentEdit.fromJson(item) : null)
                    : (CreateFile.canParse(item, nullLspJsonReporter)
                        ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t2(item != null ? CreateFile.fromJson(item) : null)
                        : (RenameFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null) : (DeleteFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null) : (item == null ? null : (throw '''$item was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)'''))))))
                ?.cast<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>()
                ?.toList())
            : (json['documentChanges'] == null ? null : (throw '''${json['documentChanges']} was not one of (List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>)''')));

@munificent
Copy link

@munificent I'm not sure what the expected timings are for a large file like this - it's about 20 seconds for 35k lines.

Even very large files should be quite fast to format, but there are corner cases where a file that contains a large number of pathologically complex expressions can get pretty slow.

Perhaps this 1903 character statement isn't helping (I'm now more convinced this is unrelated to the original issue - I don't think most people have code like this!):

final documentChanges = (json['documentChanges'] is List && (json['documentChanges'].every((item) => TextDocumentEdit.canParse(item, nullLspJsonReporter))))
        ? Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t1(
            json['documentChanges']
                ?.map((item) =>
                    item != null ? TextDocumentEdit.fromJson(item) : null)
                ?.cast<TextDocumentEdit>()
                ?.toList())
        : ((json['documentChanges'] is List && (json['documentChanges'].every((item) => (TextDocumentEdit.canParse(item, nullLspJsonReporter) || CreateFile.canParse(item, nullLspJsonReporter) || RenameFile.canParse(item, nullLspJsonReporter) || DeleteFile.canParse(item, nullLspJsonReporter)))))
            ? Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t2(json['documentChanges']
                ?.map((item) => TextDocumentEdit.canParse(item, nullLspJsonReporter)
                    ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t1(
                        item != null ? TextDocumentEdit.fromJson(item) : null)
                    : (CreateFile.canParse(item, nullLspJsonReporter)
                        ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t2(item != null ? CreateFile.fromJson(item) : null)
                        : (RenameFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null) : (DeleteFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null) : (item == null ? null : (throw '''$item was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)'''))))))
                ?.cast<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>()
                ?.toList())
            : (json['documentChanges'] == null ? null : (throw '''${json['documentChanges']} was not one of (List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>)''')));

You wouldn't believe the things I've seen. That one is definitely pretty bad, but generated code often looks like this and dartfmt is supposed to handle it well.

@DanTup
Copy link
Member

DanTup commented Apr 21, 2021

@munificent is it worth me filing an issue in dart_style about that? (do you think it's likely significant gains could be made?). I could also tweak this generated code (I'm generating it), although my concern was less about this specific file than whether there's a more general issue other users may also see.

If not, I wonder if the analysis server should offload this to another isolate, since it's currently synchronous in the main isolate that will block all other language server requests for the duration (@bwilkerson any thoughts?).

Although, I don't think either of those resolve the original issue here. I'm not sure it's just slow formatting, but suspect the server was busy with something else (perhaps rebuilding contexts it didn't need to - which hopefully is now fixed).

@bwilkerson
Copy link

If we're sure that dart_style is causing the issue (and not something else in server), then it might well make sense to run dart_style asynchronously with a timeout. I'm not convinced that a separate isolate is the right choice because I think that would require parsing the AST again, but I don't have a strong opinion about it either.

@DanTup
Copy link
Member

DanTup commented Apr 21, 2021

If we're sure that dart_style is causing the issue (and not something else in server)

I'm not sure it's the cause of the original issue raised here - I think I just happened to see the same behaviour but it was caused by the big file. I don't expect many users have code like generated code above, but it would be nice not to improve the experience if they did.

it might well make sense to run dart_style asynchronously with a timeout. I'm not convinced that a separate isolate is the right choice because I think that would require parsing the AST again, but I don't have a strong opinion about it either.

If I understand correctly, I think it may be parsing currently anyway?

https://github.com/dart-lang/dart_style/blob/f17c23e0eea9a870601c19d904e2a9c1a7c81470/lib/src/dart_formatter.dart#L116-L121

Is it possible to run dart_style asynchronously? I thought it was all synchronous and CPU bound. If it can be run asynchronously (whether in an isolate or otherwise), I'd prefer to support cancellation than add a timeout (at least for LSP). Timeouts can be frustrating because in some cases users might want to wait for an operation to complete (because the result are more important than it being fast). As long as it's running asynchronously, for LSP we can receive cancellation requests from the client and could abort - that way the user is in control of whether they wait of cancel, rather than it being a fixed time (which could have different cut-offs in terms of file size/complexity based on how powerful the users machine is).

This is probably moot if Bob thinks this could be much faster (in which case I'll file a dart_style issue with the repro above), though otherwise I could file an SDK issue about handling this better and we can figure out the best way there.

I'll leave this issue open for now either way, as I think there's another issue - which may or may not be fixed by the context rebuild changes - that's causing people to see what looks like slow formatting but might not be.

@bwilkerson
Copy link

If I understand correctly, I think it may be parsing currently anyway?

Yes, it looks that way. I'd assumed that we'd ask the AnalysisSession for the parsed AST and that it would most likely be cached because it would be a priority file. But that assumption appears to have been wrong.

Is it possible to run dart_style asynchronously?

Probably not.

... for LSP we can receive cancellation requests ...

The legacy protocol doesn't support that, so we might have to have a timeout there, or just let the client (IntelliJ) handle the timeout.

@DanTup
Copy link
Member

DanTup commented Apr 21, 2021

The legacy protocol doesn't support that, so we might have to have a timeout there, or just let the client (IntelliJ) handle the timeout.

Is there a way to time out synchronous code? If not, presumably an isolate would be the only way? (and then it probably wouldn't really be cancelled, but rather us just returning early and it finishing in the background). If we do decide it needs a timeout, it shouldn't be difficult to add to just the non-LSP protocol and use cancellation for LSP (or at least, have a higher timeout for LSP).

We can revisit when it's clearer whether this is a common case (I suspect not) and whether there are optimisations dart_style could make for code like the above. I think may "repro" above is likely an edge case and a bit of a red herring.

@munificent
Copy link

@munificent is it worth me filing an issue in dart_style about that?

Yes, please do.

(do you think it's likely significant gains could be made?).

Yeah, it's definitely possible, though I can't promise when I'll have time to look into it.

I could also tweak this generated code (I'm generating it), although my concern was less about this specific file than whether there's a more general issue other users may also see.

Tweaking the code would definitely be a good idea. That's a huge expression, and a giant generated file that contains many many expressions that large is basically the worst case for dartfmt.

If you generate code like:

final documentChanges = () {
  if (json['documentChanges'] is List &&
      (json['documentChanges'].every(
          (item) => TextDocumentEdit.canParse(item, nullLspJsonReporter)))) {
    return Either2<
        List<TextDocumentEdit>,
        List<
            Either4<TextDocumentEdit, CreateFile, RenameFile,
                DeleteFile>>>.t1(json['documentChanges']
        ?.map((item) => item != null ? TextDocumentEdit.fromJson(item) : null)
        ?.cast<TextDocumentEdit>()
        ?.toList());
  } else if (json['documentChanges'] is List &&
      (json['documentChanges'].every((item) =>
          (TextDocumentEdit.canParse(item, nullLspJsonReporter) ||
              CreateFile.canParse(item, nullLspJsonReporter) ||
              RenameFile.canParse(item, nullLspJsonReporter) ||
              DeleteFile.canParse(item, nullLspJsonReporter))))) {
    return Either2<
        List<TextDocumentEdit>,
        List<
            Either4<TextDocumentEdit, CreateFile, RenameFile,
                DeleteFile>>>.t2(json['documentChanges']
        ?.map((item) {
          if (TextDocumentEdit.canParse(item, nullLspJsonReporter)) {
            return Either4<TextDocumentEdit, CreateFile, RenameFile,
                    DeleteFile>.t1(
                item != null ? TextDocumentEdit.fromJson(item) : null);
          } else if (CreateFile.canParse(item, nullLspJsonReporter)) {
            return Either4<TextDocumentEdit, CreateFile, RenameFile,
                DeleteFile>.t2(item != null ? CreateFile.fromJson(item) : null);
          } else if (RenameFile.canParse(item, nullLspJsonReporter)) {
            return Either4<TextDocumentEdit, CreateFile, RenameFile,
                DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null);
          } else if (DeleteFile.canParse(item, nullLspJsonReporter)) {
            return Either4<TextDocumentEdit, CreateFile, RenameFile,
                DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null);
          } else if (item == null) {
            return null;
          } else {
            throw '''$item was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)''';
          }
        })
        ?.cast<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>()
        ?.toList());
  } else if (json['documentChanges'] == null) {
    return null;
  } else {
    throw '''${json['documentChanges']} was not one of (List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>)''';
  }
};

Then it will format it about 1200x faster. (That's times, not percent.)

@DanTup
Copy link
Member

DanTup commented Apr 23, 2021

@munificent thanks! I've raised dart-lang/dart_style#1022 and may see if it's easy to tweak that in future (I don't hand-edit/format this file, but the generation script does format it at the end - so now I realise why that seemed to be taking a while too).

@github-actions
Copy link

This issue has been marked stale because it is tagged awaiting-info for 30 days with no activity. Remove the stale label or comment to prevent the issue being closed in 10 days.

@github-actions github-actions bot added the stale Will be closed soon if no response. label May 24, 2021
@mellowcello77
Copy link

mellowcello77 commented May 25, 2021

I don't know what is causing it, but all I see is "Saving 'http.dart': Running 'Dart' Formatter (configure)". and it doesn't stop. Started with the latest Flutter upgrade. Have to restart vscode everytime and try again, works for one or two saves. Is there anything I can provide to help solve this issue? Serious workflow problem.

Flutter 2.2.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b22742018b (10 days ago) • 2021-05-14 19:12:57 -0700
Engine • revision a9d88a4d18
Tools • Dart 2.13.0

Screenshot 2021-05-25 at 15 24 53

@DanTup
Copy link
Member

DanTup commented May 25, 2021

@mellowcello77 a log could be very helpful:

  • Run the "Preferences: Open Workspace Settings" command from the VS Code command palette
  • Set the dart.analyzerInstrumentationLogFile to a file path for logging (either absolute, or relative like "logs/analyzer.txt" which will go in the project folder)
  • Reproduce the issue
  • Leave the "Saving..." notification up for a minute or so (on the off-chance it's code that's slow to format rather than the server not responding)
  • Take a copy of the log file
  • (you can then remove the log file setting)

The log file may contain parts of your source code so if it's something you can't share, please open the log file and look for the last few occurrences of :Res: near the bottom of the file which should show what request(s) the server last responded to. I'm interested to know what are the few requests (:Req) around that time that were not responded to.

If you can repro on a project without sensitive code, feel free to just attach (or email to me at logs@dartcode.org) the lines starting a handful above the last server response. Thanks!

@github-actions github-actions bot removed the stale Will be closed soon if no response. label May 26, 2021
@netgfx
Copy link

netgfx commented May 26, 2021

even with no more than 300 lines of flutter code, no conditionals. But system overall low memory (less than 1Gb unallocated) still causes this issue on a daily basis. Could it be that the formatting process requires some system resources to be available at the forefront (even if it doesn't utilize them completely)?

@mellowcello77
Copy link

One day later and have not been able to replicate it again. Will post as requested by DanTup soon as it happens again.

@DanTup
Copy link
Member

DanTup commented May 26, 2021

@netgfx

Could it be that the formatting process requires some system resources to be available at the forefront (even if it doesn't utilize them completely)?

I'm not certain, but I suspect it's probably not the formatter here - I think the server is not responding correctly and then the format requests jut gets stuck (I think it was coincidence that I triggered something similar behaviour by actually having something that formatted slowly).

If this seems to happen after you're just run a debug session and the analysis server appears to never recover, then it could be related to dart-lang/sdk#45996 (which my or may not be specific to macOS), though I don't fully understand what's happening there yet.

@samandmoore
Copy link

I have not corroborated this, but someone on my team reported that this appears to happen to them when they have Android studio open at the same time as VS Code. I can't easily imagine how that could happen, perhaps some sort of shared resource contention (seems unlikely right?), but I figure it doesn't hurt too much to share that theory.

I'm also trying to replicate with logging turned on, but haven't had any luck.

@ilkerulusoy
Copy link

I have deleted editor.codeActionsOnSave": null in settings.json and my problem fixed. null not acceptable.

@ilkerulusoy
Copy link

I made an update. The problem still persists. I will send log to logs@dartcode.org.

@DanTup
Copy link
Member

DanTup commented Jun 29, 2021

@ilkerulusoy thanks! I checked the log, but it looks like it didn't include the request to format. The log file ends right after the initial analysis completes. Did you try to save/format while initial analysis may still have been in progress? (parts of that analysis are synchronous and will delay formatting until they're complete).

Also - could you see if enabling the dart.previewLsp setting to see if that makes any difference? That will soon become the default mode and has some performance advantages (because less of the code has to share a single thread with all other VS Code extensions).

@ilkerulusoy
Copy link

@DanTup Restarting vscode fixed it. My log setting is active, I'll repost from the next. I didn't make any changes for dart.previewLsp in the initial setting.
I think this event happens after this situation that run real ios device or simulator mixed.

@sowens-csd
Copy link

I just emailed a log taken during a formatter hang in VSCode. I'm using 2.2.2. The issue is very intermittent for me. The same project will work fine for a week or so and then I'll get a hang. I've had logging turned on for a long time to see if I could catch one in progress. Let me know if the log snippet I sent isn't enough. The whole log was > 700 mb so I only sent the last 200 lines. The formatter was hung for more than three minutes before I closed VSCode and sent the log.

@DanTup
Copy link
Member

DanTup commented Jul 12, 2021

@sowens-csd thanks for the log - unfortunately it doesn't seem to include the formatting request, so it's hard to tell what was going on. Was the formatting still occurring when you took this log? There are lots of requests/responses in the part you sent me, suggesting the server was responsive so I'm not yet sure what might've happened.

If you still have the full log, are you able to search for /formatting and see if you can find the format request? Sending everything from a little before that might be useful to understand what's going on. Thanks!

@sowens-csd
Copy link

I do still have the full log and did a grep for 'formatting' and it doesn't appear in the file analyzer.txt.1 at all. That's surprising since it spans from Friday morning to this morning. Perhaps I have the logging configured incorrectly? When I took the log I'd closed and restarted VSCode. I figured that the end of this log would represent the state when it shut down, at which time it was still formatting. That word doesn't appear in analyzer.txt either.

@DanTup
Copy link
Member

DanTup commented Jul 12, 2021

@sowens-csd that's definitely strange (although perhaps may also be related? 🤔)

A few questions:

  • Do you have dart.enableSdkFormatter: false in your settings?
  • Do you have any other formatters enabled? For example Prettier encourages adding "editor.defaultFormatter": "esbenp.prettier-vscode", to your setting which would result in it being called for Dart formatting
  • Did the message definitely say it was formatting (and not - for example - running some other action on-save, like Sort Members or Fix All?)

It may also be interesting to run Dart: Capture Logs and just force a format operation and see whether that shows up in the log or not.

@sowens-csd
Copy link

  • Do you have dart.enableSdkFormatter: false in your settings?
    No

  • Do you have any other formatters enabled? For example Prettier encourages adding "editor.defaultFormatter": "esbenp.prettier-vscode", to your setting which would result in it being called for Dart formatting
    Not that I know of. Editor: Default Formatter shows None. I don't see anything else referenced in the settings.json.

  • Did the message definitely say it was formatting (and not - for example - running some other action on-save, like Sort Members or Fix All?)
    Yes, I believe so. Of course just because that's my memory doesn't prove it is so.

I tried a Capture Logs and formatting does not appear in that log when I save a file with format on save turned on nor when I try a dart format lib/*.dart from the command line. I'd assume that the save operation triggers a format every time with that setting on? Or is there another way I can ensure it is forced?

@DanTup
Copy link
Member

DanTup commented Jul 13, 2021

@sowens-csd sorry, my mistake - I thought you had LSP enabled but checking the log again it is not. In this case you should be looking for edit.format in the log instead (this also doesn't exist in the log you sent me unfortunately).

That said, I would also encourage enabling LSP with the dart.previewLsp setting if possible to see whether that makes any difference. That will soon become the default, and improves the performance of some things as it moves more work out of the single thread shared with other VS Code extensions.

To force formatting, you should be able to just insert any unformatted code (eg. foo() { }) and save or run the Format Document command from the command palette (and you should see all the spaces disappear if it's working).

nor when I try a dart format lib/*.dart from the command line

Running from the command line or embedded terminal definitely won't show up, as they're completely disconnected from the extension and just work on the filesystem directly.

@sowens-csd
Copy link

I just sent you a larger log extract that includes the last edit.format request and surrounding context. Just out of curiosity I checked the complete log file and there were 77 edit.format instances in it. All of them were successful until the last one. Let me know if anything else from that file would be useful.

I'll give the dart.previewLsp another try. I have tried it previously but switched back for reasons that I don't remember. I think it might have been that code completion and help stopped working intermittently. That was in an earlier release though so it's definitely worth another try. I'll keep logging turned on in case I can reproduce again.

@DanTup
Copy link
Member

DanTup commented Jul 13, 2021

In the log you sent me, I only see one edit.format but it appears to have completed very quickly (the line immediately following it is the response).

There have been many improvements in LSP in the latest stable releases, and from the next release of the Dart plugin it will be on by default for everyone that hasn't explicitly turned it off (it's currently at 75%). If there are any outstanding issues with it I'd definitely like to know. (I'm not sure it'll make much difference here, but it's certainly worth trying - there's less to go wrong in the VS Code side using LSP, and if things go wrong in the server they're usually more obvious from the logs).

In LSP the formatting is a little different too - we minimise the edits on the server, whereas without we'll send a replacement for the entire file and let VS Code figure it out. Again, I'm not sure it would affect this issue, but it will cut out that extra work being done by VS Code.

@sowens-csd
Copy link

Thanks for having a look. I've switched to LSP and will post an update if I see the format issue again.

@AleksandarSavic95
Copy link

Had the same issue with Flutter 2.2.1. After uninstalling Flutter and Dart extensions, upgrading flutter to latest version (now 2.2.3) and reinstalling the extensions, the formatting on save works instantly.
Great job, Flutter/Dart team! 🚀

@DanTup DanTup modified the milestones: v3.25.0, v3.26.0 Jul 20, 2021
@github-actions
Copy link

This issue has been marked stale because it is tagged awaiting-info for 20 days with no activity. Remove the stale label or comment to prevent the issue being closed in 10 days.

@github-actions github-actions bot added the stale Will be closed soon if no response. label Aug 10, 2021
@temitopeog
Copy link

temitopeog commented Dec 14, 2021

Having the same issues with the following -

Flutter 2.8.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision cf44000065 (6 days ago) • 2021-12-08 14:06:50 -0800
Engine • revision 40a99c5951
Tools • Dart 2.15.0

@DanTup
Copy link
Member

DanTup commented Dec 14, 2021

@temitopeog can you reproduce it reliably? Is it with particular files? (If so, are you able to share one so that I can reproduce)?

@karascr
Copy link

karascr commented Jan 26, 2022

Removing all package files from the project and deleting local VS Code files (package files etc.) and reinstalling them worked for me idk why.

@DanTup
Copy link
Member

DanTup commented Jan 27, 2022

I can't explain that either, but if you see this come back, please do file a new issue so we can do some digging. Thanks!

@Cory-FanDemand
Copy link

I am getting this issue alot. I need to use various flutter versions of flutter including 2.2.0. Restarting the window with cmd-R helps at lest temporarily.

My log file has no error messages:
!! PLEASE REVIEW THIS LOG FOR SENSITIVE INFORMATION BEFORE SHARING !!

Dart Code extension: 3.34.0
Flutter extension: 3.34.0 (activated)

App: Visual Studio Code
Version: 1.64.0
Platform: mac

Workspace type: Flutter
Analyzer type: LSP
Multi-root?: false

Dart SDK:
Loc: /Users/me/Development/Dev/fvmhome/versions/2.2.1/bin/cache/dart-sdk
Ver: 2.13.1
Flutter SDK:
Loc: /Users/me/Development/Dev/fvmhome/versions/2.2.1
Ver: 2.2.1

HTTP_PROXY: undefined
NO_PROXY: undefined

Logging Categories:
General, Analyzer, CommandProcesses, DartTest, DAP, VmService, DevTools, FlutterDaemon, FlutterRun, FlutterTest, WebDaemon

Fri Feb 04 2022 [14:23:27 GMT-0500 (Eastern Standard Time)] Log file started
Fri Feb 04 2022 [14:23:58 GMT-0500 (Eastern Standard Time)] Log file ended

@DanTup
Copy link
Member

DanTup commented Feb 4, 2022

@Cory-FanDemand the log you included doesn't seem to have captured anything - did you start capturing before saving/formatting?

I see you're not on the latest version of Flutter (you have v2.2.1, the latest is v2.10). There have been many fixes to the LSP server since then - please try upgrading to the latest version and it may be that the problem goes away.

@Cory-FanDemand
Copy link

@DanTup Yes I did, next time it starts happening - if I'm on 2.10 at the time - I'll try to capture again.

@DanTup
Copy link
Member

DanTup commented Feb 7, 2022

@Cory-FanDemand thanks - you ned to start capturing before the format request is sent (and ideally, leave it for until it completes). You can set logging to run all the time using settings on this page:

https://dartcode.org/docs/logging/#analyzer

Although the files can get quite large, so you should keep an eye on them.

FYI - the analysis server logs will contain parts of your source code, so they may need reviewing/redacting before sharing.

@grlduarte
Copy link

I was facing the same issue and noticed it would only happen when my internet connection was slow or down. For me, disabling analytics solved the problem:

dart --disable-analytics

@DanTup
Copy link
Member

DanTup commented Feb 14, 2023

@grlduarte can you reliably reproduce this? (for example if you manually disconnect your internet, does it occur?)

There are some things I'm aware of where the server will try to connect to the internet (such as caching Pub package names to use in code completion) but I didn't think it was currently sending any analytics. I'm surprised that disabling analytics would fix formatting getting stuck. Has it been long since you disabled them? Is it possible it be intermittent and you've just been lucky since disabling it?

If you can reproduce the issue, I'd be interested in a new issue opening (here or in dart-lang/sdk and CCing me) so we can capture some logs and understand what's happening.

(@bwilkerson FYI)

@grlduarte
Copy link

@DanTup I have had this problem on and off for some time. Using Vim + Dart plugin I noticed every time my internet was down the editor would stuck on save.

Today I tried what you suggested and: TA-DA. Once the problem was isolated, I don't know what led me to it, but I disabled analytics and the problem was gone.

There's more, I didn't mention in the previous answer but every dart command gets stuck with analytics enabled and internet down, even dart --help.

Also worth mentioning that my SDK is pretty outdated (2.18.2).

I will open a new issue in dart-lang/sdk since this does not seems to be related to Dart Code

@DanTup
Copy link
Member

DanTup commented Feb 14, 2023

@grlduarte

If this hang still occurs on the latest SDK, I would certainly file an issue in dart-lang/sdk about it. Analytics and no internet should defintely not prevent these commands from working.

If the dart language_server command is hanging, that could certainly also affect editor functionality - although I'd expect far more than formatting to not work, I would expect general editor functionality to suffer too. If you can reproduce issues where general editor functionality (like code completion) works and only formatting is broken in that case, I'd be interested in an additional issue opened here in the Dart-Code repo so we can get some logs to see what's happening there, since it could be a different issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting info Requires more information from the customer to progress in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is bug stale Will be closed soon if no response.
Projects
None yet
Development

No branches or pull requests