in Clients/Xamarin.Interactive.Client/Workbook/Models/WorkbookPageViewModel.cs [451:526]
async Task DoEvaluateCodeCellAsync (CodeCellState codeCellState, bool evaluateAll = false)
{
await ClientSession.EnsureAgentConnectionAsync ();
var codeCellsToEvaluate = ImmutableList<CodeCellState>.Empty;
var originalCodeCellState = codeCellState;
if (ClientSession.ViewControllers.ReplHistory != null) {
ClientSession.ViewControllers.ReplHistory.UpdateLastAppended (
codeCellState.Cell.Buffer.Value.Trim ());
ClientSession.ViewControllers.ReplHistory.Save ();
}
var codeCell = originalCodeCellState.Cell;
var isLastCell = codeCell.GetNextCell<CodeCell> () == null;
var isFirstCell = codeCell.GetPreviousCell<CodeCell> () == null;
if (isFirstCell && ClientSession.SessionKind == ClientSessionKind.Workbook)
await ClientSession.Agent.Api.EvaluationContextManager.ResetStateAsync (
TargetCompilationConfiguration.EvaluationContextId);
while (codeCell != null) {
if (CodeCells.TryGetValue (codeCell.View.Editor, out codeCellState)) {
var evaluateCodeCell =
codeCellState == originalCodeCellState ||
codeCellState.EvaluationCount == 0 ||
codeCellState.View.IsDirty ||
codeCellState.View.IsOutdated;
if (await ClientSession.CompilationWorkspace.IsCellOutdatedAsync (codeCellState.CodeCellId))
evaluateCodeCell = true;
if (evaluateCodeCell)
codeCellsToEvaluate = codeCellsToEvaluate.Insert (0, codeCellState);
}
codeCell = codeCell.GetPreviousCell<CodeCell> ();
}
codeCell = originalCodeCellState.Cell;
var skipRemainingCodeCells = false;
while (true) {
codeCell = codeCell.GetNextCell<CodeCell> ();
if (codeCell == null)
break;
if (CodeCells.TryGetValue (codeCell.View.Editor, out codeCellState)) {
if (skipRemainingCodeCells || codeCellState.AgentTerminatedWhileEvaluating)
skipRemainingCodeCells = true;
else if (evaluateAll || codeCellState.EvaluationCount > 0)
codeCellsToEvaluate = codeCellsToEvaluate.Add (codeCellState);
codeCellState.View.IsOutdated = true;
}
}
foreach (var evaluatableCodeCell in codeCellsToEvaluate) {
evaluatableCodeCell.View.Reset ();
evaluatableCodeCell.View.IsEvaluating = true;
switch (await CoreEvaluateCodeCellAsync (evaluatableCodeCell)) {
case EvaluationStatus.ErrorDiagnostic:
case EvaluationStatus.Disconnected:
return;
}
}
if (isLastCell && !evaluateAll)
StartNewCodeCell ();
// NOTE: I cannot remember why this has to be run after awaiting
// CoreEvaluateCodeCellAsync but it does... so don't move it? -abock
if (ClientSession.ViewControllers.ReplHistory != null) {
ClientSession.ViewControllers.ReplHistory.CursorToEnd ();
ClientSession.ViewControllers.ReplHistory.Append (null);
}
}