예제 #1
0
        CodeCellState InsertCodeCell(CodeCell newCell, Cell previousCell, bool isHidden = false)
        {
            if (newCell == null)
            {
                throw new ArgumentNullException(nameof(newCell));
            }

            InsertCellInDocumentModel(newCell, previousCell);

            var previousCodeCell = newCell.GetPreviousCell <CodeCell> ();
            var nextCodeCell     = newCell.GetNextCell <CodeCell> ();

            var codeCellState = new CodeCellState(newCell);

            if (isHidden)
            {
                // Set up editor, required as dictionary key
                codeCellState.Editor = new HiddenCodeCellEditor();
                codeCellState.View   = new HiddenCodeCellView {
                    Editor = codeCellState.Editor
                };
                newCell.View = codeCellState.View;
            }
            else
            {
                BindCodeCellToView(newCell, codeCellState);
            }

            if (ClientSession.CompilationWorkspace != null)
            {
                codeCellState.CompilationWorkspace = ClientSession.CompilationWorkspace;
                codeCellState.DocumentId           = ClientSession.CompilationWorkspace.AddSubmission(
                    newCell.CodeAnalysisBuffer.CurrentText,
                    GetDocumentId(previousCodeCell),
                    GetDocumentId(nextCodeCell));
            }

            if (!isHidden)
            {
                InsertCellInViewModel(newCell, previousCell);
            }

            OutdateAllCodeCells(newCell);

            AppendCodeCell(codeCellState.Editor, codeCellState);

            return(codeCellState);
        }
예제 #2
0
        static void RenderResult(
            CodeCellState codeCellState,
            Evaluation result,
            bool isResultAnExpression)
        {
            if (codeCellState == null)
            {
                throw new ArgumentNullException(nameof(codeCellState));
            }

            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            var cultureInfo = CultureInfo.CurrentCulture;

            try {
                cultureInfo = CultureInfo.GetCultureInfo(result.CultureLCID);
            } catch (Exception e) when(
                e is CultureNotFoundException ||
                e is ArgumentOutOfRangeException)
            {
                Log.Error(TAG, $"Invalid CultureInfo LCID: {result.CultureLCID}");
            }

            codeCellState.View.EvaluationDuration = result.EvaluationDuration;

            if (result.Exception != null)
            {
                codeCellState.View.RenderResult(
                    cultureInfo,
                    FilterException(result.Exception),
                    result.ResultHandling);
            }
            else if (!result.Interrupted && result.Result != null || isResultAnExpression)
            {
                codeCellState.View.RenderResult(
                    cultureInfo,
                    result.Result,
                    result.ResultHandling);
            }
        }
예제 #3
0
        async Task <EvaluationStatus> CoreEvaluateCodeCellAsync(
            CodeCellState codeCellState,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken = ClientSession.CancellationToken.LinkWith(cancellationToken);

            if (!ClientSession.Agent.IsConnected || ClientSession.CompilationWorkspace == null)
            {
                codeCellState.View.IsEvaluating        = false;
                codeCellState.View.HasErrorDiagnostics = true;
                codeCellState.View.RenderDiagnostic(new Diagnostic(
                                                        DiagnosticSeverity.Error,
                                                        "Cannot evaluate: not connected to agent."));
                return(EvaluationStatus.Disconnected);
            }

            CodeAnalysis.Compilation   compilation = null;
            IReadOnlyList <Diagnostic> diagnostics = null;
            ExceptionNode exception = null;
            bool          agentTerminatedWhileEvaluating = false;

            try {
                compilation = await ClientSession.CompilationWorkspace.EmitCellCompilationAsync(
                    codeCellState.CodeCellId,
                    new EvaluationEnvironment (ClientSession.WorkingDirectory),
                    cancellationToken);

                diagnostics = await ClientSession.CompilationWorkspace.GetCellDiagnosticsAsync(
                    codeCellState.CodeCellId,
                    cancellationToken);

                var integrationAssemblies = compilation
                                            .References
                                            .Where(ra => ra.HasIntegration)
                                            .ToArray();
                if (integrationAssemblies.Length > 0)
                {
                    await ClientSession.Agent.Api.EvaluationContextManager.LoadAssembliesAsync(
                        TargetCompilationConfiguration.EvaluationContextId,
                        integrationAssemblies);
                }
            } catch (Exception e) {
                exception = ExceptionNode.Create(e);
            }

            var hasErrorDiagnostics = codeCellState.View.HasErrorDiagnostics = diagnostics
                                                                               .Any(d => d.Severity == DiagnosticSeverity.Error);

            foreach (var diagnostic in diagnostics)
            {
                codeCellState.View.RenderDiagnostic(diagnostic);
            }

            try {
                if (compilation != null)
                {
                    await ClientSession.Agent.Api.EvaluationContextManager.EvaluateAsync(
                        TargetCompilationConfiguration.EvaluationContextId,
                        compilation,
                        cancellationToken);
                }
            } catch (XipErrorMessageException e) {
                exception = e.XipErrorMessage.Exception;
            } catch (Exception e) {
                Log.Error(TAG, "marking agent as terminated", e);
                agentTerminatedWhileEvaluating         = true;
                codeCellState.View.HasErrorDiagnostics = true;
                codeCellState.View.RenderDiagnostic(new Diagnostic(
                                                        DiagnosticSeverity.Error,
                                                        Catalog.GetString(
                                                            "The application terminated during evaluation of this cell. " +
                                                            "Run this cell manually to try again.")));
            }

            codeCellState.View.IsEvaluating = false;

            EvaluationStatus evaluationStatus;

            if (exception != null)
            {
                codeCellState.View.RenderResult(
                    CultureInfo.CurrentCulture,
                    exception,
                    EvaluationResultHandling.Replace);
                evaluationStatus = EvaluationStatus.EvaluationException;
            }
            else if (hasErrorDiagnostics)
            {
                return(EvaluationStatus.ErrorDiagnostic);
            }
            else if (agentTerminatedWhileEvaluating)
            {
                evaluationStatus = EvaluationStatus.Disconnected;
            }
            else
            {
                evaluationStatus = EvaluationStatus.Success;
            }

            if (ClientSession.SessionKind != ClientSessionKind.Workbook)
            {
                codeCellState.Freeze();
            }

            codeCellState.NotifyEvaluated(agentTerminatedWhileEvaluating);
            return(evaluationStatus);
        }
예제 #4
0
        // Only call this from EvaluateCodeCellAsync, for CanEvaluate handling
        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);
            }
        }
예제 #5
0
 void AppendCodeCell(IEditor editor, CodeCellState codeCellState)
 => codeCells = codeCells.Add(editor, codeCellState);
예제 #6
0
 protected abstract void BindCodeCellToView(CodeCell cell, CodeCellState codeCellState);
예제 #7
0
        async Task <CodeCellEvaluationStatus> CoreEvaluateCodeCellAsync(
            CodeCellState codeCellState,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken = ClientSession.CancellationToken.LinkWith(cancellationToken);

            if (!ClientSession.Agent.IsConnected || ClientSession.CompilationWorkspace == null)
            {
                codeCellState.View.IsEvaluating        = false;
                codeCellState.View.HasErrorDiagnostics = true;
                codeCellState.View.RenderDiagnostic(new InteractiveDiagnostic(
                                                        DiagnosticSeverity.Error,
                                                        "Cannot evaluate: not connected to agent."));
                return(CodeCellEvaluationStatus.Disconnected);
            }

            CodeAnalysis.Compilation compilation = null;
            ExceptionNode            exception   = null;
            bool agentTerminatedWhileEvaluating  = false;

            try {
                compilation = await ClientSession.CompilationWorkspace.GetSubmissionCompilationAsync(
                    codeCellState.DocumentId,
                    new EvaluationEnvironment (ClientSession.WorkingDirectory),
                    cancellationToken);

                var integrationAssemblies = compilation
                                            .References
                                            .Where(ra => ra.HasIntegration)
                                            .ToArray();
                if (integrationAssemblies.Length > 0)
                {
                    await ClientSession.Agent.Api.LoadAssembliesAsync(
                        ClientSession.CompilationWorkspace.EvaluationContextId,
                        integrationAssemblies);
                }

                foreach (var dependency in ClientSession.CompilationWorkspace.WebDependencies)
                {
                    if (ClientSession.AddWebResource(dependency.Location, out var guid))
                    {
                        await LoadWorkbookDependencyAsync(guid + dependency.Location.Extension);
                    }
                }
            } catch (Exception e) {
                exception = ExceptionNode.Create(e);
            }

            var diagnostics = ClientSession.CompilationWorkspace.CurrentSubmissionDiagnostics.Filter();

            codeCellState.View.HasErrorDiagnostics = diagnostics.HasErrors;

            foreach (var diagnostic in diagnostics)
            {
                codeCellState.View.RenderDiagnostic((InteractiveDiagnostic)diagnostic);
            }

            try {
                if (compilation != null)
                {
                    codeCellState.LastEvaluationRequestId = compilation.MessageId;
                    codeCellState.IsResultAnExpression    = compilation.IsResultAnExpression;

                    await ClientSession.Agent.Api.EvaluateAsync(
                        compilation,
                        cancellationToken);
                }
            } catch (XipErrorMessageException e) {
                exception = e.XipErrorMessage.Exception;
            } catch (Exception e) {
                Log.Error(TAG, "marking agent as terminated", e);
                agentTerminatedWhileEvaluating         = true;
                codeCellState.View.HasErrorDiagnostics = true;
                codeCellState.View.RenderDiagnostic(new InteractiveDiagnostic(
                                                        DiagnosticSeverity.Error,
                                                        Catalog.GetString(
                                                            "The application terminated during evaluation of this cell. " +
                                                            "Run this cell manually to try again.")));
            }

            codeCellState.View.IsEvaluating = false;

            CodeCellEvaluationStatus evaluationStatus;

            if (exception != null)
            {
                codeCellState.View.RenderResult(
                    CultureInfo.CurrentCulture,
                    FilterException(exception),
                    EvaluationResultHandling.Replace);
                evaluationStatus = CodeCellEvaluationStatus.EvaluationException;
            }
            else if (diagnostics.HasErrors)
            {
                return(CodeCellEvaluationStatus.ErrorDiagnostic);
            }
            else if (agentTerminatedWhileEvaluating)
            {
                evaluationStatus = CodeCellEvaluationStatus.Disconnected;
            }
            else
            {
                evaluationStatus = CodeCellEvaluationStatus.Success;
            }

            if (ClientSession.SessionKind != ClientSessionKind.Workbook)
            {
                codeCellState.Freeze();
            }

            codeCellState.NotifyEvaluated(agentTerminatedWhileEvaluating);
            return(evaluationStatus);
        }