Skip to content

Conversation

RikkiGibson
Copy link
Member

@RikkiGibson RikkiGibson commented Jul 16, 2025

#78688

  • Creates a new IDiagnosticSourceProvider, which produces IDiagnosticSource with IsLiveSource() => false.
  • When VirtualProjectXmlProvider gets a virtual project, it caches the diagnostics from the run-api result in a dictionary
  • The IDiagnosticSource has a reference to the VirtualProjectXmlProvider and accesses the latest diagnostics for the project from it
  • Right now this works well enough to display directive diagnostics when a file is first opened.
  • TODO: When GetVirtualProjectContentAsync gets a new project back from run-api, it needs to signal that the new diagnostics are available, and the associated IDiagnosticSource should be queried again. I'm not sure how to do this. Edit: resolved by using IDiagnosticRefresher.
  • Looking for feedback on the location to keep the cached diagnostics, etc. Possibly the diagnostics should be "unloaded" if the associated project is unloaded. Possibly even these should be cached in the FileBasedProgramsProjectSystem and looked up somehow.
    • Since 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 the IDiagnosticSource could access them.
    • Maybe the IDiagnosticSourceProvider could be a parameter to the FileBasedProgramsProjectSystem and when the project system has diagnostics it wants cached/potentially surfaced it could just call into the diagnostic source provider.

if (string.IsNullOrEmpty(document.FilePath))
return [];

var simpleDiagnostics = await virtualProjectXmlProvider.GetCachedDiagnosticsAsync(document.FilePath, cancellationToken);
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

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.

Copy link
Member

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?

using (await _gate.DisposableWaitAsync(cancellationToken))
{
_diagnosticsByFilePath[documentFilePath] = project.Diagnostics;
}
return (project.Content, project.Diagnostics);
}
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

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.

@CyrusNajmabadi
Copy link
Member

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! :)

@RikkiGibson
Copy link
Member Author

So, when the "Save" happens, what ensures that the entire pipeline even knows to run again to then get these cached diagnostics?

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.

TODO: When GetVirtualProjectContentAsync gets a new project back from run-api, it needs to signal that the new diagnostics are available, and the associated IDiagnosticSource should be queried again. I'm not sure how to do this.

@CyrusNajmabadi
Copy link
Member

TODO: When GetVirtualProjectContentAsync gets a new project back from run-api, it needs to signal that the new diagnostics are available, and the associated IDiagnosticSource should be queried again. I'm not sure how to do this.

Answered offline.

@RikkiGibson
Copy link
Member Author

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.mp4

Also, 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.


// check for difference, and signal to host to update if so.
if (previousCachedDiagnostics.IsDefault || !project.Diagnostics.SequenceEqual(previousCachedDiagnostics))
diagnosticRefresher.RequestWorkspaceRefresh();
Copy link
Member

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.

Copy link
Member Author

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))
Copy link
Member

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?

Copy link
Member

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

Copy link
Member Author

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.

@RikkiGibson
Copy link
Member Author

Handled unloading. Quite possibly the caching should be in FileBasedProgramsProjectSystem rather than VirtualProjectXmlProvider. I don't have a strong opinion on it.

@RikkiGibson RikkiGibson marked this pull request as ready for review July 25, 2025 01:52
@RikkiGibson RikkiGibson requested a review from a team as a code owner July 25, 2025 01:52
@RikkiGibson RikkiGibson requested a review from dibarbet July 28, 2025 17:10
@RikkiGibson
Copy link
Member Author

@dibarbet @jasonmalinowski for review

@CyrusNajmabadi
Copy link
Member

@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)
Copy link
Member

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

  1. Does this get called when the file is closed in the editor
  2. Does this get called when the file moves from a loose file, into an actual project?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Yes.
  2. No. I'm adding a comment to explain in more details.

Copy link
Member

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.

Copy link
Member Author

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.

Note also the assert that tracked targets for a given project, are all associated with only one projectFactory at a given time:

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.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wfm

@RikkiGibson RikkiGibson merged commit afaf319 into dotnet:main Jul 29, 2025
25 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Jul 29, 2025
Comment on lines +53 to +54
id: FileBasedPrograms,
category: FileBasedPrograms,
Copy link
Member

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?

Comment on lines +74 to +75
? new VSTextDocumentIdentifier { ProjectContext = ProtocolConversions.ProjectToProjectContext(document.Project), DocumentUri = document.GetURI() }
: null;
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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?

Comment on lines +27 to +28
private readonly SemaphoreSlim _gate = new(initialCount: 1);
private readonly Dictionary<string, ImmutableArray<SimpleDiagnostic>> _diagnosticsByFilePath = [];
Copy link
Member

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);
Copy link
Member

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);
Copy link
Member

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?

@RikkiGibson RikkiGibson self-assigned this Jul 31, 2025
dibarbet added a commit that referenced this pull request Jul 31, 2025
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
333fred added a commit that referenced this pull request Aug 7, 2025
* 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]>
@RikkiGibson RikkiGibson modified the milestones: Next, 18.0 P1 Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants