public void Remove(SyntaxNodeKey key) { InvalidateEnumerator(); if (_deadQueue.Contains(key)) { _deadQueue.Remove(key); } _elements.Remove(key); }
public EnvDTE.CodeElement TryGetValue(SyntaxNodeKey nodeKey) { CodeElementWeakComAggregateHandle resultWeakComHandle; if (_elementWeakComHandles.TryGetValue(nodeKey, out resultWeakComHandle)) { return(resultWeakComHandle.ComAggregateObject); } return(null); }
internal void OnCodeElementCreated(SyntaxNodeKey nodeKey, EnvDTE.CodeElement element) { // If we're creating an element with the same node key as an element that's already in the table, just remove // the old element. The old element will continue to function but the new element will replace it in the cache. if (_codeElementTable.ContainsKey(nodeKey)) { _codeElementTable.Remove(nodeKey); } _codeElementTable.Add(nodeKey, element); }
public void Add(SyntaxNodeKey key, EnvDTE.CodeElement element) { // This code deals with a weird case of interaction with WinForms: The same // element can be added multiple times. What we have to do is bump // the conflicting element to a free [KeyName, Ordinal] slot // by incrementing [Ordinal] // Elements with the same node path can also be added multiple times in // normal editing scenarios, e.g. when a code element is changing preserving its name // (e.g. a class becomes an interface) or user just removes a block of code and // then readds it back before code elements for removed code were garbage collected. CodeElementWeakComAggregateHandle existingElementHandle; if (_elementWeakComHandles.TryGetValue(key, out existingElementHandle)) { int newOrdinal = key.Ordinal; while (true) { newOrdinal++; var currentKey = new SyntaxNodeKey(key.Name, newOrdinal); if (!_elementWeakComHandles.ContainsKey(currentKey)) { // We found a free "slot": use it and release the previous one AbstractKeyedCodeElement existingElement = null; EnvDTE.CodeElement existingElementManagedObject; if (existingElementHandle.TryGetManagedObjectWithoutCaringWhetherNativeObjectIsAlive(out existingElementManagedObject)) { existingElement = existingElementManagedObject as AbstractKeyedCodeElement; } _elementWeakComHandles.Remove(key); if (existingElementHandle.ComAggregateObject == null) { // The native object has already been released. // There's no need to re-add this handle. break; } Debug.Assert(existingElement != null, "The ComAggregate is alive. Why isn't the actual managed object?"); _elementWeakComHandles.Add(currentKey, existingElementHandle); existingElement.NodeKey = currentKey; break; } } } Debug.Assert(!_elementWeakComHandles.ContainsKey(key), "All right, we got it wrong. We should ahve a free entry in the table!"); _elementWeakComHandles.Add(key, new CodeElementWeakComAggregateHandle(element)); }
private CodeElementWeakComAggregateHandle RemoveImpl(SyntaxNodeKey nodeKey) { CodeElementWeakComAggregateHandle elementHandleInTable; if (!_elementWeakComHandles.TryGetValue(nodeKey, out elementHandleInTable)) { Debug.Fail("Can't find code element being removed"); throw new InvalidOperationException(); } _elementWeakComHandles.Remove(nodeKey); return(elementHandleInTable); }
/// <summary> /// This function re-adds a code element to the table, taking care not to duplicate /// an element (i.e., making sure that no two elements with the same key-ordinal /// appear in the same element chain in the table). To resolve any conflict, each /// node with the given key is examined positionally, and the existing order is /// maintained as closely as possible -- but it is still possible the code element /// references to duplicate elements can get "bumped" by odd edits -- nothing we /// can do about this. /// </summary> internal void ResetElementNodeKey(AbstractKeyedCodeElement element, SyntaxNodeKey nodeKey) { EnvDTE.CodeElement elementInTable; _elementTable.Remove(element.NodeKey, out elementInTable); var abstractElementInTable = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>(elementInTable); if (!object.Equals(abstractElementInTable, element)) { Debug.Fail("Found a different element with the same key!"); throw new InvalidOperationException(); } abstractElementInTable.NodeKey = nodeKey; _elementTable.Add(nodeKey, elementInTable); }
internal void UpdateCodeElementNodeKey( AbstractKeyedCodeElement keyedElement, SyntaxNodeKey oldNodeKey, SyntaxNodeKey newNodeKey ) { if (!_codeElementTable.TryGetValue(oldNodeKey, out var codeElement)) { throw new InvalidOperationException( $"Could not find {oldNodeKey} in Code Model element table." ); } _codeElementTable.Remove(oldNodeKey); var managedElement = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>( codeElement ); if (!object.Equals(managedElement, keyedElement)) { throw new InvalidOperationException( $"Unexpected failure in Code Model while updating node keys {oldNodeKey} -> {newNodeKey}" ); } // If we're updating this element with the same node key as an element that's already in the table, // just remove the old element. The old element will continue to function (through its node key), but // the new element will replace it in the cache. if (_codeElementTable.ContainsKey(newNodeKey)) { _codeElementTable.Remove(newNodeKey); } _codeElementTable.Add(newNodeKey, codeElement); }
internal void OnCodeElementDeleted(SyntaxNodeKey nodeKey) { _codeElementTable.Remove(nodeKey); }
internal void UpdateCodeElementNodeKey(AbstractKeyedCodeElement keyedElement, SyntaxNodeKey oldNodeKey, SyntaxNodeKey newNodeKey) { if (!_codeElementTable.TryGetValue(oldNodeKey, out var codeElement)) { throw new InvalidOperationException($"Could not find {oldNodeKey} in Code Model element table."); } _codeElementTable.Remove(oldNodeKey); var managedElement = ComAggregate.GetManagedObject <AbstractKeyedCodeElement>(codeElement); if (!object.Equals(managedElement, keyedElement)) { throw new InvalidOperationException($"Unexpected failure in Code Model while updating node keys {oldNodeKey} -> {newNodeKey}"); } _codeElementTable.Add(newNodeKey, codeElement); }
internal void OnCodeElementCreated(SyntaxNodeKey nodeKey, EnvDTE.CodeElement element) { _codeElementTable.Add(nodeKey, element); }
internal SyntaxNode LookupNode(SyntaxNodeKey nodeKey) { return(CodeModelService.LookupNode(nodeKey, GetSyntaxTree())); }
public void Add(SyntaxNodeKey key, CodeElementWeakComAggregateHandle value) { TriggerCleanup(); InvalidateEnumerator(); _elements.Add(key, value); }
public void Remove(SyntaxNodeKey nodeKey) { RemoveImpl(nodeKey); }
public void Remove(SyntaxNodeKey nodeKey, out EnvDTE.CodeElement removedElement) { var elementHandleInTable = RemoveImpl(nodeKey); removedElement = elementHandleInTable.ComAggregateObject; }
private void AddElement(SyntaxNodeKey nodeKey, EnvDTE.CodeElement element) { _elementTable.Add(nodeKey, element); }
private void RemoveElement(SyntaxNodeKey nodeKey) { _elementTable.Remove(nodeKey); }
public bool TryGetValue(SyntaxNodeKey key, out CodeElementWeakComAggregateHandle value) { return(_elements.TryGetValue(key, out value)); }
internal void OnElementCreated(SyntaxNodeKey nodeKey, EnvDTE.CodeElement element) { AddElement(nodeKey, element); }
public bool ContainsKey(SyntaxNodeKey key) { return(_elements.ContainsKey(key)); }
internal TSyntaxNode LookupNode <TSyntaxNode>(SyntaxNodeKey nodeKey) where TSyntaxNode : SyntaxNode { return(CodeModelService.LookupNode(nodeKey, GetSyntaxTree()) as TSyntaxNode); }
public GlobalNodeKey(SyntaxNodeKey nodeKey, SyntaxPath path) { this.NodeKey = nodeKey; this.Path = path; }