diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreContext.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreContext.cs index e5be2a2..c037564 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreContext.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreContext.cs @@ -30,7 +30,7 @@ public ExploreContext( _nodeHandlers = GetNodeHandlers(services); _ffiBuilder = new ExploreFfiBuilder(); _frontier = services.GetService()!; - _ignoredIncludeFiles = parseContext.ExtractOptions.IgnoredIncludeFiles.ToImmutableHashSet(); + _ignoredIncludeFiles = parseContext.ExtractInput.IgnoredIncludeFiles.ToImmutableHashSet(); } public CFfiTargetPlatform GetFfi() diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreFfiBuilder.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreFfiBuilder.cs index 080fbea..d715b22 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreFfiBuilder.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Context/ExploreFfiBuilder.cs @@ -41,7 +41,7 @@ public CFfiTargetPlatform GetFfi(ParseContext context) PlatformActual = context.TargetPlatformActual, ClangArguments = context.Arguments, SystemIncludeDirectories = context.SystemIncludeDirectories, - UserIncludeDirectories = context.ExtractOptions.UserIncludeDirectories, + UserIncludeDirectories = context.ExtractInput.UserIncludeDirectories, PointerSize = context.PointerSize, Variables = variables, Functions = functions, diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Explorer.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Explorer.cs index 26df316..af899bd 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Explorer.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/Explorer.cs @@ -33,10 +33,9 @@ public Explorer(ILogger logger, IServiceProvider services, ClangTransl public CFfiTargetPlatform ExtractFfi( string filePath, - ExtractTargetPlatformOptions options) + ExtractTargetPlatformInput input) { - using var context = CreateExploreContext(filePath, options); - using var _ = _logger.BeginScope(options.TargetPlatform)!; + using var context = CreateExploreContext(filePath, input); CFfiTargetPlatform result; try @@ -159,7 +158,7 @@ private void VisitInclude(ExploreContext context, clang.CXCursor clangCursor) var parseContext2 = _clangTranslationUnitParser.ParseTranslationUnit( filePath, - context.ParseContext.ExtractOptions, + context.ParseContext.ExtractInput, false, true); _parseContexts.Add(parseContext2); @@ -167,9 +166,9 @@ private void VisitInclude(ExploreContext context, clang.CXCursor clangCursor) VisitTranslationUnit(context, parseContext2); } - private ExploreContext CreateExploreContext(string filePath, ExtractTargetPlatformOptions options) + private ExploreContext CreateExploreContext(string filePath, ExtractTargetPlatformInput input) { - var parseContext = _clangTranslationUnitParser.ParseTranslationUnit(filePath, options); + var parseContext = _clangTranslationUnitParser.ParseTranslationUnit(filePath, input); var result = new ExploreContext(_services, parseContext); return result; } diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/FunctionExplorer.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/FunctionExplorer.cs index 3679fab..cd9426e 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/FunctionExplorer.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/FunctionExplorer.cs @@ -30,7 +30,7 @@ public sealed class FunctionExplorer(ILogger logger) protected override bool IsAllowed(ExploreContext context, ExploreNodeInfo info) { - var regexes = context.ParseContext.ExtractOptions.IgnoredFunctionRegexes; + var regexes = context.ParseContext.ExtractInput.IgnoredFunctionRegexes; foreach (var regex in regexes) { if (regex.IsMatch(info.Name)) diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/MacroObjectExplorer.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/MacroObjectExplorer.cs index 7e058c9..25b7778 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/MacroObjectExplorer.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/MacroObjectExplorer.cs @@ -40,7 +40,7 @@ public MacroObjectExplorer( protected override bool IsAllowed(ExploreContext context, ExploreNodeInfo info) { - var ignoredMacroObjectRegexes = context.ParseContext.ExtractOptions.IgnoredMacroObjectsRegexes; + var ignoredMacroObjectRegexes = context.ParseContext.ExtractInput.IgnoredMacroObjectsRegexes; foreach (var regex in ignoredMacroObjectRegexes) { if (regex.IsMatch(info.Name)) @@ -123,7 +123,7 @@ int main(void) { using var parseContext = _clangTranslationUnitParser.ParseTranslationUnit( filePath, - context.ParseContext.ExtractOptions, + context.ParseContext.ExtractInput, isCPlusPlus: true, ignoreWarnings: true, logClangDiagnostics: false, diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/VariableExplorer.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/VariableExplorer.cs index 9f2fe93..e25b9ff 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/VariableExplorer.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Explore/NodeExplorers/VariableExplorer.cs @@ -20,7 +20,7 @@ public sealed class VariableExplorer(ILogger logger) protected override bool IsAllowed(ExploreContext context, ExploreNodeInfo info) { - var regexes = context.ParseContext.ExtractOptions.IgnoredVariableRegexes; + var regexes = context.ParseContext.ExtractInput.IgnoredVariableRegexes; foreach (var regex in regexes) { if (regex.IsMatch(info.Name)) diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ClangTranslationUnitParser.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ClangTranslationUnitParser.cs index 8d223a0..ebf5a09 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ClangTranslationUnitParser.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ClangTranslationUnitParser.cs @@ -29,7 +29,7 @@ public ClangTranslationUnitParser( public ParseContext ParseTranslationUnit( string filePath, - ExtractTargetPlatformOptions extractOptions, + ExtractTargetPlatformInput extractInput, bool isCPlusPlus = false, bool ignoreWarnings = false, bool logClangDiagnostics = false, @@ -37,9 +37,9 @@ public ParseContext ParseTranslationUnit( bool skipFunctionBodies = true) { var systemIncludeDirectories = _systemIncludeDirectoriesProvider.GetSystemIncludeDirectories( - extractOptions.TargetPlatform, extractOptions.SystemIncludeDirectories, extractOptions.IsEnabledFindSystemHeaders); + extractInput.TargetPlatform, extractInput.SystemIncludeDirectories, extractInput.IsEnabledFindSystemHeaders); var arguments = _argumentsProvider.GetArguments( - extractOptions, systemIncludeDirectories, isCPlusPlus, ignoreWarnings); + extractInput, systemIncludeDirectories, isCPlusPlus, ignoreWarnings); var argumentsString = string.Join(" ", arguments); if (!TryParseTranslationUnit(filePath, arguments, out var translationUnit, skipFunctionBodies, keepGoing)) @@ -57,7 +57,7 @@ public ParseContext ParseTranslationUnit( var result = new ParseContext( translationUnit, filePath, - extractOptions, + extractInput, arguments, systemIncludeDirectories); return result; diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseArgumentsProvider.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseArgumentsProvider.cs index f5c0636..303db0e 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseArgumentsProvider.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseArgumentsProvider.cs @@ -11,18 +11,18 @@ namespace c2ffi.Tool.Commands.Extract.Domain.Parse; public sealed class ParseArgumentsProvider { public ImmutableArray GetArguments( - ExtractTargetPlatformOptions options, + ExtractTargetPlatformInput input, ImmutableArray systemIncludeDirectories, bool isCPlusPlus, bool ignoreWarnings) { var args = ImmutableArray.CreateBuilder(); - AddDefaults(args, options.TargetPlatform, isCPlusPlus, ignoreWarnings); - AddUserIncludeDirectories(args, options.UserIncludeDirectories); - AddDefines(args, options.MacroObjectDefines); - AddTargetTriple(args, options.TargetPlatform); - AddAdditionalArgs(args, options.AdditionalArguments); + AddDefaults(args, input.TargetPlatform, isCPlusPlus, ignoreWarnings); + AddUserIncludeDirectories(args, input.UserIncludeDirectories); + AddDefines(args, input.MacroObjectDefines); + AddTargetTriple(args, input.TargetPlatform); + AddAdditionalArgs(args, input.AdditionalArguments); AddSystemIncludeDirectories(args, systemIncludeDirectories); return args.ToImmutable(); diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseContext.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseContext.cs index babcb9e..a245aa7 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseContext.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Domain/Parse/ParseContext.cs @@ -12,7 +12,7 @@ namespace c2ffi.Tool.Commands.Extract.Domain.Parse; public sealed class ParseContext : IDisposable { public readonly string FilePath; - public readonly ExtractTargetPlatformOptions ExtractOptions; + public readonly ExtractTargetPlatformInput ExtractInput; public readonly ImmutableArray Arguments; public readonly ImmutableArray SystemIncludeDirectories; public readonly TargetPlatform TargetPlatformRequested; @@ -26,17 +26,17 @@ public sealed class ParseContext : IDisposable public ParseContext( clang.CXTranslationUnit translationUnit, string filePath, - ExtractTargetPlatformOptions extractOptions, + ExtractTargetPlatformInput extractInput, ImmutableArray arguments, ImmutableArray systemIncludeDirectories) { _translationUnit = translationUnit; FilePath = filePath; - ExtractOptions = extractOptions; + ExtractInput = extractInput; Arguments = arguments; SystemIncludeDirectories = systemIncludeDirectories; - TargetPlatformRequested = extractOptions.TargetPlatform; + TargetPlatformRequested = extractInput.TargetPlatform; var targetInfo = GetTargetInfo(translationUnit); TargetPlatformActual = targetInfo.TargetPlatform; diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/ExtractFfiTool.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/ExtractFfiTool.cs index 4a6a5c0..badd2a1 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/ExtractFfiTool.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/ExtractFfiTool.cs @@ -1,125 +1,67 @@ // Copyright (c) Bottlenose Labs Inc. (https://github.com/bottlenoselabs). All rights reserved. // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information. -using System.Collections.Immutable; using System.IO.Abstractions; -using c2ffi.Data; +using bottlenoselabs.Common.Tools; using c2ffi.Data.Serialization; using c2ffi.Tool.Commands.Extract.Domain.Explore; +using c2ffi.Tool.Commands.Extract.Domain.Parse; using c2ffi.Tool.Commands.Extract.Input; using c2ffi.Tool.Commands.Extract.Input.Sanitized; +using c2ffi.Tool.Commands.Extract.Input.Unsanitized; +using c2ffi.Tool.Commands.Extract.Output; using Microsoft.Extensions.Logging; -using ClangInstaller = c2ffi.Tool.Commands.Extract.Domain.Parse.ClangInstaller; -using ExtractOptions = c2ffi.Tool.Commands.Extract.Input.ExtractOptions; namespace c2ffi.Tool.Commands.Extract; -public sealed partial class ExtractFfiTool +public sealed class ExtractFfiTool : Tool { - private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; - private readonly ExtractInputSanitizer _inputSanitizer; private readonly ClangInstaller _clangInstaller; private readonly Explorer _explorer; + private string? _clangFilePath; + public ExtractFfiTool( ILogger logger, IFileSystem fileSystem, ExtractInputSanitizer inputSanitizer, ClangInstaller clangInstaller, Explorer explorer) + : base(logger, inputSanitizer, fileSystem) { - _logger = logger; _fileSystem = fileSystem; - _inputSanitizer = inputSanitizer; _clangInstaller = clangInstaller; _explorer = explorer; } public void Run(string configurationFilePath, string? clangFilePath = null) { - if (!TryInstallClang(clangFilePath)) - { - return; - } - - var options = GetOptions(configurationFilePath); - var targetPlatforms = ExtractFfis(options); - if (targetPlatforms.IsDefaultOrEmpty) - { - LogFailure(); - } - else - { - LogSuccess(targetPlatforms); - } + _clangFilePath = clangFilePath; + base.Run(configurationFilePath); } - private bool TryInstallClang(string? clangFilePath = null) + protected override void Execute(ExtractInput input, ExtractOutput output) { - return _clangInstaller.TryInstall(clangFilePath); - } + BeginStep("Install libclang"); + var libClangIsInstalled = _clangInstaller.TryInstall(_clangFilePath); + EndStep(); - private ExtractOptions GetOptions(string configurationFilePath) - { - return _inputSanitizer.SanitizeFromFile(configurationFilePath); - } - - private ImmutableArray ExtractFfis(ExtractOptions options) - { - var builder = ImmutableArray.CreateBuilder(); - - foreach (var targetPlatformOptions in options.TargetPlatformsOptions) + if (!libClangIsInstalled) { - var targetPlatform = ExtractFfi(options, targetPlatformOptions); - if (targetPlatform != null) - { - builder.Add(targetPlatform.Value); - } + return; } - return builder.ToImmutable(); - } - - private TargetPlatform? ExtractFfi( - ExtractOptions options, - ExtractTargetPlatformOptions targetPlatformOptions) - { - try + foreach (var targetPlatformInput in input.TargetPlatformInputs) { + BeginStep($"Extracting FFI {targetPlatformInput.TargetPlatform}"); + var ffi = _explorer.ExtractFfi( - options.InputFilePath, - targetPlatformOptions); - Json.WriteFfiTargetPlatform(_fileSystem, targetPlatformOptions.OutputFilePath, ffi); - } -#pragma warning disable CA1031 - catch (Exception e) -#pragma warning restore CA1031 - { - LogWriteFfiTargetPlatformFailure(e, targetPlatformOptions.TargetPlatform, targetPlatformOptions.OutputFilePath); - return null; - } + input.InputFilePath, + targetPlatformInput); + Json.WriteFfiTargetPlatform(_fileSystem, targetPlatformInput.OutputFilePath, ffi); - LogWriteFfiTargetPlatformSuccess(targetPlatformOptions.TargetPlatform, targetPlatformOptions.OutputFilePath); - return targetPlatformOptions.TargetPlatform; + EndStep(); + } } - - [LoggerMessage(0, LogLevel.Information, "Success. Extracted FFI for the target platform '{TargetPlatform}': {FilePath}")] - private partial void LogWriteFfiTargetPlatformSuccess( - TargetPlatform targetPlatform, - string filePath); - - [LoggerMessage(1, LogLevel.Error, "Failed to extract FFI for the target platform '{TargetPlatform}': {FilePath}")] - private partial void LogWriteFfiTargetPlatformFailure( - Exception exception, - TargetPlatform targetPlatform, - string filePath); - - [LoggerMessage(2, LogLevel.Information, "Success. Extracted FFIs for the target platforms '{TargetPlatforms}'.")] - private partial void LogSuccess( - ImmutableArray targetPlatforms); - - [LoggerMessage(3, LogLevel.Error, "Failure.")] - private partial void LogFailure(); } diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/ExtractInputSanitizer.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/ExtractInputSanitizer.cs index 8613631..7354e5f 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/ExtractInputSanitizer.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/ExtractInputSanitizer.cs @@ -12,7 +12,7 @@ namespace c2ffi.Tool.Commands.Extract.Input; -public sealed class ExtractInputSanitizer : InputSanitizer +public sealed class ExtractInputSanitizer : InputSanitizer { private readonly string _hostOperatingSystemString; @@ -22,16 +22,16 @@ public ExtractInputSanitizer(IFileSystem fileSystem) _hostOperatingSystemString = Native.OperatingSystem.ToString().ToUpperInvariant(); } - protected override ExtractOptions Sanitize(UnsanitizedExtractInput unsanitizedInput) + public override ExtractInput Sanitize(UnsanitizedExtractInput unsanitizedInput) { unsanitizedInput.TargetPlatforms ??= CreateDefaultTargetPlatformsUnsanitizedInput(); var inputFilePath = SanitizeCInputFilePath(unsanitizedInput.InputFilePath); var targetPlatformsOptions = SanitizeTargetPlatformsOptions(unsanitizedInput, inputFilePath); - var result = new ExtractOptions + var result = new ExtractInput { InputFilePath = inputFilePath, - TargetPlatformsOptions = targetPlatformsOptions + TargetPlatformInputs = targetPlatformsOptions }; return result; @@ -71,11 +71,11 @@ private string SanitizeCInputFilePath(string? inputFilePath) return filePath; } - private ImmutableArray SanitizeTargetPlatformsOptions( + private ImmutableArray SanitizeTargetPlatformsOptions( UnsanitizedExtractInput unsanitizedInput, string inputFilePath) { - var builder = ImmutableArray.CreateBuilder(); + var builder = ImmutableArray.CreateBuilder(); var isAtLeastOneMatchingOperatingSystem = false; var targetPlatformsUnsanitizedInputByOperatingSystem = unsanitizedInput.TargetPlatforms; @@ -109,14 +109,14 @@ private ImmutableArray SanitizeTargetPlatformsOpti return builder.ToImmutable(); } - private ExtractTargetPlatformOptions SanitizeTargetPlatformInput( + private ExtractTargetPlatformInput SanitizeTargetPlatformInput( UnsanitizedExtractInput input, string targetPlatformString, UnsanitizedExtractInputTargetPlatform targetPlatformInput, string inputFilePath) { var targetPlatform = new TargetPlatform(targetPlatformString); - var options = new ExtractTargetPlatformOptions + var options = new ExtractTargetPlatformInput { TargetPlatform = targetPlatform, OutputFilePath = OutputFilePath(input, targetPlatformString), diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/ExtractOptions.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/ExtractOptions.cs deleted file mode 100644 index 2c075da..0000000 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/ExtractOptions.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Bottlenose Labs Inc. (https://github.com/bottlenoselabs). All rights reserved. -// Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information. - -using System.Collections.Immutable; -using c2ffi.Tool.Commands.Extract.Input.Sanitized; - -namespace c2ffi.Tool.Commands.Extract.Input; - -public sealed class ExtractOptions -{ - public string InputFilePath { get; init; } = string.Empty; - - public ImmutableArray TargetPlatformsOptions { get; init; } -} diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractOptions.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractInput.cs similarity index 74% rename from src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractOptions.cs rename to src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractInput.cs index 8b965b7..92c8365 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractOptions.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractInput.cs @@ -5,9 +5,9 @@ namespace c2ffi.Tool.Commands.Extract.Input.Sanitized; -public sealed class ExtractOptions +public sealed class ExtractInput { public string InputFilePath { get; init; } = string.Empty; - public ImmutableArray TargetPlatformOptions { get; init; } + public ImmutableArray TargetPlatformInputs { get; init; } } diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractTargetPlatformOptions.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractTargetPlatformInput.cs similarity index 96% rename from src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractTargetPlatformOptions.cs rename to src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractTargetPlatformInput.cs index b3dbb4e..9a52d88 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractTargetPlatformOptions.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Sanitized/ExtractTargetPlatformInput.cs @@ -7,7 +7,7 @@ namespace c2ffi.Tool.Commands.Extract.Input.Sanitized; -public sealed class ExtractTargetPlatformOptions +public sealed class ExtractTargetPlatformInput { public string OutputFilePath { get; init; } = string.Empty; diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Unsanitized/UnsanitizedExtractInput.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Unsanitized/UnsanitizedExtractInput.cs index 3aab4ed..da86686 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Unsanitized/UnsanitizedExtractInput.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Input/Unsanitized/UnsanitizedExtractInput.cs @@ -3,13 +3,14 @@ using System.Collections.Immutable; using System.Text.Json.Serialization; +using bottlenoselabs.Common.Tools; using JetBrains.Annotations; namespace c2ffi.Tool.Commands.Extract.Input.Unsanitized; // NOTE: This class is considered un-sanitized input; all strings and other types could be null. [PublicAPI] -public sealed class UnsanitizedExtractInput +public sealed class UnsanitizedExtractInput : ToolUnsanitizedInput { /// /// Gets or sets the path of the output FFI directory. diff --git a/src/cs/production/c2ffi.Tool/Commands/Extract/Output/ExtractOutput.cs b/src/cs/production/c2ffi.Tool/Commands/Extract/Output/ExtractOutput.cs new file mode 100644 index 0000000..4541b9b --- /dev/null +++ b/src/cs/production/c2ffi.Tool/Commands/Extract/Output/ExtractOutput.cs @@ -0,0 +1,14 @@ +// Copyright (c) Bottlenose Labs Inc. (https://github.com/bottlenoselabs). All rights reserved. +// Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information. + +using bottlenoselabs.Common.Tools; +using c2ffi.Tool.Commands.Extract.Input.Sanitized; + +namespace c2ffi.Tool.Commands.Extract.Output; + +public class ExtractOutput : ToolOutput +{ + protected override void OnComplete() + { + } +} diff --git a/src/cs/production/c2ffi.Tool/Commands/Merge/Input/MergeInputSanitizer.cs b/src/cs/production/c2ffi.Tool/Commands/Merge/Input/MergeInputSanitizer.cs index f05f0a3..6693b78 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Merge/Input/MergeInputSanitizer.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Merge/Input/MergeInputSanitizer.cs @@ -9,7 +9,7 @@ namespace c2ffi.Tool.Commands.Merge.Input; -public sealed class MergeInputSanitizer +public sealed class MergeInputSanitizer : ToolInputSanitizer { private readonly IFileSystem _fileSystem; @@ -18,9 +18,9 @@ public MergeInputSanitizer(IFileSystem fileSystem) _fileSystem = fileSystem; } - public MergeOptions Sanitize(UnsanitizedMergeOptions unsanitizedOptions) + public override MergeInput Sanitize(UnsanitizedMergeInput unsanitizedInput) { - var directoryPath = _fileSystem.Path.GetFullPath(unsanitizedOptions.InputDirectoryPath); + var directoryPath = _fileSystem.Path.GetFullPath(unsanitizedInput.InputDirectoryPath); if (!_fileSystem.Directory.Exists(directoryPath)) { throw new ToolInputSanitizationException($"The directory '{directoryPath}' does not exist."); @@ -33,9 +33,9 @@ public MergeOptions Sanitize(UnsanitizedMergeOptions unsanitizedOptions) throw new ToolInputSanitizationException($"The directory '{directoryPath}' does not contain any abstract syntax tree `.json` files."); } - var outputFilePath = _fileSystem.Path.GetFullPath(unsanitizedOptions.OutputFilePath); + var outputFilePath = _fileSystem.Path.GetFullPath(unsanitizedInput.OutputFilePath); - var result = new MergeOptions + var result = new MergeInput { OutputFilePath = outputFilePath, InputFilePaths = filePaths diff --git a/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Sanitized/MergeOptions.cs b/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Sanitized/MergeInput.cs similarity index 94% rename from src/cs/production/c2ffi.Tool/Commands/Merge/Input/Sanitized/MergeOptions.cs rename to src/cs/production/c2ffi.Tool/Commands/Merge/Input/Sanitized/MergeInput.cs index 304c73c..b736891 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Sanitized/MergeOptions.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Sanitized/MergeInput.cs @@ -5,7 +5,7 @@ namespace c2ffi.Tool.Commands.Merge.Input.Sanitized; -public class MergeOptions +public class MergeInput { public ImmutableArray InputFilePaths { get; set; } = ImmutableArray.Empty; diff --git a/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Unsanitized/UnsanitizedMergeOptions.cs b/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Unsanitized/UnsanitizedMergeInput.cs similarity index 84% rename from src/cs/production/c2ffi.Tool/Commands/Merge/Input/Unsanitized/UnsanitizedMergeOptions.cs rename to src/cs/production/c2ffi.Tool/Commands/Merge/Input/Unsanitized/UnsanitizedMergeInput.cs index 1a80806..8f31d85 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Unsanitized/UnsanitizedMergeOptions.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Merge/Input/Unsanitized/UnsanitizedMergeInput.cs @@ -1,10 +1,12 @@ // Copyright (c) Bottlenose Labs Inc. (https://github.com/bottlenoselabs). All rights reserved. // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information. +using bottlenoselabs.Common.Tools; + namespace c2ffi.Tool.Commands.Merge.Input.Unsanitized; // NOTE: This class is considered un-sanitized input; all strings and other types could be null. -public class UnsanitizedMergeOptions +public class UnsanitizedMergeInput : ToolUnsanitizedInput { public string InputDirectoryPath { get; set; } = string.Empty; diff --git a/src/cs/production/c2ffi.Tool/Commands/Merge/MergeFfisTool.cs b/src/cs/production/c2ffi.Tool/Commands/Merge/MergeFfisTool.cs index d4d3044..5f7246b 100644 --- a/src/cs/production/c2ffi.Tool/Commands/Merge/MergeFfisTool.cs +++ b/src/cs/production/c2ffi.Tool/Commands/Merge/MergeFfisTool.cs @@ -3,21 +3,22 @@ using System.Collections.Immutable; using System.IO.Abstractions; +using bottlenoselabs.Common.Tools; using c2ffi.Data; using c2ffi.Data.Nodes; using c2ffi.Data.Serialization; using c2ffi.Tool.Commands.Merge.Input; using c2ffi.Tool.Commands.Merge.Input.Sanitized; using c2ffi.Tool.Commands.Merge.Input.Unsanitized; +using c2ffi.Tool.Commands.Merge.Output; using Microsoft.Extensions.Logging; namespace c2ffi.Tool.Commands.Merge; -public sealed partial class MergeFfisTool +public sealed partial class MergeFfisTool : Tool { private readonly ILogger _logger; private readonly IFileSystem _fileSystem; - private readonly MergeInputSanitizer _mergeInputSanitizer; private readonly List _enums = new(); private readonly List _variables = new(); @@ -44,34 +45,34 @@ public MergeFfisTool( ILogger logger, IFileSystem fileSystem, MergeInputSanitizer mergeInputSanitizer) + : base(logger, mergeInputSanitizer, fileSystem) { _logger = logger; _fileSystem = fileSystem; - _mergeInputSanitizer = mergeInputSanitizer; } public void Run(string inputDirectoryPath, string outputFilePath) { - var options = GetOptions(inputDirectoryPath, outputFilePath); + var unsanitizedOptions = new UnsanitizedMergeInput + { + InputDirectoryPath = inputDirectoryPath, + OutputFilePath = outputFilePath + }; + + Run(unsanitizedOptions); + } + + protected override void Execute(MergeInput input, MergeOutput output) + { var platformFfis = - GetPlatformFfis(options.InputFilePaths); + GetPlatformFfis(input.InputFilePaths); var platforms = platformFfis. Select(x => x.PlatformRequested).ToImmutableArray(); var platformNodesByKey = GetPlatformNodesByKey(platformFfis); var ffi = CreateCrossPlatformFfi(platforms, platformNodesByKey); - Json.WriteFfiCrossPlatform(_fileSystem, options.OutputFilePath, ffi); - LogWriteAbstractSyntaxTreeSuccess(string.Join(", ", platforms), options.OutputFilePath); - } - - private MergeOptions GetOptions(string inputDirectoryPath, string outputFilePath) - { - var unsanitizedOptions = new UnsanitizedMergeOptions - { - InputDirectoryPath = inputDirectoryPath, - OutputFilePath = outputFilePath - }; - return _mergeInputSanitizer.Sanitize(unsanitizedOptions); + Json.WriteFfiCrossPlatform(_fileSystem, input.OutputFilePath, ffi); + LogWriteAbstractSyntaxTreeSuccess(string.Join(", ", platforms), input.OutputFilePath); } private CFfiCrossPlatform CreateCrossPlatformFfi( diff --git a/src/cs/production/c2ffi.Tool/Commands/Merge/Output/MergeOutput.cs b/src/cs/production/c2ffi.Tool/Commands/Merge/Output/MergeOutput.cs new file mode 100644 index 0000000..b45bc63 --- /dev/null +++ b/src/cs/production/c2ffi.Tool/Commands/Merge/Output/MergeOutput.cs @@ -0,0 +1,14 @@ +// Copyright (c) Bottlenose Labs Inc. (https://github.com/bottlenoselabs). All rights reserved. +// Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information. + +using bottlenoselabs.Common.Tools; +using c2ffi.Tool.Commands.Merge.Input.Sanitized; + +namespace c2ffi.Tool.Commands.Merge.Output; + +public class MergeOutput : ToolOutput +{ + protected override void OnComplete() + { + } +} diff --git a/src/cs/production/c2ffi.Tool/Generated/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs b/src/cs/production/c2ffi.Tool/Generated/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs index eeee4de..b99350a 100644 --- a/src/cs/production/c2ffi.Tool/Generated/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs +++ b/src/cs/production/c2ffi.Tool/Generated/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs @@ -361,60 +361,6 @@ private partial void LogMissingSystemIncludeDirectory(global::System.String dire } } } -namespace c2ffi.Tool.Commands.Extract -{ - partial class ExtractFfiTool - { - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private static readonly global::System.Action __LogWriteFfiTargetPlatformSuccessCallback = - global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Information, new global::Microsoft.Extensions.Logging.EventId(0, nameof(LogWriteFfiTargetPlatformSuccess)), "Success. Extracted FFI for the target platform '{TargetPlatform}': {FilePath}", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private partial void LogWriteFfiTargetPlatformSuccess(global::c2ffi.Data.TargetPlatform targetPlatform, global::System.String filePath) - { - if (_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Information)) - { - __LogWriteFfiTargetPlatformSuccessCallback(_logger, targetPlatform, filePath, null); - } - } - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private static readonly global::System.Action __LogWriteFfiTargetPlatformFailureCallback = - global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Error, new global::Microsoft.Extensions.Logging.EventId(1, nameof(LogWriteFfiTargetPlatformFailure)), "Failed to extract FFI for the target platform '{TargetPlatform}': {FilePath}", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private partial void LogWriteFfiTargetPlatformFailure(global::System.Exception exception, global::c2ffi.Data.TargetPlatform targetPlatform, global::System.String filePath) - { - if (_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Error)) - { - __LogWriteFfiTargetPlatformFailureCallback(_logger, targetPlatform, filePath, exception); - } - } - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private static readonly global::System.Action, global::System.Exception?> __LogSuccessCallback = - global::Microsoft.Extensions.Logging.LoggerMessage.Define>(global::Microsoft.Extensions.Logging.LogLevel.Information, new global::Microsoft.Extensions.Logging.EventId(2, nameof(LogSuccess)), "Success. Extracted FFIs for the target platforms '{TargetPlatforms}'.", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private partial void LogSuccess(global::System.Collections.Immutable.ImmutableArray targetPlatforms) - { - if (_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Information)) - { - __LogSuccessCallback(_logger, targetPlatforms, null); - } - } - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private static readonly global::System.Action __LogFailureCallback = - global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Error, new global::Microsoft.Extensions.Logging.EventId(3, nameof(LogFailure)), "Failure.", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "8.0.9.3103")] - private partial void LogFailure() - { - if (_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Error)) - { - __LogFailureCallback(_logger, null); - } - } - } -} namespace c2ffi.Tool.Commands.Merge { partial class MergeFfisTool diff --git a/src/cs/production/c2ffi.Tool/Internal/Input/InputSanitizer.cs b/src/cs/production/c2ffi.Tool/Internal/Input/InputSanitizer.cs index 712d36e..16acb1a 100644 --- a/src/cs/production/c2ffi.Tool/Internal/Input/InputSanitizer.cs +++ b/src/cs/production/c2ffi.Tool/Internal/Input/InputSanitizer.cs @@ -5,10 +5,11 @@ using System.IO.Abstractions; using System.Text.Json; using System.Text.RegularExpressions; +using bottlenoselabs.Common.Tools; namespace c2ffi.Tool.Internal.Input; -public abstract class InputSanitizer +public abstract class InputSanitizer : ToolInputSanitizer where TUnsanitizedInput : class where TSanitizedInput : class { @@ -59,8 +60,6 @@ public TSanitizedInput SanitizeFromFile(string filePath) return result; } - protected abstract TSanitizedInput Sanitize(TUnsanitizedInput unsanitizedInput); - protected ImmutableArray SanitizeStrings(ImmutableArray? strings) { if (strings == null || strings.Value.IsDefaultOrEmpty) diff --git a/src/cs/production/c2ffi.Tool/c2ffi.Tool.csproj b/src/cs/production/c2ffi.Tool/c2ffi.Tool.csproj index dffc5da..d2a29ed 100644 --- a/src/cs/production/c2ffi.Tool/c2ffi.Tool.csproj +++ b/src/cs/production/c2ffi.Tool/c2ffi.Tool.csproj @@ -38,7 +38,7 @@ - +