// Обновляет список вызванных методов для this, если это имеет статус DependsOnInvocation. // Иначе удаляет список вызванных методов. // Cразу применяет все действия. // Возвращает были ли изменения. private bool UpdateInvokedExpressionsForThis(ICollection<ControlFlowElementData> previousElems, ControlFlowElementData data, VariableDisposeStatus resultStatus) { if (resultStatus != VariableDisposeStatus.DependsOnInvocation) { if (data.ThisInvokedExpressions.Any()) { data.ThisInvokedExpressions.Clear(); return true; } } var result = new HashSet<InvokedExpressionData>(data.ThisInvokedExpressions); foreach (var previousElem in previousElems) { if (previousElem == null || !previousElem.IsVisited()) continue; var previousStatus = previousElem.ThisStatus; if (previousStatus == null) continue; if (previousStatus != VariableDisposeStatus.DependsOnInvocation) continue; result.AddRange(previousElem.ThisInvokedExpressions); } var changesAre = result.Except(data.ThisInvokedExpressions).Any(); // или вычисляется лениво data.ThisInvokedExpressions = result; return changesAre; }
// Вычисляет статус на основе предыдущего объединенного статуса и текущего статуса. private VariableDisposeStatus CombinePreviousAndCurrent(VariableDisposeStatus previousStatus, VariableDisposeStatus status) { switch (status) { case VariableDisposeStatus.Disposed: return VariableDisposeStatus.Disposed; case VariableDisposeStatus.NotDisposed: return VariableDisposeStatus.NotDisposed; case VariableDisposeStatus.Both: return VariableDisposeStatus.Both; case VariableDisposeStatus.Unknown: return previousStatus; case VariableDisposeStatus.DependsOnInvocation: switch (previousStatus) { case VariableDisposeStatus.Disposed: return VariableDisposeStatus.Disposed; case VariableDisposeStatus.Both: return VariableDisposeStatus.Both; default: return VariableDisposeStatus.DependsOnInvocation; } default: Assertion.Fail("Unaccounted VariableDisposeStatus"); return VariableDisposeStatus.Unknown; } }