| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 | using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Reflection;using System.Runtime.CompilerServices;using System.Threading.Tasks;using Microsoft.CodeAnalysis;using Microsoft.CodeAnalysis.CSharp.Scripting;using Microsoft.CodeAnalysis.CSharp.Scripting.Hosting;using Microsoft.CodeAnalysis.Scripting;using Microsoft.CodeAnalysis.Scripting.Hosting;using RoslynPad.Roslyn;namespace InABox.DynamicGrid{    internal class DocumentViewModel : INotifyPropertyChanged    {        private readonly RoslynHost _host;        private bool _isReadOnly;        private string _result;        public DocumentViewModel(RoslynHost host, DocumentViewModel previous)        {            _host = host;            Previous = previous;        }        public DocumentId Id { get; private set; }        public bool IsReadOnly        {            get => _isReadOnly;            private set => SetProperty(ref _isReadOnly, value);        }        public DocumentViewModel Previous { get; }        public DocumentViewModel LastGoodPrevious        {            get            {                var previous = Previous;                while (previous != null && previous.HasError) previous = previous.Previous;                return previous;            }        }        public Script<object> Script { get; private set; }        public string Text { get; set; }        public bool HasError { get; private set; }        public string Result        {            get => _result;            private set => SetProperty(ref _result, value);        }        private static MethodInfo HasSubmissionResult { get; } =            typeof(Compilation).GetMethod(nameof(HasSubmissionResult), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);        private static PrintOptions PrintOptions { get; } = new() { MemberDisplayFormat = MemberDisplayFormat.SeparateLines };        public event PropertyChangedEventHandler? PropertyChanged;        internal void Initialize(DocumentId id)        {            Id = id;        }        public async Task<bool> TrySubmit()        {            Result = null;            Script = LastGoodPrevious?.Script.ContinueWith(Text) ??                     CSharpScript.Create(Text, ScriptOptions.Default                         .WithReferences(_host.DefaultReferences)                         .WithImports(_host.DefaultImports));            var compilation = Script.GetCompilation();            var hasResult = (bool)HasSubmissionResult.Invoke(compilation, null);            var diagnostics = Script.Compile();            if (diagnostics.Any(t => t.Severity == DiagnosticSeverity.Error))            {                Result = string.Join(Environment.NewLine, diagnostics.Select(FormatObject));                return false;            }            IsReadOnly = true;            await Execute(hasResult);            return true;        }        private async Task Execute(bool hasResult)        {            try            {                var result = await Script.RunAsync();                if (result.Exception != null)                {                    HasError = true;                    Result = FormatException(result.Exception);                }                else                {                    Result = hasResult ? FormatObject(result.ReturnValue) : null;                }            }            catch (Exception ex)            {                HasError = true;                Result = FormatException(ex);            }        }        private static string FormatException(Exception ex)        {            return CSharpObjectFormatter.Instance.FormatException(ex);        }        private static string FormatObject(object o)        {            return CSharpObjectFormatter.Instance.FormatObject(o, PrintOptions);        }        protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)        {            if (!EqualityComparer<T>.Default.Equals(field, value))            {                field = value;                // ReSharper disable once ExplicitCallerInfoArgument                OnPropertyChanged(propertyName);                return true;            }            return false;        }        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)        {            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));        }    }}
 |