提交 0e3f98fc 编写于 作者: D Dustin Campbell

Explicitly remove code model elements from the CleanableWeakComHandleTable when they are deleted

There are WinForms scenarios where code model elements can be deleted and re-added, for example,
when the modifiers of a control on the designer surface are changed the control will be deleted
and immediately re-added. We must be sure to delete the element's node key from the
CleanableWeakComHandleTable or else an exception will be thrown when the element is re-added with
the same node key.
上级 14d7e3e5
......@@ -199,6 +199,11 @@ internal void OnCodeElementCreated(SyntaxNodeKey nodeKey, EnvDTE.CodeElement ele
_codeElementTable.Add(nodeKey, element);
}
internal void OnCodeElementDeleted(SyntaxNodeKey nodeKey)
{
_codeElementTable.Remove(nodeKey);
}
internal T GetOrCreateCodeElement<T>(SyntaxNode node)
{
var nodeKey = CodeModelService.TryGetNodeKey(node);
......@@ -612,7 +617,7 @@ public void Remove(object element)
if (codeElement == null)
{
throw new ArgumentException(ServicesVSResources.ElementIsNotValid, "element");
throw new ArgumentException(ServicesVSResources.ElementIsNotValid, nameof(element));
}
codeElement.Delete();
......
......@@ -249,6 +249,12 @@ public virtual void RenameSymbol(string newName)
CodeModelService.Rename(LookupSymbol(), newName, this.Workspace.CurrentSolution);
}
protected virtual Document DeleteCore(Document document)
{
var node = LookupNode();
return CodeModelService.Delete(document, node);
}
/// <summary>
/// Delete the element from the source file.
/// </summary>
......@@ -256,8 +262,7 @@ internal void Delete()
{
FileCodeModel.PerformEdit(document =>
{
var node = LookupNode();
return CodeModelService.Delete(document, node);
return DeleteCore(document);
});
}
......
......@@ -95,6 +95,15 @@ protected void UpdateNodeAndReacquireNodeKey<T>(Action<SyntaxNode, T> updater, T
});
}
protected override Document DeleteCore(Document document)
{
var result = base.DeleteCore(document);
FileCodeModel.OnCodeElementDeleted(_nodeKey);
return result;
}
protected override string GetName()
{
if (IsUnknown)
......
......@@ -3812,6 +3812,24 @@ class $$C : Generic&lt;string&gt;
Await TestGetBaseName(code, "N.M.Generic<string>")
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestAddDeleteManyTimes() As Task
Dim code =
<Code>
class C$$
{
}
</Code>
Await TestElement(code,
Sub(codeClass)
For i = 1 To 100
Dim variable = codeClass.AddVariable("x", "System.Int32")
codeClass.RemoveMember(variable)
Next
End Sub)
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestTypeDescriptor_GetProperties() As Task
Dim code =
......
......@@ -3124,6 +3124,23 @@ End Class
Await TestGetBaseName(code, "N.M.Generic(Of String)")
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestAddDeleteManyTimes() As Task
Dim code =
<Code>
Class C$$
End Class
</Code>
Await TestElement(code,
Sub(codeClass)
For i = 1 To 100
Dim variable = codeClass.AddVariable("x", "System.Int32")
codeClass.RemoveMember(variable)
Next
End Sub)
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestExternalClass_ImplementedInterfaces() As Task
Dim code =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册