diff --git a/src/components/tbc.core/Http/HttpServer.cs b/src/components/tbc.core/Http/HttpServer.cs index 67ab821..018909a 100644 --- a/src/components/tbc.core/Http/HttpServer.cs +++ b/src/components/tbc.core/Http/HttpServer.cs @@ -83,7 +83,7 @@ private async Task HandleRequest (string path, Stream inputStream) using var sr = new StreamReader(inputStream); var json = await sr.ReadToEndAsync(); var content = JsonSerializer.Deserialize(json, type, new JsonSerializerOptions(JsonSerializerDefaults.Web)); - var ret = await action(content); + var ret = await action(content!); return ret; } @@ -110,7 +110,7 @@ private static async Task Write(object ret, HttpListenerResponse resp) private void SetHandlerOperations(THandler handler) { - _handlerOperations = typeof(THandler).GetMethods().Concat(handler.GetType().GetMethods()) + _handlerOperations = typeof(THandler).GetMethods().Concat(handler!.GetType().GetMethods()) .Select(x => (x.GetCustomAttribute(), x)) .Where(x => x.Item1 != null) .ToDictionary(x => x.Item1.Path, x => (x.x.GetParameters()[0].ParameterType, diff --git a/src/components/tbc.core/Models/OperationModels.cs b/src/components/tbc.core/Models/OperationModels.cs index 696bf6c..b73339c 100644 --- a/src/components/tbc.core/Models/OperationModels.cs +++ b/src/components/tbc.core/Models/OperationModels.cs @@ -38,10 +38,10 @@ public record SocketRequest : ISocketMessage public string RequestIdentifier { get; set; } = default!; [Key(1)] - public T Payload { get; set; } = default!; + public T Payload { get; init; } = default!; SocketMessageKind ISocketMessage.Kind => SocketMessageKind.Request; - object ISocketMessage.Payload => Payload; + object ISocketMessage.Payload => Payload!; } [MessagePackObject] @@ -60,7 +60,7 @@ public record SocketResponse : ISocketMessage public string? ErrorData { get; set; } SocketMessageKind ISocketMessage.Kind => SocketMessageKind.Response; - object ISocketMessage.Payload => Data; + object ISocketMessage.Payload => Data!; public SocketResponse() { } @@ -120,7 +120,7 @@ public record LoadDynamicAssemblyRequest public string AssemblyName { get; set; } = default!; [Key(3)] - public string PrimaryTypeName { get; set; } = default!; + public string? PrimaryTypeName { get; set; } = default!; } [MessagePackObject] diff --git a/src/components/tbc.core/Socket/Abstractions/ISendToRemote.cs b/src/components/tbc.core/Socket/Abstractions/ISendToRemote.cs index 33a7ac0..c8b7108 100644 --- a/src/components/tbc.core/Socket/Abstractions/ISendToRemote.cs +++ b/src/components/tbc.core/Socket/Abstractions/ISendToRemote.cs @@ -2,5 +2,5 @@ namespace Tbc.Core.Socket.Abstractions; public interface ISendToRemote { - IRemoteEndpoint Remote { get; set; } -} \ No newline at end of file + IRemoteEndpoint? Remote { get; set; } +} diff --git a/src/components/tbc.core/Socket/Serialization/Serializers/ClearTextSystemTextJsonSocketSerializer.cs b/src/components/tbc.core/Socket/Serialization/Serializers/ClearTextSystemTextJsonSocketSerializer.cs index d52025b..fdbfc67 100644 --- a/src/components/tbc.core/Socket/Serialization/Serializers/ClearTextSystemTextJsonSocketSerializer.cs +++ b/src/components/tbc.core/Socket/Serialization/Serializers/ClearTextSystemTextJsonSocketSerializer.cs @@ -18,7 +18,7 @@ public object Deserialize(Type type, byte[] data) var json = Encoding.UTF8.GetString(data); var ret = JsonSerializer.Deserialize(json, type, _serializerOptions); - return ret; + return ret!; } private readonly JsonSerializerOptions _serializerOptions = new(JsonSerializerDefaults.Web); diff --git a/src/components/tbc.core/Socket/Serialization/Serializers/SystemTextJsonSocketSerializer.cs b/src/components/tbc.core/Socket/Serialization/Serializers/SystemTextJsonSocketSerializer.cs index 75c9f2a..8e685a5 100644 --- a/src/components/tbc.core/Socket/Serialization/Serializers/SystemTextJsonSocketSerializer.cs +++ b/src/components/tbc.core/Socket/Serialization/Serializers/SystemTextJsonSocketSerializer.cs @@ -29,7 +29,7 @@ public object Deserialize(Type type, byte[] data) var ret = JsonSerializer.Deserialize(gz, type, _serializerOptions); - return ret; + return ret!; } private readonly JsonSerializerOptions _serializerOptions = new(JsonSerializerDefaults.Web); diff --git a/src/components/tbc.core/Socket/SocketServer.cs b/src/components/tbc.core/Socket/SocketServer.cs index 8eeff39..7dc0fb9 100644 --- a/src/components/tbc.core/Socket/SocketServer.cs +++ b/src/components/tbc.core/Socket/SocketServer.cs @@ -56,7 +56,8 @@ public class SocketServer : IRemoteEndpoint { SocketSerializationFormat.Json => new ClearTextSystemTextJsonSocketSerializer(), SocketSerializationFormat.CompressedJson => new SystemTextJsonSocketSerializer(), - SocketSerializationFormat.MessagePack => new MessagePackSocketSerializer() + SocketSerializationFormat.MessagePack => new MessagePackSocketSerializer(), + _ => throw new ArgumentOutOfRangeException() }; if (Handler is ISendToRemote str) @@ -66,7 +67,7 @@ public class SocketServer : IRemoteEndpoint SetHandlerOperations(); } - public async Task Run(CancellationToken ct = default) + public Task Run(CancellationToken ct = default) { #pragma warning disable CS4014 Task.Run(async () => await RunRequestLoop(ct)) @@ -77,6 +78,8 @@ public async Task Run(CancellationToken ct = default) _log(t.Exception?.ToString() ?? "no exception"); _finished = true; }); + + return Task.CompletedTask; } private async Task RunRequestLoop(CancellationToken ct = default) @@ -251,7 +254,8 @@ private async Task Receive(CancellationToken ct) socketMessageKind switch { SocketMessageKind.Request => typeof(SocketRequest<>).MakeGenericType(incomingType), - SocketMessageKind.Response => typeof(SocketResponse<>).MakeGenericType(incomingType) + SocketMessageKind.Response => typeof(SocketResponse<>).MakeGenericType(incomingType), + _ => throw new ArgumentOutOfRangeException() }; var message = (ISocketMessage) diff --git a/src/components/tbc.core/tbc.core.csproj b/src/components/tbc.core/tbc.core.csproj index cc0d19f..f5ab1d5 100644 --- a/src/components/tbc.core/tbc.core.csproj +++ b/src/components/tbc.core/tbc.core.csproj @@ -3,7 +3,7 @@ netstandard2.1;net472 Tbc.Core - latest + preview true true embedded diff --git a/src/components/tbc.host/Components/CommandProcessor/CommandProcessor.cs b/src/components/tbc.host/Components/CommandProcessor/CommandProcessor.cs index 5ab489f..f4a8fd8 100644 --- a/src/components/tbc.host/Components/CommandProcessor/CommandProcessor.cs +++ b/src/components/tbc.host/Components/CommandProcessor/CommandProcessor.cs @@ -45,7 +45,7 @@ public void PrintCommands() , Formatting.Indented)); } - public async Task HandleCommand(string command) + public async Task HandleCommand(string command) { if (String.IsNullOrWhiteSpace(command)) return null; diff --git a/src/components/tbc.host/Components/CommandProcessor/ICommandProcessor.cs b/src/components/tbc.host/Components/CommandProcessor/ICommandProcessor.cs index eed38ea..f4b2f98 100644 --- a/src/components/tbc.host/Components/CommandProcessor/ICommandProcessor.cs +++ b/src/components/tbc.host/Components/CommandProcessor/ICommandProcessor.cs @@ -6,7 +6,7 @@ public interface ICommandProcessor { void RegisterCommands(object context); void RegisterManyCommands(params object[] context); - Task HandleCommand(string command); + Task HandleCommand(string command); void PrintCommands(); } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Components/CommandProcessor/Models/TbcCommand.cs b/src/components/tbc.host/Components/CommandProcessor/Models/TbcCommand.cs index c46b205..b440fd8 100644 --- a/src/components/tbc.host/Components/CommandProcessor/Models/TbcCommand.cs +++ b/src/components/tbc.host/Components/CommandProcessor/Models/TbcCommand.cs @@ -6,9 +6,9 @@ namespace Tbc.Host.Components.CommandProcessor.Models { public class TbcCommand { - public string Command { get; set; } + public required string Command { get; init; } [JsonIgnore] - public Func Execute { get; set; } + public required Func Execute { get; init; } } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Components/CommandProcessor/Models/TbcComponentCommand.cs b/src/components/tbc.host/Components/CommandProcessor/Models/TbcComponentCommand.cs index 15b1b86..f667b3c 100644 --- a/src/components/tbc.host/Components/CommandProcessor/Models/TbcComponentCommand.cs +++ b/src/components/tbc.host/Components/CommandProcessor/Models/TbcComponentCommand.cs @@ -2,7 +2,7 @@ { public class TbcComponentCommand { - public string ComponentIdentifier { get; set; } - public TbcCommand Command { get; set; } + public required string ComponentIdentifier { get; init; } + public required TbcCommand Command { get; init; } } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Components/FileEnvironment/FileEnvironment.cs b/src/components/tbc.host/Components/FileEnvironment/FileEnvironment.cs index b09f5f0..d1c8441 100644 --- a/src/components/tbc.host/Components/FileEnvironment/FileEnvironment.cs +++ b/src/components/tbc.host/Components/FileEnvironment/FileEnvironment.cs @@ -23,8 +23,6 @@ namespace Tbc.Host.Components.FileEnvironment { public partial class FileEnvironment : TransientComponentBase, IFileEnvironment, IExposeCommands, IHaveComponentsThatExposeCommands { - private bool _running; - public ITargetClient Client { get; } public ICommandProcessor CommandProcessor { get; } public IFileWatcher FileWatcher { get; } @@ -42,10 +40,14 @@ public partial class FileEnvironment : TransientComponentBase, FileSystem = fileSystem; FileWatcher = fileWatcher; IncrementalCompiler = incrementalCompilerFactory($"{client.Address}:{client.Port}"); - IncrementalCompiler.RootPath = FileWatcher.WatchPath; + IncrementalCompiler.SetRootPath(FileWatcher.WatchPath); } - private string _primaryTypeHint; + private bool _running; + public bool Terminated { get; set; } + private string? _primaryTypeHint; + private EmittedAssembly? _lastEmittedAssembly; + private string? _loadContext; public async Task Run() { @@ -60,19 +62,21 @@ public async Task Run() await TryLoadLoadContext(); - Task.Factory.StartNew(SetupReferenceTracking, TaskCreationOptions.LongRunning); + Task.Factory.StartNew(SetupReferenceTracking, TaskCreationOptions.LongRunning) + .FireAndForgetSafeAsync(); FileWatcher .Changes .Where(_ => !Terminated) .Select(IncrementalCompiler.StageFile) .Where(x => x != null) - .SelectMany(SendAssemblyForReload) + .SelectMany(SendAssemblyForReload!) .Subscribe(x => Logger.Log(x.Success ? LogLevel.Information : LogLevel.Error, "Send incremental assembly outcome: {@Outcome}", x)); Logger.LogInformation("FileEnvironment for client {@Client} initialised", Client); - Task.Factory.StartNew(SetupCommandListening, TaskCreationOptions.LongRunning); + Task.Factory.StartNew(SetupCommandListening, TaskCreationOptions.LongRunning) + .FireAndForgetSafeAsync(); await Client.WaitForTerminalState(); @@ -104,8 +108,8 @@ public async Task Reset() await TryLoadLoadContext(); - Task.Factory.StartNew(SetupReferenceTracking, TaskCreationOptions.LongRunning); - Task.Factory.StartNew(SetupCommandListening, TaskCreationOptions.LongRunning); + Task.Factory.StartNew(SetupReferenceTracking, TaskCreationOptions.LongRunning).FireAndForgetSafeAsync(); + Task.Factory.StartNew(SetupCommandListening, TaskCreationOptions.LongRunning).FireAndForgetSafeAsync(); } public async Task SetupReferenceTracking() @@ -129,7 +133,8 @@ public async Task SetupReferenceTracking() // allow a little time for references to come back <:-) // should have client tell us when all current dependencies have been sent - Task.Delay(TimeSpan.FromSeconds(.33)).ContinueWith(_ => IncrementalCompiler.DoWarmup()); + Task.Delay(TimeSpan.FromSeconds(.33)).ContinueWith(_ => IncrementalCompiler.DoWarmup()) + .FireAndForgetSafeAsync(); } if (targetHello.UseDependencyCache && targetHello.ApplicationIdentifier is { } appIdentifier) @@ -197,11 +202,6 @@ public async Task SetupCommandListening() Logger.LogError(ex, nameof(SetupCommandListening)); } } - - public bool Terminated { get; set; } - - private EmittedAssembly _lastEmittedAssembly; - private string _loadContext; public async Task SendAssemblyForReload(EmittedAssembly asm) { @@ -213,14 +213,14 @@ public async Task SendAssemblyForReload(EmittedAssembly asm) PdbBytes = asm.Pd, PrimaryTypeName = String.IsNullOrWhiteSpace(_primaryTypeHint) - ? "" + ? null : TryResolvePrimaryType(_primaryTypeHint) }; return await Client.RequestClientLoadAssemblyAsync(req); } - public string TryResolvePrimaryType(string typeHint) + public string? TryResolvePrimaryType(string typeHint) => IncrementalCompiler.TryResolvePrimaryType(typeHint); public Task PrintTrees(bool withDetail = false) @@ -230,9 +230,9 @@ public Task PrintTrees(bool withDetail = false) return Task.CompletedTask; } - public async Task SetPrimaryTypeHint(string typeHint) + public async Task SetPrimaryTypeHint(string? maybeTypeHint) { - _primaryTypeHint = typeHint; + _primaryTypeHint = maybeTypeHint; if (_lastEmittedAssembly != null) await SendAssemblyForReload(_lastEmittedAssembly); @@ -298,7 +298,7 @@ string IExposeCommands.Identifier break; default: - Logger.LogWarning("Don't know how to handle subcommand '{SubCommand}' of context"); + Logger.LogWarning("Don't know how to handle subcommand '{SubCommand}' of context", sub); break; } @@ -322,7 +322,7 @@ public void SetLoadContext(string saveIdentifier) { _loadContext = saveIdentifier; - Reset(); + Reset().FireAndForgetSafeAsync(); } public IEnumerable Components @@ -356,6 +356,6 @@ private async Task AddSharedFilesystemReference(TargetHello targetHello, List WatchedFiles { get; set; } + public List WatchedFiles { get; set; } = new(); } } diff --git a/src/components/tbc.host/Components/FileEnvironment/Models/IRemoteClientDefinition.cs b/src/components/tbc.host/Components/FileEnvironment/Models/IRemoteClientDefinition.cs index e0ad865..355b21f 100644 --- a/src/components/tbc.host/Components/FileEnvironment/Models/IRemoteClientDefinition.cs +++ b/src/components/tbc.host/Components/FileEnvironment/Models/IRemoteClientDefinition.cs @@ -2,8 +2,8 @@ namespace Tbc.Host.Components.FileEnvironment.Models { public interface IRemoteClientDefinition { - public string Address { get; set; } - public int Port { get; set; } + public string Address { get; } + public int Port { get; } public string HttpAddress => $"http://{Address}:{Port}"; } diff --git a/src/components/tbc.host/Components/FileEnvironment/Models/RemoteClient.cs b/src/components/tbc.host/Components/FileEnvironment/Models/RemoteClient.cs index 568fb02..1d56cd4 100644 --- a/src/components/tbc.host/Components/FileEnvironment/Models/RemoteClient.cs +++ b/src/components/tbc.host/Components/FileEnvironment/Models/RemoteClient.cs @@ -1,11 +1,11 @@ namespace Tbc.Host.Components.FileEnvironment.Models { - public class RemoteClient : IRemoteClientDefinition + public record RemoteClient : IRemoteClientDefinition { - public string Address { get; set; } - public int Port { get; set; } + public required string Address { get; init; } + public required int Port { get; set; } public override string ToString() => $"{Address}:{Port}"; } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Components/FileWatcher/FileWatcher.cs b/src/components/tbc.host/Components/FileWatcher/FileWatcher.cs index 1c419d1..c5bf194 100644 --- a/src/components/tbc.host/Components/FileWatcher/FileWatcher.cs +++ b/src/components/tbc.host/Components/FileWatcher/FileWatcher.cs @@ -21,33 +21,26 @@ public class FileWatcher : ComponentBase, IFileWatcher, IExposeComm private readonly IFileSystem _fileSystem; public string WatchPath { get; private set; } - public ChangedFile LastChangedFile { get; private set; } + public ChangedFile? LastChangedFile { get; private set; } - private Subject _manualWatchFiles = new Subject(); + private readonly Subject _manualWatchFiles = new Subject(); public IObservable Changes { get; set; } public FileWatcher(FileWatchConfig config, IFileSystem fileSystem, ILogger logger) : base(logger) { _fileSystem = fileSystem; _config = config; - - Init(); - } - private void Init() - { - Changes = - Observable.Merge( - _manualWatchFiles, // files added to the incremental by a 'watch' command - CreateFileSystemWatcher(_config.RootPath, _config.FileMask)); // files actually changed + WatchPath = _config.RootPath; + Changes = Observable.Merge( + _manualWatchFiles, // files added to the incremental by a 'watch' command + CreateFileSystemWatcher(_config.FileMask)); // files actually changed } - - public IObservable CreateFileSystemWatcher(string path, string mask) + + public IObservable CreateFileSystemWatcher(string mask) { - WatchPath = path; - if (!_fileSystem.Path.IsPathRooted(WatchPath)) - WatchPath = _fileSystem.Path.Combine(Environment.CurrentDirectory, path); + WatchPath = _fileSystem.Path.Combine(Environment.CurrentDirectory, WatchPath); Logger.LogInformation("Watching files under path {Path}", WatchPath); @@ -64,19 +57,20 @@ public IObservable CreateFileSystemWatcher(string path, string mask var ret = Observable - .Merge(ofsw.Changed, ofsw.Created, ofsw.Renamed, ofsw.Deleted) - .Where(x => !_config.Ignore.Any(i => x.FullPath.Contains((string) i))) - .Select(x => x.FullPath) - .Select(TryGetChangedFile) - .Where(x => x != null) - .Do(f => Logger.LogInformation("Changed File: {ChangedFile}", f.Path.Substring(WatchPath.Length))); + .Merge(ofsw.Changed, ofsw.Created, ofsw.Renamed, ofsw.Deleted) + .Where(x => !_config.Ignore.Any(i => x.FullPath.Contains((string)i))) + .Select(x => x.FullPath) + .Select(TryGetChangedFile) + .Where(x => x != null) + .Select(x => (ChangedFile) x!) // in order to return non-null + .Do(f => Logger.LogInformation("Changed File: {ChangedFile}", f!.Path.Substring(WatchPath.Length))); ofsw.Start(); return ret; } - private ChangedFile TryGetChangedFile(string filePath) + private ChangedFile? TryGetChangedFile(string filePath) { try { @@ -123,7 +117,7 @@ private Task HandleWatchCommand(string cmd, string[] args) var inputPath = args[0]; var lastPath = LastChangedFile.Path; - var lastDirectory = Path.GetDirectoryName(lastPath); + var lastDirectory = Path.GetDirectoryName(lastPath)!; var targetPath = Path.Combine(lastDirectory, inputPath); var filesInPath = @@ -135,7 +129,8 @@ private Task HandleWatchCommand(string cmd, string[] args) inputPath, targetPath, filesInPath); foreach (var file in filesInPath) - _manualWatchFiles.OnNext(TryGetChangedFile(file)); + if (TryGetChangedFile(file) is {} cf) + _manualWatchFiles.OnNext(cf); return Task.CompletedTask; } diff --git a/src/components/tbc.host/Components/FileWatcher/Models/ChangedFile.cs b/src/components/tbc.host/Components/FileWatcher/Models/ChangedFile.cs index 4a8d695..30109d9 100644 --- a/src/components/tbc.host/Components/FileWatcher/Models/ChangedFile.cs +++ b/src/components/tbc.host/Components/FileWatcher/Models/ChangedFile.cs @@ -4,9 +4,9 @@ namespace Tbc.Host.Components.FileWatcher.Models { public class ChangedFile { - public string Path { get; set; } - internal string Contents { get; set; } - public DateTimeOffset ChangedAt { get; set; } + public required string Path { get; init; } + public required string Contents { get; init; } + public DateTimeOffset ChangedAt { get; init; } = DateTimeOffset.Now; public override string ToString() @@ -14,4 +14,4 @@ public override string ToString() return $"{Path} ({ChangedAt})"; } } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Components/GlobalUsingsResolver/GlobalUsingsResolver.cs b/src/components/tbc.host/Components/GlobalUsingsResolver/GlobalUsingsResolver.cs index 37ad277..1ae0374 100644 --- a/src/components/tbc.host/Components/GlobalUsingsResolver/GlobalUsingsResolver.cs +++ b/src/components/tbc.host/Components/GlobalUsingsResolver/GlobalUsingsResolver.cs @@ -21,7 +21,7 @@ public GlobalUsingsResolver(ILogger logger, IFileSystem fi _fileSystem = fileSystem; } - public async Task ResolveGlobalUsings(ResolveGlobalUsingsRequest request, CancellationToken canceller = default) + public Task ResolveGlobalUsings(ResolveGlobalUsingsRequest request, CancellationToken canceller = default) { var sources = request.Sources; var usings = ImmutableList.Create(); @@ -43,10 +43,10 @@ source.Kind switch usings = usings.Distinct().ToImmutableList(); - return new ResolveGlobalUsingsResponse( + return Task.FromResult(new ResolveGlobalUsingsResponse( sources, usings.Distinct().ToImmutableList(), usings.Any() ? String.Join(Environment.NewLine, usings) : null, - diagnostics); + diagnostics)); } public (List Usings, Dictionary Diagnostics) GetUsingsFromText(string text) @@ -61,7 +61,7 @@ source.Kind switch } public (List Usings, Dictionary Diagnostics) GetUsingsFromSearchPath( - string path, string maybeResolutionMethod) + string path, string? maybeResolutionMethod) { maybeResolutionMethod ??= KnownGlobalUsingSearchPathResolutionApproach.LastModified; diff --git a/src/components/tbc.host/Components/IncrementalCompiler/DeclarationSyntaxWalker.cs b/src/components/tbc.host/Components/IncrementalCompiler/DeclarationSyntaxWalker.cs index eb185f7..8cf831a 100644 --- a/src/components/tbc.host/Components/IncrementalCompiler/DeclarationSyntaxWalker.cs +++ b/src/components/tbc.host/Components/IncrementalCompiler/DeclarationSyntaxWalker.cs @@ -10,8 +10,8 @@ public class DeclarationSyntaxWalker : SyntaxWalker public override void Visit(SyntaxNode node) { - if (node is T) - Members.Add(node as T); + if (node is T syntaxNode) + Members.Add(syntaxNode); else base.Visit(node); } @@ -23,4 +23,4 @@ public List Visit(SyntaxTree tree) return Members; } } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Components/IncrementalCompiler/IIncrementalCompiler.cs b/src/components/tbc.host/Components/IncrementalCompiler/IIncrementalCompiler.cs index c941859..1186020 100644 --- a/src/components/tbc.host/Components/IncrementalCompiler/IIncrementalCompiler.cs +++ b/src/components/tbc.host/Components/IncrementalCompiler/IIncrementalCompiler.cs @@ -7,16 +7,15 @@ namespace Tbc.Host.Components.IncrementalCompiler { public interface IIncrementalCompiler { - string OutputPath { get; set; } - string RootPath { get; set; } List StagedFiles { get; } - EmittedAssembly StageFile(ChangedFile file) => StageFile(file, false); - EmittedAssembly StageFile(ChangedFile file, bool silent = false); + EmittedAssembly? StageFile(ChangedFile file) => StageFile(file, false); + EmittedAssembly? StageFile(ChangedFile file, bool silent = false); void AddMetadataReference(AssemblyReference asm); void ClearReferences(); void ClearTrees(); void PrintTrees(bool withDetail); - string TryResolvePrimaryType(string typeHint); + string? TryResolvePrimaryType(string typeHint); void DoWarmup(); + void SetRootPath(string rootPath); } } diff --git a/src/components/tbc.host/Components/IncrementalCompiler/IncrementalCompiler.cs b/src/components/tbc.host/Components/IncrementalCompiler/IncrementalCompiler.cs index 5803785..0d1eedc 100644 --- a/src/components/tbc.host/Components/IncrementalCompiler/IncrementalCompiler.cs +++ b/src/components/tbc.host/Components/IncrementalCompiler/IncrementalCompiler.cs @@ -16,7 +16,6 @@ using Tbc.Core.Models; using Tbc.Host.Components.Abstractions; using Tbc.Host.Components.CommandProcessor.Models; -using Tbc.Host.Components.FileEnvironment.Models; using Tbc.Host.Components.FileWatcher.Models; using Tbc.Host.Components.GlobalUsingsResolver; using Tbc.Host.Components.GlobalUsingsResolver.Models; @@ -24,7 +23,6 @@ using Tbc.Host.Components.IncrementalCompiler.Models; using Tbc.Host.Components.SourceGeneratorResolver; using Tbc.Host.Components.SourceGeneratorResolver.Models; -using Tbc.Host.Components.TargetClient; using Tbc.Host.Config; using Tbc.Host.Extensions; @@ -32,8 +30,11 @@ namespace Tbc.Host.Components.IncrementalCompiler { public class IncrementalCompiler : ComponentBase, IIncrementalCompiler, IDisposable, IExposeCommands { +#pragma warning disable CS0414 private bool _disposing; - +#pragma warning restore CS0414 + public string? _rootPath; + private readonly AssemblyCompilationOptions _options; private readonly IFileSystem _fileSystem; @@ -46,9 +47,6 @@ public class IncrementalCompiler : ComponentBase, IIncremen private readonly object _lock = new object(); private readonly string _identifier; - public string OutputPath { get; set; } - public string RootPath { get; set; } - public ImmutableDictionary SourceGeneratorResolution { get; set; } public (IEnumerable Srcs, IEnumerable Incs) SourceGenerators { get; set; } public bool AnySourceGenerators => SourceGenerators.Srcs.Any() || SourceGenerators.Incs.Any(); @@ -58,7 +56,6 @@ public class IncrementalCompiler : ComponentBase, IIncremen public CSharpCompilation CurrentCompilation { get; set; } public Dictionary RawTrees { get; } = new(); - public List StagedFiles => CurrentCompilation.SyntaxTrees.Select(x => x.FilePath).ToList(); @@ -119,7 +116,7 @@ IEnumerable fixers ImmutableDictionary.Create(), (curr, next) => curr.Add(next, _sourceGeneratorResolver.ResolveSourceGenerators(new(next)).Result)); - public EmittedAssembly StageFile(ChangedFile file, bool silent = false) + public EmittedAssembly? StageFile(ChangedFile file, bool silent = false) { var sw = Stopwatch.StartNew(); @@ -133,7 +130,7 @@ public EmittedAssembly StageFile(ChangedFile file, bool silent = false) path: file.Path, Encoding.Default); - EmittedAssembly emittedAssembly = null; + EmittedAssembly? emittedAssembly = null; WithCompilation(c => { @@ -193,10 +190,11 @@ public EmittedAssembly StageFile(ChangedFile file, bool silent = false) if (!result.Success && _options.FixerOptions.Enabled - && TryApplyCompilationFixers(result, compilation, out var fixedResult, out emittedAssembly)) + && TryApplyCompilationFixers(result, compilation, out var fixedResult, out emittedAssembly) + && fixedResult is { }) result = fixedResult; - if (!String.IsNullOrWhiteSpace(_options.WriteAssembliesPath)) + if (!String.IsNullOrWhiteSpace(_options.WriteAssembliesPath) && emittedAssembly is { }) WriteEmittedAssembly(emittedAssembly); var elapsed = sw.ElapsedMilliseconds; @@ -256,7 +254,12 @@ public void WriteEmittedAssembly(EmittedAssembly emittedAssembly) } public void AddMetadataReference(AssemblyReference asm) - => WithCompilation(c => c.AddReferences(MetadataReference.CreateFromImage(asm.PeBytes))); + { + if (asm.PeBytes is { } bytes) + WithCompilation(c => c.AddReferences(MetadataReference.CreateFromImage(bytes))); + else + Logger.LogWarning("Can't add reference {@AssemblyReference} that doesn't have assembly data", asm); + } private bool TryApplyCompilationFixers(EmitResult result, CSharpCompilation currentCompilation, out EmitResult? newResult, out EmittedAssembly? emittedAssembly) { @@ -367,14 +370,19 @@ private T WithCompilation(Func act }); public void PrintTrees(bool withDetail) - { - Logger.LogInformation(RootPath); + { + if (_rootPath is null) + { + Logger.LogError("Can't print trees with null rootpath"); + + return; + } var output = RawTrees .Select(rt => { var (fn, tree) = rt; - var relativePath = fn.Replace(RootPath, ""); + var relativePath = fn.Replace(_rootPath, ""); if (relativePath.StartsWith("/")) relativePath = relativePath.Substring(1); @@ -426,7 +434,7 @@ public void TryRemoveTree(string treeHint) }); } - public string TryResolvePrimaryType(string typeHint) + public string? TryResolvePrimaryType(string typeHint) { var candidates = RawTrees.Values @@ -444,17 +452,14 @@ public string TryResolvePrimaryType(string typeHint) return preferred; } - private string GetDescriptionForDiagnostic(SourceLocation Location, string Message) + private string GetDescriptionForDiagnostic(SourceLocation? Location, string Message) { try { - return $"{_fileSystem.Path.GetFileName(Location.SourceTree.FilePath)} " + - $"[{Location.GetLineSpan().StartLinePosition}]: {Message}"; - } - catch (Exception ex) - { - return Message; + return $"{_fileSystem.Path.GetFileName(Location?.SourceTree.FilePath)} " + + $"[{Location?.GetLineSpan().StartLinePosition}]: {Message}"; } + catch { return Message; } } public void Dispose() @@ -462,6 +467,9 @@ public void Dispose() _disposing = true; } + public void SetRootPath(string rootPath) + => _rootPath = rootPath; + string IExposeCommands.Identifier => $"inc-{_identifier}"; @@ -473,9 +481,9 @@ string IExposeCommands.Identifier Execute = (_, args) => { var detail = false; - if (args.Any() && bool.TryParse(args[0], out detail)) ; - - PrintTrees(detail); + if (args.Any() && bool.TryParse(args[0], out detail)) + PrintTrees(detail); + return Task.CompletedTask; } }, @@ -498,7 +506,7 @@ string IExposeCommands.Identifier break; default: - Logger.LogWarning("Don't know how to handle subcommand '{SubCommand}' of tree"); + Logger.LogWarning("Don't know how to handle subcommand '{SubCommand}' of tree", sub); break; } diff --git a/src/components/tbc.host/Components/IncrementalCompiler/Models/EmittedAssembly.cs b/src/components/tbc.host/Components/IncrementalCompiler/Models/EmittedAssembly.cs index 0a3971a..a4bc69d 100644 --- a/src/components/tbc.host/Components/IncrementalCompiler/Models/EmittedAssembly.cs +++ b/src/components/tbc.host/Components/IncrementalCompiler/Models/EmittedAssembly.cs @@ -1,12 +1,12 @@ namespace Tbc.Host.Components.IncrementalCompiler.Models { - public class EmittedAssembly + public record EmittedAssembly { - public string AssemblyName { get; set; } - public byte[] Pe { get; set; } - public byte[] Pd { get; set; } + public required string AssemblyName { get; init; } + public required byte[] Pe { get; init; } + public byte[]? Pd { get; init; } public bool HasDebugSymbols => - Pd != null && Pd.Length > 0; + Pd is { Length: > 0 }; } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Components/IncrementalCompiler/iOSDynamicRegistrationAttributeRewriter.cs b/src/components/tbc.host/Components/IncrementalCompiler/iOSDynamicRegistrationAttributeRewriter.cs index fabb924..91d03eb 100644 --- a/src/components/tbc.host/Components/IncrementalCompiler/iOSDynamicRegistrationAttributeRewriter.cs +++ b/src/components/tbc.host/Components/IncrementalCompiler/iOSDynamicRegistrationAttributeRewriter.cs @@ -24,12 +24,12 @@ public iOSDynamicRegistrationAttributeRewriter(MetadataLoadContext metadataLoadC public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) { var symbol = _semanticModel.GetDeclaredSymbolForNode(node); - if (symbol is null) return base.VisitClassDeclaration(node); + if (symbol is null) return base.VisitClassDeclaration(node)!; var symbolReference = $"{symbol.ContainingNamespace}.{symbol.MetadataName}"; var type = _metadataLoadContext.ResolveType(symbolReference); if (type is null) - return base.VisitClassDeclaration(node); + return base.VisitClassDeclaration(node)!; if (type.IsSubclassOf(_nsObject)) { @@ -51,6 +51,6 @@ public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) return updatedNode; } - return base.VisitClassDeclaration(node); + return base.VisitClassDeclaration(node)!; } } diff --git a/src/components/tbc.host/Components/SourceGeneratorResolver/SourceGeneratorResolver.cs b/src/components/tbc.host/Components/SourceGeneratorResolver/SourceGeneratorResolver.cs index c558d45..5bda615 100644 --- a/src/components/tbc.host/Components/SourceGeneratorResolver/SourceGeneratorResolver.cs +++ b/src/components/tbc.host/Components/SourceGeneratorResolver/SourceGeneratorResolver.cs @@ -29,7 +29,7 @@ public SourceGeneratorResolver(ILogger logger, IFileSys _fileSystem = fileSystem; } - public async Task ResolveSourceGenerators(ResolveSourceGeneratorsRequest request, + public Task ResolveSourceGenerators(ResolveSourceGeneratorsRequest request, CancellationToken canceller = default) { var (req, (kind, reference, context)) = (request.Reference, request.Reference); @@ -47,12 +47,27 @@ public SourceGeneratorResolver(ILogger logger, IFileSys srcs = srcs.GroupBy(x => x.GetType()).Select(x => x.First()).ToImmutableList(); incs = incs.GroupBy(x => x.GetType()).Select(x => x.First()).ToImmutableList(); - return new ResolveSourceGeneratorsResponse(req, srcs, incs, diags); + return Task.FromResult(new ResolveSourceGeneratorsResponse(req, srcs, incs, diags)); } private (ImmutableList Srcs, ImmutableList Incs, ImmutableDictionary Diags) - GetGeneratorsFromNugetPackageReference(string package, string version) + GetGeneratorsFromNugetPackageReference(string package, string? maybeVersion) { + var version = maybeVersion + ?? _fileSystem.Directory.GetDirectories(_fileSystem.Path.Combine(GetNugetPackageCachePath, package)) + .OrderByDescending(x => x) + .FirstOrDefault(); + + if (String.IsNullOrWhiteSpace(version)) + { + Logger.LogWarning("No version provided for source generator package {Package} and none could be inferred", + package); + + return (Srcs: ImmutableList.Create(), + Incs: ImmutableList.Create(), + Diags: ImmutableDictionary.Create()); + } + var nugetPath = _fileSystem.Path.Combine(GetNugetPackageCachePath, package, version); var dllPaths = _fileSystem.Directory.GetFiles(nugetPath, "*.dll", SearchOption.AllDirectories) .Where(x => x.Contains("roslyn4.0/cs", StringComparison.InvariantCultureIgnoreCase) || x.Contains("roslyn4.0\\cs", StringComparison.InvariantCultureIgnoreCase)); @@ -75,7 +90,7 @@ public SourceGeneratorResolver(ILogger logger, IFileSys { var diagnostics = ImmutableDictionary.Create(); - Assembly asm = null; + Assembly asm = null!; try { asm = Assembly.LoadFile(path); } catch (Exception ex) { @@ -114,8 +129,9 @@ public SourceGeneratorResolver(ILogger logger, IFileSys doc.DescendantNodes() .OfType() .Where(x => x.Name.LocalName == "PackageReference") - .Select(pr => new PackageReference(pr.Attribute("Include")?.Value, pr.Attribute("Version")?.Value)) + .Select(pr => new { Include = pr.Attribute("Include")?.Value, Version = pr.Attribute("Version")?.Value }) .Where(x => x.Include is not null && x.Version is not null) + .Select(pr => new PackageReference(pr.Include!, pr.Version!)) .ToList(); foreach (var packageReference in packageReferences) diff --git a/src/components/tbc.host/Components/TargetClient/SocketTargetClient.cs b/src/components/tbc.host/Components/TargetClient/SocketTargetClient.cs index 30d1e25..b6b8ade 100644 --- a/src/components/tbc.host/Components/TargetClient/SocketTargetClient.cs +++ b/src/components/tbc.host/Components/TargetClient/SocketTargetClient.cs @@ -22,13 +22,14 @@ public class SocketTargetClient : ComponentBase, ITargetClie { private readonly IFileSystem _fileSystem; - public TcpClient TcpClient { get; private set; } - public SocketServer Target { get; set; } + protected TcpClient? TcpClient { get; private set; } + protected SocketServer? Target { get; private set; } public SocketTargetClient(ILogger logger, IRemoteClientDefinition clientDefinition, IFileSystem fileSystem) : base(logger) { - ClientDefinition = clientDefinition; _fileSystem = fileSystem; + + ClientDefinition = clientDefinition; } public IRemoteClientDefinition ClientDefinition { get; } @@ -70,7 +71,7 @@ public async Task WaitForConnection() success = true; } - catch (Exception ex) + catch (Exception) // happens repeatedly when waiting for the other end to turn up, don't want to spam logs { _clientChannelState.OnNext(CanonicalChannelState.TransientFailure); @@ -83,28 +84,28 @@ public async Task WaitForConnection() } public Task Hello(HostHello hello) => - Target.SendRequest(hello); + Target!.SendRequest(hello); - public async Task> AssemblyReferences(List assemblyReferences) + public Task> AssemblyReferences(List assemblyReferences) { var cachedAssemblies = assemblyReferences.Select(x => new CachedAssembly(x)).ToList(); Task.Delay(TimeSpan.FromSeconds(.1)) - .ContinueWith(_ => Target.SendRequest(new CachedAssemblyState { CachedAssemblies = cachedAssemblies })); + .ContinueWith(_ => Target!.SendRequest(new CachedAssemblyState { CachedAssemblies = cachedAssemblies })); - return _incomingAssemblyReferences.ToAsyncEnumerable(); + return Task.FromResult(_incomingAssemblyReferences.ToAsyncEnumerable()); } - public async Task> CommandRequests() - => _incomingCommandRequests.ToAsyncEnumerable(); + public Task> CommandRequests() + => Task.FromResult(_incomingCommandRequests.ToAsyncEnumerable()); public Task RequestClientExecAsync(ExecuteCommandRequest req) - => Target.SendRequest(req); + => Target!.SendRequest(req); public async Task RequestClientLoadAssemblyAsync(LoadDynamicAssemblyRequest req) { var sw = Stopwatch.StartNew(); - var result = await Target.SendRequest(req); + var result = await Target!.SendRequest(req); Logger.LogInformation("Round trip for LoadAssembly with primary type {PrimaryTypeName}, {Duration}ms", req.PrimaryTypeName, sw.ElapsedMilliseconds); return result; } @@ -117,14 +118,14 @@ public async Task RequestClientLoadAssemblyAsync(LoadDynamicAssemblyReq || x == CanonicalChannelState.Idle) .ToTask(); - public async Task AddAssemblyReference(AssemblyReference reference) + public Task AddAssemblyReference(AssemblyReference reference) { _incomingAssemblyReferences.OnNext(reference); - return new Outcome { Success = true }; + return Task.FromResult(new Outcome { Success = true }); } - public async Task AddManyAssemblyReferences(ManyAssemblyReferences references) + public Task AddManyAssemblyReferences(ManyAssemblyReferences references) { var sw = Stopwatch.StartNew(); Logger.LogInformation("Begin loading {AssemblyCount} references", references.AssemblyReferences.Count); @@ -133,14 +134,15 @@ public async Task AddManyAssemblyReferences(ManyAssemblyReferences refe _incomingAssemblyReferences.OnNext(asm); Logger.LogInformation("{Elapsed:N0}ms to load {AssemblyCount} references", sw.ElapsedMilliseconds, references.AssemblyReferences.Count); - return new Outcome { Success = true }; + + return Task.FromResult(new Outcome { Success = true }); } - public async Task ExecuteCommand(ExecuteCommandRequest request) + public Task ExecuteCommand(ExecuteCommandRequest request) { _incomingCommandRequests.OnNext(request); - return new Outcome { Success = true }; + return Task.FromResult(new Outcome { Success = true }); } public Task Heartbeat(HeartbeatRequest request) diff --git a/src/components/tbc.host/Config/AssemblyCompilationOptions.cs b/src/components/tbc.host/Config/AssemblyCompilationOptions.cs index f863655..c274e85 100644 --- a/src/components/tbc.host/Config/AssemblyCompilationOptions.cs +++ b/src/components/tbc.host/Config/AssemblyCompilationOptions.cs @@ -13,7 +13,7 @@ public class AssemblyCompilationOptions public bool DisambiguateClassNames { get; set; } public List PreprocessorSymbols { get; set; } = new List(); - public string WriteAssembliesPath { get; set; } + public string? WriteAssembliesPath { get; set; } public List SourceGeneratorReferences { get; set; } = new(); public List GlobalUsingsSources { get; set; } = new(); public AssemblyFixerOptions FixerOptions { get; set; } = new() { Enabled = true }; diff --git a/src/components/tbc.host/Config/FileWatchConfig.cs b/src/components/tbc.host/Config/FileWatchConfig.cs index 82b0be6..dcc4f9d 100644 --- a/src/components/tbc.host/Config/FileWatchConfig.cs +++ b/src/components/tbc.host/Config/FileWatchConfig.cs @@ -4,8 +4,8 @@ namespace Tbc.Host.Config { public class FileWatchConfig { - public string RootPath { get; set; } + public required string RootPath { get; init; } public List Ignore { get; set; } = new List(); - public string FileMask { get; set; } + public string FileMask { get; set; } = "*.cs"; } -} \ No newline at end of file +} diff --git a/src/components/tbc.host/Extensions/HelpfulExtensions.cs b/src/components/tbc.host/Extensions/HelpfulExtensions.cs index 16762a5..5ede060 100644 --- a/src/components/tbc.host/Extensions/HelpfulExtensions.cs +++ b/src/components/tbc.host/Extensions/HelpfulExtensions.cs @@ -13,7 +13,7 @@ namespace Tbc.Host.Extensions { public static class HelpfulExtensions { - public static Task WhileTrue(Func @do) => + public static Task WhileTrue(Func @do) => Task.Run(async () => { while (true) @@ -21,7 +21,22 @@ public static class HelpfulExtensions try { await @do(); } catch (Exception ex) { Console.WriteLine(ex); } } + +#pragma warning disable CS0162 + return true; +#pragma warning restore CS0162 }); + + public static async Task If(Func @if, Func @true, Func @false) + { + var ret = @if(); + if (ret) + await @true(); + else + await @false(); + + return ret; + } public static JsonSerializerSettings NaiveCloneSerialiserSettings = new JsonSerializerSettings { @@ -29,15 +44,16 @@ public static class HelpfulExtensions }; public static T Clone(this T obj) - => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj, NaiveCloneSerialiserSettings), NaiveCloneSerialiserSettings); + where T: notnull + => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj, NaiveCloneSerialiserSettings), NaiveCloneSerialiserSettings)!; public static T CloneInto(this object obj) - => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj, NaiveCloneSerialiserSettings), NaiveCloneSerialiserSettings); + => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj, NaiveCloneSerialiserSettings), NaiveCloneSerialiserSettings)!; - public static T GetOrDefault(this Dictionary dict, U key) - => dict.TryGetValue(key, out var val) + public static T? GetOrDefault(this Dictionary dict, U key) + where U : notnull => dict.TryGetValue(key, out var val) ? val - : default(T); + : default; public static string ToJson(this object o, bool indented = true) => JsonConvert.SerializeObject(o, indented ? Formatting.Indented : Formatting.None); @@ -73,5 +89,24 @@ public static void LogAsync(this ILogger logger, LogLevel level, string message, public static IEnumerable DistinctBySelector(this IEnumerable items, Func selector) => items.GroupBy(selector).Select(x => x.First()); + +#pragma warning disable RECS0165 // Asynchronous methods should return a Task instead of void + public static async void FireAndForgetSafeAsync(this Task task, IErrorHandler? handler = null) +#pragma warning restore RECS0165 // Asynchronous methods should return a Task instead of void + { + try + { + await task; + } + catch (Exception ex) + { + handler?.HandleError(ex); + } + } + + public interface IErrorHandler + { + void HandleError(Exception ex); + } } } diff --git a/src/components/tbc.host/tbc.host.csproj b/src/components/tbc.host/tbc.host.csproj index eabd454..955e9a7 100644 --- a/src/components/tbc.host/tbc.host.csproj +++ b/src/components/tbc.host/tbc.host.csproj @@ -1,12 +1,13 @@ - netstandard2.1 + net7.0 Tbc.Host preview true true embedded + enable @@ -16,13 +17,13 @@ - + - + diff --git a/src/components/tbc.target/Implementation/AssemblyLoaderService.cs b/src/components/tbc.target/Implementation/AssemblyLoaderService.cs index 300ab2d..958cbbb 100644 --- a/src/components/tbc.target/Implementation/AssemblyLoaderService.cs +++ b/src/components/tbc.target/Implementation/AssemblyLoaderService.cs @@ -67,11 +67,7 @@ public async Task LoadAssembly(LoadDynamicAssemblyRequest request) ? asm.GetTypes().FirstOrDefault(x => x.Name.EndsWith(request.PrimaryTypeName)) : null; - var req = new ProcessNewAssemblyRequest - { - Assembly = asm, - PrimaryType = primaryType - }; + var req = new ProcessNewAssemblyRequest(asm, primaryType); return await _reloadManager.ProcessNewAssembly(req); } @@ -106,7 +102,7 @@ public async Task Exec(ExecuteCommandRequest request) } } - public async Task SynchronizeDependencies(CachedAssemblyState cachedAssemblyState) + public Task SynchronizeDependencies(CachedAssemblyState cachedAssemblyState) { _cachedAssemblyState = cachedAssemblyState.CachedAssemblies.GroupBy(x => x.AssemblyLocation) .ToDictionary(x => x.Key, x => x.ToList()); @@ -126,15 +122,15 @@ public async Task SynchronizeDependencies(CachedAssemblyState cachedAss => await WriteIfNecessary(args.LoadedAssembly); }); - return new Outcome { Success = true }; + return Task.FromResult(new Outcome { Success = true }); } - public async Task RequestCommand(CommandRequest req) - => await Remote.SendRequest(new ExecuteCommandRequest + public Task RequestCommand(CommandRequest req) + => Remote is {} r ? r.SendRequest(new ExecuteCommandRequest { Command = req.Command, Args = req.Args.ToList() - }); + }) : Task.CompletedTask; private readonly AsyncLock _mutex = new(); private Dictionary> _cachedAssemblyState = new(); @@ -167,7 +163,7 @@ private async Task WriteIfNecessary(Assembly asm) _log($"Will send {asm.FullName} - {sw.Elapsed}"); - await Remote.SendRequest(@ref); + await Remote!.SendRequest(@ref); _log($"Sent {asm.FullName} - {sw.Elapsed}"); _cachedAssemblyState[asm.Location] = new List { new(@ref) }; diff --git a/src/components/tbc.target/Interfaces/INotifyReplacement.cs b/src/components/tbc.target/Interfaces/INotifyReplacement.cs index 938236f..d8e1547 100644 --- a/src/components/tbc.target/Interfaces/INotifyReplacement.cs +++ b/src/components/tbc.target/Interfaces/INotifyReplacement.cs @@ -4,6 +4,6 @@ namespace Tbc.Target.Interfaces { public interface INotifyReplacement { - Action NotifyReplacement { get; set; } + Action? NotifyReplacement { get; set; } } -} \ No newline at end of file +} diff --git a/src/components/tbc.target/Interfaces/IRequestHostCommand.cs b/src/components/tbc.target/Interfaces/IRequestHostCommand.cs index 9c10f63..7b831eb 100644 --- a/src/components/tbc.target/Interfaces/IRequestHostCommand.cs +++ b/src/components/tbc.target/Interfaces/IRequestHostCommand.cs @@ -6,6 +6,6 @@ namespace Tbc.Target.Interfaces { public interface IRequestHostCommand { - Func RequestHostCommand { get; set; } + Func? RequestHostCommand { get; set; } } -} \ No newline at end of file +} diff --git a/src/components/tbc.target/ReloadManagerBase.cs b/src/components/tbc.target/ReloadManagerBase.cs index 5a31742..20293b6 100644 --- a/src/components/tbc.target/ReloadManagerBase.cs +++ b/src/components/tbc.target/ReloadManagerBase.cs @@ -11,16 +11,16 @@ public abstract class ReloadManagerBase : IReloadManager, INotifyReplacement, IR public abstract Task ProcessNewAssembly(ProcessNewAssemblyRequest req); public abstract Task ExecuteCommand(CommandRequest req); - private Func _requestHostCommand; - private Action _notifyReplacement; + private Func? _requestHostCommand; + private Action? _notifyReplacement; - Func IRequestHostCommand.RequestHostCommand + Func? IRequestHostCommand.RequestHostCommand { get => _requestHostCommand; set => _requestHostCommand = value; } - Action INotifyReplacement.NotifyReplacement + Action? INotifyReplacement.NotifyReplacement { get => _notifyReplacement; set => _notifyReplacement = value; diff --git a/src/components/tbc.target/Requests/CommandRequest.cs b/src/components/tbc.target/Requests/CommandRequest.cs index 7f85e20..4e80269 100644 --- a/src/components/tbc.target/Requests/CommandRequest.cs +++ b/src/components/tbc.target/Requests/CommandRequest.cs @@ -4,11 +4,6 @@ namespace Tbc.Target.Requests { public class CommandRequest { - public CommandRequest() - { - - } - public CommandRequest(string command, List args) { Command = command; @@ -16,8 +11,6 @@ public CommandRequest(string command, List args) } public string Command { get; set; } - public List Args { get; set; } - = new List(); } -} \ No newline at end of file +} diff --git a/src/components/tbc.target/Requests/HostCommandRequestedEventArgs.cs b/src/components/tbc.target/Requests/HostCommandRequestedEventArgs.cs index 2130330..0dbd940 100644 --- a/src/components/tbc.target/Requests/HostCommandRequestedEventArgs.cs +++ b/src/components/tbc.target/Requests/HostCommandRequestedEventArgs.cs @@ -4,6 +4,6 @@ namespace Tbc.Target.Requests { public class HostCommandRequestedEventArgs : EventArgs { - public CommandRequest Command { get; set; } + public CommandRequest Command { get; set; } = default!; } -} \ No newline at end of file +} diff --git a/src/components/tbc.target/Requests/ProcessNewAssemblyRequest.cs b/src/components/tbc.target/Requests/ProcessNewAssemblyRequest.cs index 8231fc2..11e18ad 100644 --- a/src/components/tbc.target/Requests/ProcessNewAssemblyRequest.cs +++ b/src/components/tbc.target/Requests/ProcessNewAssemblyRequest.cs @@ -3,9 +3,15 @@ namespace Tbc.Target.Requests { - public class ProcessNewAssemblyRequest + public record ProcessNewAssemblyRequest { + public ProcessNewAssemblyRequest(Assembly assembly, Type? primaryType) + { + Assembly = assembly; + PrimaryType = primaryType; + } + public Assembly Assembly { get; set; } - public Type PrimaryType { get; set; } + public Type? PrimaryType { get; set; } } -} \ No newline at end of file +} diff --git a/src/components/tbc.target/TargetServer.cs b/src/components/tbc.target/TargetServer.cs index 0a1a0ca..dde569c 100644 --- a/src/components/tbc.target/TargetServer.cs +++ b/src/components/tbc.target/TargetServer.cs @@ -24,7 +24,7 @@ public TargetServer(TargetConfiguration configuration) Configuration = configuration; } - public async Task Run(IReloadManager reloadManager, Action log = null) + public Task Run(IReloadManager reloadManager, Action? log = null) { log ??= Console.WriteLine; @@ -54,6 +54,8 @@ public async Task Run(IReloadManager reloadManager, Action log = null) { log($"socket loop faulted: {t.Exception}"); }); + + return Task.CompletedTask; } } } diff --git a/src/heads/tbc.host.console/tbc.host.console.csproj b/src/heads/tbc.host.console/tbc.host.console.csproj index b2e97fb..f66fac7 100644 --- a/src/heads/tbc.host.console/tbc.host.console.csproj +++ b/src/heads/tbc.host.console/tbc.host.console.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;net6.0 + net7.0