Move EnC manager implementation down to Features layer (16.3 P1) #36727
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Replaces legacy EnC manager implementation with a new one.
The previous implementation of the EnC manager in the debugger communicated with language services via project system coupled interfaces (
IVsENCRebuildableProjectCfg*). This had many limitations, including necessity to perform IO synchronously on UI thread, lack of support for multi-targeting, necessity to make buffers readonly while application is running and for projects whose modules were not loaded to the debugee process etc.The new architecture completely removes the dependency on Project System. The debugger communicates with language services via a MEF component. Language services export
IDebugStateChangeListenerThe implementation of this interface receives callbacks from the debugger when the debug state changes:
IEditAndContinueManagedModuleUpdateProviderThe implementation responds to the debugger's requests for updates in managed modules.
The debugger sends these requests when changes made in source files need to be applied due to a user action (e.g. "continue" in break mode, change current IP while in break mode, etc.).
Avoiding read-only buffers
Previously we made buffers read only in scenarios where we couldn't apply the change at the end of the current edit session ("continue"). This could be for multiple reasons:
Changes can only be applied when the debuggee is stopped.
We let the user made changes while the debuggee is running. We report a warning for these changes notifying the user that the changes are not being applied while the debugee is running.
When the debugger stops on a breakpoint in a modified source, the source won't match the one that's being executed so based on the settings the debugger may display a dialog saying so. We will follow up to improve that experience, but not going to block the change on it.
Since the modules are not loaded we can't apply the delta at the end of the edit session (there is no module in the debugee process to apply the delta to).
We calculate the EnC deltas for all projects changed during edit session regardless of whether their modules are loaded or not. At the end of the session we apply deltas only to modules that are loaded, but we remember all the deltas we calculated for next opportunity to apply changes. Such opportunity occurs when a module is loaded while the debuggee is running. At that point the debuggee is stopped while the even is processed and we can apply all deltas that were made to the project that corresponds to the module. Note that this also handles the case where multiple instances of the same module are loaded to the debuggee (e.g. to different AppDomains or AssemblyLoadContexts). The previous design didn't account for this scenario resulting in bugs like #34253.
We do not block the user from making changes in the source files. Instead we report regular errors like we do for other Rude Edits. We use new APIs added to Concord to support querying for availability of EnC for specific module.
Fixes #10203.
Fixes #11656.
Fixes #18917.
Fixes #21170.
Fixes #27373.
Fixes #27735.
Fixes #29223.
Fixes #34253.
Fixes DevDiv 750649
Fixes DevDiv 551604
See also #18350.