-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Fix OOP crashes due to inability to roundtrip error symbols. #44713
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
Fix OOP crashes due to inability to roundtrip error symbols. #44713
Conversation
| [|Goo|](s); | ||
| } | ||
| } | ||
| </Document> |
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.
have verified this test fails in OOP scenarios prior to the fix and passes post the fix.
src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationNamespaceSymbol.cs
Outdated
Show resolved
Hide resolved
…tionNamespaceSymbol.cs
src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ErrorTypeSymbolKey.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test2/FindReferences/FindReferencesTests.OrdinaryMethodSymbols.vb
Show resolved
Hide resolved
...ilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs
Show resolved
Hide resolved
src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ErrorTypeSymbolKey.cs
Outdated
Show resolved
Hide resolved
| public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor) | ||
| { | ||
| visitor.WriteString(symbol.Name); | ||
| visitor.WriteSymbolKey(symbol.ContainingSymbol as INamespaceOrTypeSymbol); |
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 not quite getting why this had to be changed here -- the symbol key written out for the namespace of the error symbol would still have been a valid symbol key, right? Would this also have been fixed if we just had the resolving of the namespace just call CreateErrorNamespaceSymbol if it can't find the original namespace?
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 symbol key written out for the namespace of the error symbol would still have been a valid symbol key, right? Would this also have been fixed if we just had the resolving of the namespace just call CreateErrorNamespaceSymbol if it can't find the original namespace?
- i went down that path and felt very oogy about that. i.e. i didn't like the idea of just blindly resolving as an ErrorNamespace if we couldnt' find it again. I want that behavior to be explicit only if that's what went in.
- i also went down a path of actually exposing an
IsMissing/IsErrorbit on INamespaceSymbol so that we could just recurse to the parent and store that bit and then rehydrate the ErrorNamespace on the other end. Indeed, my early commits show that. However, it was much larger in scope, and as i thought about it, i realized it wasn't necessary, so i went with the simpelr appraoch.
|
@CyrusNajmabadi Does this need to target something other than master? I don't quite know what our ship schedule is but if this is dogfood impacting we might have to go to a servicing branch? (I don't know how "bad" this actually is or honestly what our snap schedule is either.) |
src/EditorFeatures/Test2/FindReferences/FindReferencesTests.OrdinaryMethodSymbols.vb
Show resolved
Hide resolved
Have pinged @jinujoseph about this. |
jasonmalinowski
left a comment
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 code handling nested namespaces seems to be missing a .Reverse() somewhere. And even if I'm wrong, we may want a test ensuring that.
src/EditorFeatures/Test2/FindReferences/FindReferencesTests.OrdinaryMethodSymbols.vb
Show resolved
Hide resolved
|
|
||
| return new SymbolKeyResolution(currentNamespace); | ||
| case 2: | ||
| return reader.ReadSymbolKey(); |
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.
Can we Debug.Assert() that this didn't really do anything, since it should always be 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.
good idea
src/Workspaces/Core/Portable/SymbolKey/SymbolKey.ErrorTypeSymbolKey.cs
Outdated
Show resolved
Hide resolved
jasonmalinowski
left a comment
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.
Looks good!
Co-authored-by: Jason Malinowski <jason@jason-m.com>
Co-authored-by: Jason Malinowski <jason@jason-m.com>
Co-authored-by: Jason Malinowski <jason@jason-m.com>
Co-authored-by: Jason Malinowski <jason@jason-m.com>
Co-authored-by: Jason Malinowski <jason@jason-m.com>
Co-authored-by: Jason Malinowski <jason@jason-m.com>
Co-authored-by: Jason Malinowski <jason@jason-m.com>
Co-authored-by: Jason Malinowski <jason@jason-m.com>
ghost
left a comment
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.
Auto-approval
|
Let's keep this in master for 16.7.preview3 |
…roslyn into missingNamespace
Fixes #14365
Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1131811
Core issue here was that we were not serializing enough information to properly rehydrate error symbols between local/OOP. For example, say you had:
The
PointCollection.Add(System.Windows.Point)method (wherePointCollectionis inPresentationCore.dllandPointis inWindowsBase.dll). However, you don't actually have a reference toWindowsBase.dll. The compiler represents this as an error-type forPoint, with a containing 'missing namespace' hierarchy forSystem.Windows.With OOP we need to be able to round-trip the symbols we're talking about on the client side with the OOP server so that it can then do the searching for it there. In this case we failed to do that because we were encoding
System.Windows.Pointonly asPoint, and thus failed to match to the corresponding method on the oop side when we rehydrated things there.We now properly encode and rehydrate the containing namespaces of errors types ensuring that this works.
While this seems like it would be difficult for customers to hit, ti's actually not uncommon as as dlls get added/removed to roslyn during things like solution-load or restores. So if a OOP request is made during that time, this could trigger.
This was discovered by examining all our fault hits at PerfWatson and seeing that all of them contained the siganture for an error type for them. This allowed me to create a simple repro that immediately triggered the issue locally.