async Task DoEvaluateCodeCellAsync()

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);
            }
        }