// internal for unit tests internal bool DeleteAndShiftElements(TextChangeContext context) { if (Thread.CurrentThread.ManagedThreadId != _ownerThreadId) { throw new ThreadStateException("Method should only be called on the main thread"); } TextChange textChange = context.PendingChanges; var changeType = textChange.TextChangeType; bool elementsChanged = false; if (changeType == TextChangeType.Structure) { IAstNode changedElement = context.ChangedNode; int start = context.NewStart; // We delete change nodes unless node is a token node // which range can be modified such as string or comment var positionType = PositionType.Undefined; if (changedElement != null) { IAstNode node; positionType = changedElement.GetPositionNode(context.NewStart, out node); } bool deleteElements = (context.OldLength > 0) || (positionType != PositionType.Token); // In case of delete or replace we need to invalidate elements that were // damaged by the delete operation. We need to remove elements and their keys // so they won't be found by validator and incremental change analysis // will not be looking at zombies. if (deleteElements) { _pendingChanges.FullParseRequired = _editorTree.InvalidateInRange(_editorTree.AstRoot, context.OldRange, out elementsChanged); } } _editorTree.NotifyTextChange(context.NewStart, context.OldLength, context.NewLength); return(elementsChanged); }