Skip to content

Use ITextBufferCloneService if available in AsText#26339

Merged
sharwell merged 1 commit intodotnet:dev15.7.xfrom
sharwell:use-clone-service
Apr 24, 2018
Merged

Use ITextBufferCloneService if available in AsText#26339
sharwell merged 1 commit intodotnet:dev15.7.xfrom
sharwell:use-clone-service

Conversation

@sharwell
Copy link
Copy Markdown
Contributor

@sharwell sharwell commented Apr 23, 2018

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/604150

/cc @minestarks

Customer scenario

A customer attempts to reformat an HTML document, and Visual Studio crashes. Pasting the following into an HTML document will reproduce the issue.

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script>    
        function foo() {}
    </script>
</head>
<body>

</body>
</html>

Bugs this fixes

https://devdiv.visualstudio.com/DevDiv/_workitems/edit/604150

Workarounds, if any

None.

Risk

Low. Of multiple possible places to fix the sequence of events leading to a product crash, this one provides the strongest assurances that 15.7 release will continue to behave like 15.6 w.r.t. text differencing.

Performance impact

Aside from fixing a possible crash, performance is improved in the impacted scenarios by allowing the use of ITextBufferCloneService rather than falling back to the slower path.

Is this a regression from a previous update?

Yes, introduced by #25558.

Root cause analysis

Two changes in the causal PR resulted in a behavior change:

  • The AsText(ITextSnapshot) extension method failed to use the ITextBufferCloneService assigned to the source text buffer for the snapshot.
  • Roslyn only uses text buffers created by ITextBufferFactoryService. The TypeScript implementation, on the other hand, uses projection buffers created by IProjectionBufferFactoryService. The events notifying extension code that a buffer is created differs for these two services.

While the fallback behavior of Roslyn was intended to be slower but functionally equivalent, the text differencing algorithm differed between the two approaches - the one used when ITextBufferCloneService was not available threw an exception if the set of changes made to a buffer were not ordered.

How was the bug found?

Dogfooding / reported by TypeScript team

Test documentation updated?

N/A

@sharwell sharwell requested a review from a team as a code owner April 23, 2018 18:15
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

💭 This seems to have been an oversight in 4924d70

@sharwell sharwell added this to the 15.7 milestone Apr 23, 2018
This change also ensures the projection buffers created in Visual Studio have
the ITextBufferCloneService added to their property bag.

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/604150
@sharwell sharwell force-pushed the use-clone-service branch from 15047ce to ab34327 Compare April 23, 2018 23:07
if (!finalize)
{
_textBufferFactoryService.TextBufferCreated -= AddTextBufferCloneServiceToBuffer;
_projectionBufferFactoryService.ProjectionBufferCreated -= AddTextBufferCloneServiceToBuffer;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

so we do this for every buffer or only roslyn buffer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

➡️ All of them

@jinujoseph
Copy link
Copy Markdown
Contributor

approved to merge via link

@jaredpar
Copy link
Copy Markdown
Member

        e.TextBuffer.Properties.AddProperty(typeof(ITextBufferCloneService), _textBufferCloneService);

Not for this change but in general we should really avoid the use of Type instances as key in the property bags. Invites collisions with other services.


Refers to: src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs:229 in ab34327. [](commit_id = ab34327, deletion_comment = False)

agocke pushed a commit that referenced this pull request May 16, 2018
See #26339 for the primary RCA.

This change corrects an additional edge case for ITextBuffer instances created before VisualStudioWorkspace attaches event handlers to ITextBufferFactoryService and IProjectionBufferFactoryService. This case is only believed to occur in IDE initialization scenarios where the workspace load is triggered by opening a document.
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.

6 participants