Skip to content

If no IDocumentDifferenceService is exported, consider the whole document changed#14317

Merged
OmarTawfik merged 2 commits intodotnet:masterfrom
OmarTawfik:no-doc-diff-service
Oct 6, 2016
Merged

If no IDocumentDifferenceService is exported, consider the whole document changed#14317
OmarTawfik merged 2 commits intodotnet:masterfrom
OmarTawfik:no-doc-diff-service

Conversation

@OmarTawfik
Copy link
Contributor

Fixes #14316
@dotnet/roslyn-ide @CyrusNajmabadi

@CyrusNajmabadi
Copy link
Contributor

tagging @paulvanbrenk @minestarks. You'll be able to remove TypeScriptDocumentDifferenceService.

tagging @heejaechang @mavasani for review.

tagging @mgoertz-msft This may be what's making it so that diagnostic presentation doesn't update for you.

@CyrusNajmabadi
Copy link
Contributor

👍 From me. But please wait until Heejae/Manish take a look.

{
// For languages that don't use a Roslyn syntax tree, they don't export a document difference service.
// The whole document should be considered as changed in that case.
await EnqueueWorkItemAsync(newDocument, InvocationReasons.DocumentChanged).ConfigureAwait(false);
Copy link
Contributor

Choose a reason for hiding this comment

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

DocumentChanged will cause p2p propagation. which project is this document belong to? do you want all other documents to be re-analyzed (due to semantic changes) and propagate it up to dependency chain? if so, DocumentChanged seems right one. otherwise, you should use things like SyntaxChanged to make only that document to be re-analyzed.

Copy link
Contributor

Choose a reason for hiding this comment

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

actually, I think it should be SyntaxChanged to make its cost to be low. if any one want to have expansive propagation, they should export IDocumentDifferenceService so that they can control its cost.

@CyrusNajmabadi
Copy link
Contributor

DocumentChanged is correct. In the absense of any "smarts" one must assume that any change to a document will propagate outwards.

in languages like TS there can't even be any "smarts" because type-inference can flow from inside methods outwards, so literally any edit could affect anyone downstream.

@heejaechang
Copy link
Contributor

well, if one wants correct behavior, they should export their own. if we ever going to provide default behavior, it should be cheapest one rather most expansive one. if they want correct one, than, they should export their own.

@CyrusNajmabadi
Copy link
Contributor

well, if one wants correct behavior,

Being conservative is the most correct behavior. If we provide the "cheap" default that is incorrect, then that just means people get incorrect results. We want correctness first, then performance.

We also want to make it so that modules like F# and TS do not need IVT to things like the workspace. That opens up a huge swath of surface area that they may then start using which we could break at any moment.

Right now only C# and VB can actually effectively provide this optimized codepath. For all other consumers, the behavior of DocumentChanged is correct and will result in the correct experience for their customers. As such, for this part of the system, it's appropriate for us to have that be the default behavior.

Put more simply: The only people that need to export this service are C#/VB/TS/F#/Xaml. For TS/F#/Xaml a good default behavior is "DocumentChanged" as it gives the correct experience across all edits. As such, if we don't have that default here, then all 3 other languages need to provide that same implementation while also needing IVT. I'd much rather them now have IVT and have things work properly for their use cases.

@heejaechang
Copy link
Contributor

well, I dont think adding simple most expansive one as default and saying correct-ness comes first is not right way to support. I think it should be either they take simplest, cheapest default behavior or they spent time to actually participate and be a good citizen. and I dont believe performance comes after correct-ness. I think performance need to come first. if it can't provide good performant one, the feature either need to cut out or its feature set should be reduced.

@minestarks
Copy link

For what it's worth - A) The IDocumentDifferenceService is internal so its usage by external parties isn't exactly encouraged. B) Our implementation is just to return DocumentChanged in all cases. If you force external parties to ALWAYS implement this interface, chances are very high that they are going to do the simplest, most expensive implementation anyway (like TS did). Might as well provide that as the default.

@heejaechang
Copy link
Contributor

@minestarks and once TS users start to complain about performance such as "I just typed a character why VS CPU 100% for a min?", now you owns the service that controls it since you are the one who exported the service and implemented the most expansive way.

@heejaechang
Copy link
Contributor

if the default implementation is for like console app who wants easiest possible way to get pass all obstacles to make something working. I agree default should be most simple thing that is correct even though it could be most expansive-way. but this is for VS. we shouldn't provide most easiest and most expansive default implementation.

@CyrusNajmabadi
Copy link
Contributor

@heejaechang This is for features like diagnostics and squiggles. It is paramount they be correct. Having incorrect results is something very frustrating for users.

Furthermore, TS cannot provide the facility you are asking for. Nearly all edits in TS will need all downstream updates. Unlike C#/VB, the language does not really have the concept of a "local only edit". F# is in a similar situation. Because of the more extensive use of inference in those languages this sort of additional work needs to happen.

and once TS users start to complain about performance such as "I just typed a character why VS CPU 100% for a min?"

TS has shipped this way for years. We are not asking for new capability. The ask here is that the correct logic, which will be shared by F#, TS and likely Xaml, be provided, reducing the need for us to expose IVT on the workspace layer to these languages.

Again, IVT would be needed just so these languages could provide this common implementation. This exposes a huge surface area just for this one function. And that exposed surface area isn't even helpful as all these languages will report DocumentChanged so that they can get the correct (and fastest) behavior that they know how to implement.

@heejaechang
Copy link
Contributor

well those reasoning made us to disable full solution analysis disabled by default. and it is hard to believe there is nothing they can do to make it more efficient. for cheap ones, things like detecting whether edit happened inside of whitespace, comments, constant literals can be done.

and hard to believe they can't figure out things that absolutely can't affect semantic of other documents.

@CyrusNajmabadi
Copy link
Contributor

well those reasoning made us to disable full solution analysis disabled by default.

Typescript already runs out of proc and does not have the same GC heavy profile that C#/VB do.

for cheap ones, things like detecting whether edit happened inside of whitespace, comments, constant literals can be done.

  1. constant literals affect the semantics of TS. (they have literal-types as part of the language)
  2. comments can affect the semantics of JS. (they embed type system information in comments)
  3. whitespace could potentially be done. However, then that's only helping the case that the user has typed nothing but whitespace (which is fairly rare). Any time they type anything non whitespace (which is the normal case when typing), then that will make it so that recomputation is necessary.

Also, for TS this isn't something that can be computed easily with their current language model. TS does not have immutable trees that they can even compare. Instead, they follow a model where their trees are mutated in place. As such, even if we pass different documents to them, it's not the case that they can even diff things.

@CyrusNajmabadi
Copy link
Contributor

This is the crux of the issue here. This API is designed to allow languages to speed things up if such things are possible in their language. It's not sensible for the core API to assume that all languages must be able to provide these services. Our system should be designed so that things work correctly, and so that there are opportunities for speed up if that's possible for the specific language.

@heejaechang
Copy link
Contributor

alright. looks like most people want DocumentChanged. I will not be the one blocking this to be in :) 👍

@OmarTawfik
Copy link
Contributor Author

@CyrusNajmabadi @heejaechang @minestarks thanks for the comments! I'll be merging this then.

@OmarTawfik OmarTawfik merged commit af97390 into dotnet:master Oct 6, 2016
@OmarTawfik OmarTawfik deleted the no-doc-diff-service branch October 6, 2016 17:57
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.

5 participants