Roslyn: VS2017: Inline renaming in Razor completely randomly broken

Created on 29 Mar 2017  路  9Comments  路  Source: dotnet/roslyn

Version Used: VS2017 (15.0.0+26228.9 and 15.0.0+26228.10)

Steps to Reproduce:

Adding further to my collection (#6821, #7660)

  1. In a ASP.NET MVC 5 Project, open a .cshtml (no other files) with more complex C# code than the template projects (haven't figured a minimum reproduction sample yet)
  2. Try to rename a C# Element

Expected Behavior:
Renaming C# things in Razor should not differ from renaming C# things in .cs files

Actual Behavior:
If you open a .cshtml file, it might trigger one of the two following behaviors. If you close the file without changes and just reopen it, the bug may go away, stay the same or switch to any of the other bugs described below.

It either starts overwriting text (although code will be correct once rename completes)
2017-03-28_17-29-05
Or you cannot type more than one or two characters (see the inline rename dialog, i'm typing "somerandomtext" but it goes s -> so -> sm -> se)
2017-03-28_17-30-51

When the rename starts behaving that weird, trying to ESC the way out of it results in non fatal and fatal exceptions

System.InvalidOperationException: Sequence contains more than one element.
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.OpenTextBufferManager.OnTextBufferChanged(Object sender, TextContentChangedEventArgs args)
   at Microsoft.VisualStudio.Text.Utilities.GuardedOperations.RaiseEvent[TArgs](Object sender, EventHandler`1 eventHandlers, TArgs args)

or

System.InvalidOperationException: Sequence contains no elements.
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.AbstractInlineRenameUndoManager`1.UpdateCurrentState(String replacementText, ITextSelection selection, SnapshotSpan activeSpan)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.AbstractInlineRenameUndoManager`1.OnTextChanged(ITextSelection selection, SnapshotSpan singleTrackingSpanTouched)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.OpenTextBufferManager.OnTextBufferChanged(Object sender, TextContentChangedEventArgs args)
   at Microsoft.VisualStudio.Text.Utilities.GuardedOperations.RaiseEvent[TArgs](Object sender, EventHandler`1 eventHandlers, TArgs args)

or a VS crash

Message: System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.OpenTextBufferManager.<>c__DisplayClass29_0.<ApplyConflictResolutionEdits>b__0(Document d)
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.OpenTextBufferManager.ApplyConflictResolutionEdits(IInlineRenameReplacementInfo conflictResolution, IEnumerable`1 documents, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.ApplyReplacements(IInlineRenameReplacementInfo replacementInfo, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.<QueueApplyReplacements>b__63_0(Task`1 t)
   at Roslyn.Utilities.TaskExtensions.<>c__DisplayClass6_0`1.<SafeContinueWith>b__0(Task antecedent)
   at Roslyn.Utilities.TaskExtensions.<>c__DisplayClass3_0.<SafeContinueWith>b__0(Task antecedent)
   at Roslyn.Utilities.TaskExtensions.<>c__DisplayClass7_0`1.<SafeContinueWith>b__0(Task t)
Stack:
   at System.Environment.FailFast(System.String, System.Exception)
   at Microsoft.CodeAnalysis.FailFast.OnFatalException(System.Exception)
   at Microsoft.CodeAnalysis.ErrorReporting.FatalError.Report(System.Exception, System.Action`1<System.Exception>)
   at Microsoft.CodeAnalysis.ErrorReporting.FatalError.ReportUnlessCanceled(System.Exception)
   at Roslyn.Utilities.TaskExtensions+<>c__DisplayClass7_0`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].<SafeContinueWith>b__0(System.Threading.Tasks.Task)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession+OpenTextBufferManager+<>c__DisplayClass29_0.<ApplyConflictResolutionEdits>b__0(Microsoft.CodeAnalysis.Document)
   at System.Linq.Enumerable.Single[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Generic.IEnumerable`1<System.__Canon>, System.Func`2<System.__Canon,Boolean>)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession+OpenTextBufferManager.ApplyConflictResolutionEdits(Microsoft.CodeAnalysis.Editor.IInlineRenameReplacementInfo, System.Collections.Generic.IEnumerable`1<Microsoft.CodeAnalysis.Document>, System.Threading.CancellationToken)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.ApplyReplacements(Microsoft.CodeAnalysis.Editor.IInlineRenameReplacementInfo, System.Threading.CancellationToken)
   at Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameSession.<QueueApplyReplacements>b__63_0(System.Threading.Tasks.Task`1<Microsoft.CodeAnalysis.Editor.IInlineRenameReplacementInfo>)
   at Roslyn.Utilities.TaskExtensions+<>c__DisplayClass6_0`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].<SafeContinueWith>b__0(System.Threading.Tasks.Task)
   at Roslyn.Utilities.TaskExtensions+<>c__DisplayClass3_0.<SafeContinueWith>b__0(System.Threading.Tasks.Task)
   at Roslyn.Utilities.TaskExtensions+<>c__DisplayClass7_0`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].<SafeContinueWith>b__0(System.Threading.Tasks.Task)
   at System.Threading.Tasks.ContinuationResultTaskFromTask`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   at System.Threading.Tasks.Task.ExecutionContextCallback(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
   at System.Threading.Tasks.Task.ExecuteEntry(Boolean)
   at System.Threading.Tasks.TaskScheduler.TryExecuteTask(System.Threading.Tasks.Task)
   at Microsoft.CodeAnalysis.Editor.Shared.Utilities.SynchronizationContextTaskScheduler.PostCallback(System.Object)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
Area-IDE Bug Concept-Continuous Improvement Feature Request Tenet-Reliability

Most helpful comment

Not sure if appropriate to add here, but wanted to note that these exceptions aren't just triggered by refactor-based renames of Razor C# elements, as described in the OP, but also with renames of JavaScript elements appearing in

All 9 comments

Mondo escrow triage: keeping this one.

Likely a razor reparsing bug. Moving to 15.5.

Not sure if appropriate to add here, but wanted to note that these exceptions aren't just triggered by refactor-based renames of Razor C# elements, as described in the OP, but also with renames of JavaScript elements appearing in