-
Notifications
You must be signed in to change notification settings - Fork 4.2k
File-based program directive diagnostics in editor #79421
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
File-based program directive diagnostics in editor #79421
Conversation
src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/FileBasedPrograms/RunApiModels.cs
Show resolved
Hide resolved
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Outdated
Show resolved
Hide resolved
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Show resolved
Hide resolved
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Outdated
Show resolved
Hide resolved
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Outdated
Show resolved
Hide resolved
if (string.IsNullOrEmpty(document.FilePath)) | ||
return []; | ||
|
||
var simpleDiagnostics = await virtualProjectXmlProvider.GetCachedDiagnosticsAsync(document.FilePath, cancellationToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of asking for cached diags, why not just ask for the diags appropriate for Document. ANd if they have been cached they are returned, otherwise they are computed.
I'm very wary about this producing stale data that is then not updated properly as changed come in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems plausible, I am actually wondering what would happen if we simply changed this to "get the virtual project" again, using whatever content is in the current version of the doc, which will take a second or two usually, and forward the diagnostics. Then I guess this source could be marked as live.
In the medium term I think we also want to try to forward certain msbuild diagnostics (e.g. if a bad id or version is used with #:package
). But that could just be a different thing reported from a different source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...except that run-api wants to take a file path for the file-based program, which it will read from disk. That means the diagnostics coming back would still be stale until user hits save.
For the short term I think it is going to be better to start with the "non-live" diagnostics which are essentially driven by design time build, and in medium term make the necessary adjustments to make the subset of diagnostics live, which can be made live.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this fairly high traffic, i.e.:
if we simply changed this to "get the virtual project" again
Would mean we'd be continually launching processes in the background to re-ask for the content?
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Outdated
Show resolved
Hide resolved
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Outdated
Show resolved
Hide resolved
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Outdated
Show resolved
Hide resolved
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Show resolved
Hide resolved
using (await _gate.DisposableWaitAsync(cancellationToken)) | ||
{ | ||
_diagnosticsByFilePath[documentFilePath] = project.Diagnostics; | ||
} | ||
return (project.Content, project.Diagnostics); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the staleness issue semes real here. it looks like we could return incorrect diagnostics for a solution snapshot. and it's unclear what would snap the ide out of that state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is updated each time a design time build occurs, which for the moment occurs whenever the file-based program is saved to disk.
The cached diagnostics would probably need to be updated in the other code paths also. e.g. if run-api completely fails, the stale diagnostics we already had in the cache are likely not useful and should be cleared out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like we could return incorrect diagnostics for a solution snapshot. and it's unclear what would snap the ide out of that state.
I don't think I fully grasp this concern or what should be done to address it.
So, when the "Save" happens, what ensures that the entire pipeline even knows to run again to then get these cached diagnostics? For context, saving a file doesn't not change our content checksums, and we often (but not always) drive these experiences off of content checksums. So we'd need something else to mix into the system to even know to get diagnostics agian. And importantly, that would either have to run after the diagnostics were definitely computed and cached, or it would have to wait on those being computed when it did its work in order for the user to get the correct diagnostics results. All this is possible. We just have to be careful and clear (and the code should be evident as to how it is ccomplishing this). Thanks! :) |
A file watcher will kick off a design time build when the file-based program is saved. For the pipeline to run again, the TODO from PR description needs to be addressed.
|
Answered offline. |
Added use of IDiagnosticRefresher. Seems decently responsive for the moment. We should still track down making this work with in-memory-only changes in the near-to-medium term so that long design time builds, autosave being turned off, etc. will not mess up the user experience. fbp-directive-diagnostics.mp4Also, if we break things so badly that run-api doesn't even give back a virtual project, we should probably clear out any stale diagnostics from the last run. |
...t.CodeAnalysis.LanguageServer/FileBasedPrograms/VirtualProjectXmlDiagnosticSourceProvider.cs
Show resolved
Hide resolved
|
||
// check for difference, and signal to host to update if so. | ||
if (previousCachedDiagnostics.IsDefault || !project.Diagnostics.SequenceEqual(previousCachedDiagnostics)) | ||
diagnosticRefresher.RequestWorkspaceRefresh(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks correct. generally the guidance I have on using the refresher is to use it as sparingly as possible because it refreshes all diagnostics. It looks like you're already checking to make sure there are changes which is good.
But the less that goes through this the better. Ideally we can get most diagnostics from the actual Roslyn snapshots, and then the normal on-type updates handle most changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we can get most diagnostics from the actual Roslyn snapshots, and then the normal on-type updates handle most changes.
What would it mean to do this? Does that require having a "live source" for diagnostics? e.g. getting the diagnostics through analyzer, or running run-api on the "snapshot" of the file-based program?
_diagnosticsByFilePath[documentFilePath] = project.Diagnostics; | ||
|
||
// check for difference, and signal to host to update if so. | ||
if (previousCachedDiagnostics.IsDefault || !project.Diagnostics.SequenceEqual(previousCachedDiagnostics)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we remove diagnostics? It looks really bad when we have stale diagnostics, so we definitely need to ensure we're clearing them when the file based project is deleted / renamed / otherwise changes contexts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also probably need to remove them from the _diagnosticsByFilePath
map if the file/project is deleted, otherwise we have a small leak
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wrapping this method to try and ensure that the cache is always dealt with appropriately, whatever the response from run-api.
Handled unloading. Quite possibly the caching should be in |
@dibarbet @jasonmalinowski for review |
Can you do a final pass through feedback plz :) |
@@ -153,4 +153,9 @@ public async ValueTask TryRemoveMiscellaneousDocumentAsync(DocumentUri uri) | |||
Preferred: buildHostKind, | |||
Actual: buildHostKind); | |||
} | |||
|
|||
protected override async ValueTask OnProjectUnloadedAsync(string projectFilePath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to figure out the semantics of OnProjectUnloadedAsync
- Does this get called when the file is closed in the editor
- Does this get called when the file moves from a loose file, into an actual project?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Yes.
- No. I'm adding a comment to explain in more details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any way we can tell when that transition happens? So that we can clear out diagnostics if its not a file based program any longer?
Maybe it would be possible to verify that the workspace kind is still the language server workspace? IIRC there would be a workspace changed event triggering a diagnostics refresh, so there should be a diagnostics requests to the server in that scenario already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any way we can tell when that transition happens? So that we can clear out diagnostics if its not a file based program any longer?
Hypothetically, upon reload, we could see if some of the targets we unloaded were associated with a different ProjectFactory than before, and react to that somehow.
Line 266 in 8fefbab
target.Dispose(); |
Note also the assert that tracked targets for a given project, are all associated with only one projectFactory at a given time:
Line 287 in 8fefbab
Debug.Assert(newProjectTargets.All(target => target.ProjectFactory == projectFactory)); |
In practice I do not think we are going to need a special behavior here. Each design time build, either of FBP or "rich misc file", is going to result in run-api reporting some set of diagnostics, and we will always surface the latest set for the project. And, we expect run-api is not going to report anything for the "non-FBP" case. It would be hard to observe it reporting in the non-FBP case, since it only reports on bad "app directives" currently, and presence of those will mark the file as an FBP.
Long and short is I do not expect an unwanted/buggy behavior here from failing to take an explicit step to clear the diagnostics out when transitioning between FBP and non-FBP. (I'll verify this manually but I keep having to change between different branches and would like to fix in a follow up in the case we really do have a problem here.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wfm
id: FileBasedPrograms, | ||
category: FileBasedPrograms, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we ever expecting to have some sort of ID for these?
? new VSTextDocumentIdentifier { ProjectContext = ProtocolConversions.ProjectToProjectContext(document.Project), DocumentUri = document.GetURI() } | ||
: null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indenting is a bit strange here.
[Export(typeof(IDiagnosticSourceProvider)), Shared] | ||
[method: ImportingConstructor] | ||
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] | ||
internal sealed class VirtualProjectXmlDiagnosticSourceProvider(VirtualProjectXmlProvider virtualProjectXmlProvider) : IDiagnosticSourceProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we have an AbstractDocumentDiagnosticSource that implements some of this for us?
Path = fileLinePositionSpan.Path, | ||
Span = fileLinePositionSpan.Span, | ||
}; | ||
internal record struct LinePositionInternal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why "internal" as a name here?
private readonly SemaphoreSlim _gate = new(initialCount: 1); | ||
private readonly Dictionary<string, ImmutableArray<SimpleDiagnostic>> _diagnosticsByFilePath = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this state just be held in FileBasedProgramsProjectSystem rather than being held here? It seems a bit odd that this provider method (that was previously stateless) gets the state.
/// So, for example, changing the target frameworks of a project, or transitioning between | ||
/// "file-based program" and "true miscellaneous file", will not result in this being called. | ||
/// </remarks> | ||
protected abstract ValueTask OnProjectUnloadedAsync(string projectFilePath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? Isn't it the derived type already the one calling Unload, so why can't it just call it's logic directly?
{ | ||
using (await _gate.DisposableWaitAsync(CancellationToken.None)) | ||
{ | ||
_diagnosticsByFilePath.Remove(path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be doing a refresh here?
Removes IsLive from the diagnostic source, and relies on diagnostic tags to correctly set the `Build` diagnostic tag. This fixes a debug assert crash when using Razor with the latest main changes ``` 2025-07-30 14:46:02.141 [error] [stderr] Process terminated. Assertion failed. All document sources should be live at Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.DiagnosticSourceManager.AggregateSourcesIfNeeded(ImmutableArray`1 sources, Boolean isDocument) in C:\Users\xiaoyuz\source\repo\roslyn\src\LanguageServer\Protocol\Handler\Diagnostics\DiagnosticSourceProviders\DiagnosticSourceManager.cs:line 109 at Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.DiagnosticSourceManager.CreateDiagnosticSourcesAsync(RequestContext context, String providerName, ImmutableDictionary`2 nameToProviderMap, Boolean isDocument, CancellationToken cancellationToken) in C:\Users\xiaoyuz\source\repo\roslyn\src\LanguageServer\Protocol\Handler\Diagnostics\DiagnosticSourceProviders\DiagnosticSourceManager.cs:line 95 at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.DiagnosticSourceManager.CreateDiagnosticSourcesAsync(RequestContext context, String providerName, ImmutableDictionary`2 nameToProviderMap, Boolean isDocument, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.DiagnosticSourceManager.CreateDocumentDiagnosticSourcesAsync(RequestContext context, String providerName, CancellationToken cancellationToken) in C:\Users\xiaoyuz\source\repo\roslyn\src\LanguageServer\Protocol\Handler\Diagnostics\DiagnosticSourceProviders\DiagnosticSourceManager.cs:line 55 at Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.AbstractDocumentPullDiagnosticHandler`3.GetOrderedDiagnosticSourcesAsync(TDiagnosticsParams diagnosticsParams, String requestDiagnosticCategory, RequestContext context, CancellationToken cancellationToken) in C:\Users\xiaoyuz\source\repo\roslyn\src\LanguageServer\Protocol\Handler\Diagnostics\AbstractDocumentPullDiagnosticHandler.cs:line 50 at Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.AbstractPullDiagnosticHandler`3.HandleRequestAsync(TDiagnosticsParams diagnosticsParams, RequestContext context, CancellationToken cancellationToken) in C:\Users\xiaoyuz\source\repo\roslyn\src\LanguageServer\Protocol\Handler\Diagnostics\AbstractPullDiagnosticHandler.cs:line 142 at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.AbstractPullDiagnosticHandler`3.HandleRequestAsync(TDiagnosticsParams diagnosticsParams, RequestContext context, CancellationToken cancellationToken) at Microsoft.CommonLanguageServerProtocol.Framework.QueueItem`1.StartRequestAsync[TRequest,TResponse](TRequest request, TRequestContext context, IMethodHandler handler, String language, CancellationToken cancellationToken) in C:\Users\xiaoyuz\source\repo\roslyn\src\LanguageServer\Microsoft.CommonLanguageServerProtocol.Framework\QueueItem.cs:line 191 at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at Microsoft.CommonLanguageServerProtocol.Framework.QueueItem`1.StartRequestAsync[TRequest,TResponse](TRequest request, TRequestContext context, IMethodHandler handler, String language, CancellationToken cancellationToken) at Microsoft.CommonLanguageServerProtocol.Framework.RequestExecutionQueue`1.<>c__DisplayClass18_0`2.<ProcessQueueCoreAsync>b__2() in C:\Users\xiaoyuz\source\repo\roslyn\src\LanguageServer\Microsoft.CommonLanguageServerProtocol.Framework\RequestExecutionQueue.cs:line 378 at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() ``` this bug was revealed in #79421 when a non-live doc diagnostic source was added
* Remove NetAnalyzers version override * Put back dotnet8 feed * Fix analyzer violations * Address more analyzer violations * Revert breaking fixes * Address more analyzer violations * Fix Xaml MEF import * Generate semantic search ref assemblies package * Change the delay for how often we synchronize solutions Now that we're doing all the WorkspaceChanged notifications on background threads, that means the notifications won't be quite as batched as before; this was causing an increase in synchronizations that was creating some wasted work. * Update dependencies from https://github.com/dotnet/dotnet build 276797 Updated Dependencies: System.CommandLine (Version 2.0.0-beta7.25374.102 -> 2.0.0-rc.1.25375.106) * PR feedback * Update dependencies from https://github.com/dotnet/dotnet build 276828 Updated Dependencies: System.CommandLine (Version 2.0.0-rc.1.25375.106 -> 2.0.0-rc.1.25375.119) * Use Append overload for repeating chars * Fix formatting of CDATA sections in quick info * Fix * Fix * Handle concurrent requests to update workspace contents and workspace SG info * Fallout * Add test * Apply suggestions from code review * Docs * Docs * Produce a better return type when trying to return an anonymous type in an async method * Fix test * Don't use a pool in SemanticTokensHelper.ComputeTokens (#79622) * Don't use a pool in SemanticTokensHelper.ComputeTokens This can be just allocated directly into an array instead of fiddling with a pool. Simpler and more efficient. This shows up as 2.5% of allocations in a scenario in a scenario in RazorEditingTest.CompletionInCohosting for the Roslyn OOP. Most of that is due to the list resizing. * Refine Caching example (#79593) Add comment to improve readability. * Add reference assemblies dir parameter (#79614) * Update Microsoft.ILVerification (#79555) * Reduce allocations in CSharpVirtualCharService.TryConvertStringToVirtualChars (#79623) This method is accounting for 1.4% of allocations in the OOP process in a completion scenario in the RazorEditing.CompletionInCohosting speedometer test I am looking at. Instead of doing all the work and hitting the pools, we can just handle the normal case of there not being any surrogates or escape characters and just create a VirtualCharSequence wrapper around the existing string. Locally, I see about 75% of strings that come through hit this optimization. Going to do a test insertion with this change to verify speedometer numbers before elevating out of draft status. * modified tagged text instead to resolve LSP issues * Remove unnecessary methods from interface * Move logic into helper * Better handle quick info for code with suppressions in it * Simplify * Revert * Simplify * fix diff * restore optionality * Remove unnecessary feed (#79635) * Reduce some UI thread blocking It looks like in various refactorings we accidentally had a ConfigureAwait(false) appear in this method which could cause us to jump to a background thread when we don't need to do that. I'm not sure why we didn't just use CA(true) only here, since that seems to do what we want without any extra trickery. * Pass in referenceAssembliesDir to ISemanticSearchSolutionService * reverted tests back to main * File-based program directive diagnostics in editor (#79421) * Sign contents of nupkg, but not the nupkg itself * Pull publishdata from the branch being published * Update dependencies from https://github.com/dotnet/dotnet build 276981 (#79647) [main] Source code updates from dotnet/dotnet * Incorporated PR feedback - Restored removed BuildHost methods. - Separated MSBuild instance finding from loading - Removed loop in favor of a single relaunch * Show nullability of a local variable when hovering on the decl of it * Add tests * Add more var cases * Add work items * Docs * Share code * nrt * Improve QuickInfo NRT info in the presence of nullability altering checks * Simplify * Simplify * Simplify * Simplify * Add test cases * Update src/Workspaces/Core/Portable/Workspace/Solution/SourceGeneratorExecutionVersion.cs Co-authored-by: Joey Robichaud <[email protected]> * Add tests * Add tests * Restore name * Make nupkg signing exclusion conditional * Fix logging when item counts change in LoadedProject (#79640) * Use checksum * Add lsp tests * remove testing branch name * reverted tests back to main * Add comment for nuget package behavior * Trap on-the-fly-doc exceptions in quick info * Cleanup * Update debugger.contracts to 18.0.0-beta.25379.1 (#79661) * Catch more * Catch more * Tweak map spans API to match document service, and call it * Enable View -> Stack Trace Explorer by default Tool windows can always be opened before their packages are loaded. The act of running the command creates the package. * Strongly type the mapping API, and allow Razor to check generator type etc. * argh don't wanna talk about it * Delete unused quick info code * SelectAsArray * Recognize known `ToString` methods inside interpolation * Fix extension-method add-import completion in syntactically ambiguous scenarios * Docs * `comp` -> `compilation` * Use pooled builder * Update src/Analyzers/Core/Analyzers/SimplifyInterpolation/AbstractSimplifyInterpolationHelpers.cs Co-authored-by: Cyrus Najmabadi <[email protected]> * Update src/Analyzers/Core/Analyzers/SimplifyInterpolation/AbstractSimplifyInterpolationHelpers.cs Co-authored-by: Cyrus Najmabadi <[email protected]> * Check for `static` just in case * Paranoia :) * Sort * Fix spelling * remove unnecessary code * Allow PR val build insertion step to be re-run * Simplify * Spelling * Move tests * Remove * Add back * Too many type name collisions in Razor tests * Revert "Move methods back to a place where TypeScript can reference them (#79208) * Fix Call Hierarchy false positives by filtering non-reference contexts * test * added typeof filtering * fix call hierarchy false positives by filtering out nameof and typeof calls * used ReferenceLocation for nameof and typeof detection * added space as per CR * wip tests * Simplify determination of live vs. build diagnostics * Add Copilot.EA IVT * walk up functionality + nameof tests for call hierarchy * formatting issues * Extract helper method * Use span mapping in codelens * Use span mapping in naviation * Use span mapping in FAR * VB: EmitDelegateCreation - account for the fact that static methods can be marked virtual in metadata (#79697) Fixes #79696 * Update based on review feedback * Update src/Compilers/Core/Portable/Diagnostic/WellKnownDiagnosticTags.cs Co-authored-by: Rikki Gibson <[email protected]> * defer tail slicing for efficiency * Remove untriaged label automation (#79701) The `Status` field on our project board supercedes this label. Removing it since it's no longer used. * test member access read/write not affected by walkup * removed commented out test * Extensions: address instrumentation follow-ups (#79557) * Move extension to helper class. Extensions on Document seemed a bit broad * Remove a hack, and clarify another * Fix tests * Allow more lifecycle events in Razor cohosting * Fix formatting in use-auto-prop when attributes are present * Move 'use auto prop' into code style layer * In progress * Move fix all helpers to shared location so that CodeStyle can reference them * IN progress * in progress * Share more code * wip * Working * Simplify * Simplify * Remove hacks * Simplify * Add assert * move service into shared location * Revert "Pull publishdata from the branch being published" This reverts commit 0721c3b. * helper method + formatting issues fix * made helper method into local method * Add Copilot semantic search (#79673) * Add null check * Semantic search updates (#79742) * [main] Source code updates from dotnet/dotnet (#79744) [main] Source code updates from dotnet/dotnet - Remove properties that now live in Version.Details.props - Update Versions.props - Add Microsoft.Extensions.FileSystemGlobbing to V.D.xml * Refactor how TestWorkspaces interact with TestCompositions TestWorkspace only had constructors that took TestCompositions, but this reintroduces a constructor that takes an ExportProvider directly if the MEF composition requires too much setup -- specifically our LSP server tests that already have their own system for creating MEF compositions. A few things got cleaned up along the way: 1. The Composition property (which was oddly nullable) gets removed entirely; a few tests that were creating a second TestWorkspace to mirror a first one are able to just use the ExportProvider directly. 2. We had a hack where we'd inject a TestWorkspaceConfigurationService into the MEF container if the call to create the TestWorkspace passed along custom options. This just adds that type directly into the base configuration so we can reuse the TestCompositions better. Any tests trying to use that feature and creating custom MEF compositons are just expected to inject that type. * Allow our LanguageServer tests to use Protocol.Test.Utilities The problem here was that adding that dependency carries along many things we don't want to put into the MEF composition, but we now have a subfolder we can use for MEF discovery that contains just the product binaries we expect. * Run our LSP Miscellaneous Files tests against both implementations We have a set of tests for miscellaneous files tests, and this now runs that against both our base implementation and also the file-based application implementation in our language server. This required a few subtle changes: 1. Making AbstractLanguageServerProtocolTests deal with test workspaces that aren't our usual MEF TestCompositions. This is because these tests against the real server implementation are using the code that creates our real MEF container. Our code assumed we had some test mocks available, but in the real product those aren't there. We can gracefully skip those since we don't need them to properly test the end-to-end product. 2. Switching the tests away from assuming there is a misc files workspace but rather that a given documenet may or may not be a miscellaneous files document. This gets rid of a TODO we had referring to this, and although required a lot of changes it's a mechanical change. * Consolidate and unify the miscellaneous files tests more This moves one test into the abstract base, and also fixes the tests to avoid using TestLspServer.TestWorkspace when in the real server tests we will be using our other host workspace implementation. * Fix file-based programs getting stuck in the host workspace If a file is loaded that can be treated as a file-based program, and then a real project is loaded that contains that file, we should unload the file-based program since we're treating that as a miscellaneous file. But we had a bug here: the code in LspWorkspaceManager that loops through workspaces assumes that the miscellaneous files workspace would be found last, so if we find a document in any other workspace first, we're good to use it. This assumption was broken once we started putting file-based programs in the host workspace, since we might find both the file-based program and the 'real' project in the same workspace. The fix is straightforward: if when we're finding a file context we amd we end up with a miscellaneous file, check if we have any other files too, and if so, prefer those. This will then allow us to unload the miscellaneous file as normal. Fixes dotnet/vscode-csharp#8471 * fix formatting issues * Tests to ensure everything is hooked up * Apply suggestions from code review Co-authored-by: Joey Robichaud <[email protected]> * Allow Razor to control the lifetime of caches, rather than using statics * Don't know how that happened * use SelectAsArray * Where+Select * Use WhereAsArray * Add docs * rename * Formatting * Simplify * Remove lazy enumerables * Delete unused functin * Fix crash when generating explicit impl properties * Improve error reporting from RemoteInitializationService (#79761) * Do not report 'no-effect' warning when active top-level code is updated (#79746) * Allow Razor to call into codelens * Make internal * Update dependencies from https://github.com/dotnet/dotnet build 278022 (#79796) [main] Source code updates from dotnet/dotnet * Simplify code * remove comment * remove comment * Support getting diagnostic descriptors from OOP * Simplify * Formatting * Has predicate, so don't use count * Named parameters * Remove unused test impl of an interface * Cleanup * Update dependencies from https://github.com/dotnet/dotnet build 278224 (#79822) [main] Source code updates from dotnet/dotnet --------- Co-authored-by: Cyrus Najmabadi <[email protected]> Co-authored-by: Jan Jones <[email protected]> Co-authored-by: David Barbet <[email protected]> Co-authored-by: Tomas Matousek <[email protected]> Co-authored-by: [email protected] <[email protected]> Co-authored-by: Jason Malinowski <[email protected]> Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: David Wengier <[email protected]> Co-authored-by: Stuart Lang <[email protected]> Co-authored-by: Cyrus Najmabadi <[email protected]> Co-authored-by: Gen Lu <[email protected]> Co-authored-by: Todd Grunke <[email protected]> Co-authored-by: RaymondY <[email protected]> Co-authored-by: Tomáš Matoušek <[email protected]> Co-authored-by: Gobind Singh <[email protected]> Co-authored-by: Rikki Gibson <[email protected]> Co-authored-by: Joey Robichaud <[email protected]> Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Joey Robichaud <[email protected]> Co-authored-by: David Kean <[email protected]> Co-authored-by: DoctorKrolic <[email protected]> Co-authored-by: DoctorKrolic <[email protected]> Co-authored-by: AlekseyTs <[email protected]> Co-authored-by: David Barbet <[email protected]> Co-authored-by: Rikki Gibson <[email protected]> Co-authored-by: Jared Parsons <[email protected]> Co-authored-by: Julien Couvreur <[email protected]>
#78688
IsLiveSource() => false
.VirtualProjectXmlProvider
gets a virtual project, it caches the diagnostics from the run-api result in a dictionaryIDiagnosticSource
has a reference to theVirtualProjectXmlProvider
and accesses the latest diagnostics for the project from itTODO:When GetVirtualProjectContentAsync gets a new project back from run-api, it needs to signal that the new diagnostics are available, and the associatedIDiagnosticSource
should be queried again. I'm not sure how to do this. Edit: resolved by using IDiagnosticRefresher.FileBasedProgramsProjectSystem
and looked up somehow.IDiagnosticSourceProvider
needs to be registered through MEF the current factoring felt fairly straightforward. However we could imagine wanting to also surface the design time build diagnostics through this provider somehow. In which case we would need the project system to cache diagnostics instead, in some location where theIDiagnosticSource
could access them.IDiagnosticSourceProvider
could be a parameter to theFileBasedProgramsProjectSystem
and when the project system has diagnostics it wants cached/potentially surfaced it could just call into the diagnostic source provider.