Skip to content

Commit

Permalink
Use common Tool abstraction (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
lithiumtoast authored Apr 11, 2024
1 parent 80b12fc commit d520a26
Show file tree
Hide file tree
Showing 24 changed files with 120 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ExploreContext(
_nodeHandlers = GetNodeHandlers(services);
_ffiBuilder = new ExploreFfiBuilder();
_frontier = services.GetService<ExploreFrontier>()!;
_ignoredIncludeFiles = parseContext.ExtractOptions.IgnoredIncludeFiles.ToImmutableHashSet();
_ignoredIncludeFiles = parseContext.ExtractInput.IgnoredIncludeFiles.ToImmutableHashSet();
}

public CFfiTargetPlatform GetFfi()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ public Explorer(ILogger<Explorer> 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
Expand Down Expand Up @@ -159,17 +158,17 @@ private void VisitInclude(ExploreContext context, clang.CXCursor clangCursor)

var parseContext2 = _clangTranslationUnitParser.ParseTranslationUnit(
filePath,
context.ParseContext.ExtractOptions,
context.ParseContext.ExtractInput,
false,
true);
_parseContexts.Add(parseContext2);

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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public sealed class FunctionExplorer(ILogger<FunctionExplorer> 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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public sealed class VariableExplorer(ILogger<VariableExplorer> 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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ public ClangTranslationUnitParser(

public ParseContext ParseTranslationUnit(
string filePath,
ExtractTargetPlatformOptions extractOptions,
ExtractTargetPlatformInput extractInput,
bool isCPlusPlus = false,
bool ignoreWarnings = false,
bool logClangDiagnostics = false,
bool keepGoing = false,
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))
Expand All @@ -57,7 +57,7 @@ public ParseContext ParseTranslationUnit(
var result = new ParseContext(
translationUnit,
filePath,
extractOptions,
extractInput,
arguments,
systemIncludeDirectories);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ namespace c2ffi.Tool.Commands.Extract.Domain.Parse;
public sealed class ParseArgumentsProvider
{
public ImmutableArray<string> GetArguments(
ExtractTargetPlatformOptions options,
ExtractTargetPlatformInput input,
ImmutableArray<string> systemIncludeDirectories,
bool isCPlusPlus,
bool ignoreWarnings)
{
var args = ImmutableArray.CreateBuilder<string>();

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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> Arguments;
public readonly ImmutableArray<string> SystemIncludeDirectories;
public readonly TargetPlatform TargetPlatformRequested;
Expand All @@ -26,17 +26,17 @@ public sealed class ParseContext : IDisposable
public ParseContext(
clang.CXTranslationUnit translationUnit,
string filePath,
ExtractTargetPlatformOptions extractOptions,
ExtractTargetPlatformInput extractInput,
ImmutableArray<string> arguments,
ImmutableArray<string> 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;
Expand Down
106 changes: 24 additions & 82 deletions src/cs/production/c2ffi.Tool/Commands/Extract/ExtractFfiTool.cs
Original file line number Diff line number Diff line change
@@ -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<UnsanitizedExtractInput, ExtractInput, ExtractOutput>
{
private readonly ILogger<ExtractFfiTool> _logger;

private readonly IFileSystem _fileSystem;
private readonly ExtractInputSanitizer _inputSanitizer;
private readonly ClangInstaller _clangInstaller;
private readonly Explorer _explorer;

private string? _clangFilePath;

public ExtractFfiTool(
ILogger<ExtractFfiTool> 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<TargetPlatform> ExtractFfis(ExtractOptions options)
{
var builder = ImmutableArray.CreateBuilder<TargetPlatform>();

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<TargetPlatform> targetPlatforms);

[LoggerMessage(3, LogLevel.Error, "Failure.")]
private partial void LogFailure();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace c2ffi.Tool.Commands.Extract.Input;

public sealed class ExtractInputSanitizer : InputSanitizer<UnsanitizedExtractInput, ExtractOptions>
public sealed class ExtractInputSanitizer : InputSanitizer<UnsanitizedExtractInput, ExtractInput>
{
private readonly string _hostOperatingSystemString;

Expand All @@ -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;
Expand Down Expand Up @@ -71,11 +71,11 @@ private string SanitizeCInputFilePath(string? inputFilePath)
return filePath;
}

private ImmutableArray<ExtractTargetPlatformOptions> SanitizeTargetPlatformsOptions(
private ImmutableArray<ExtractTargetPlatformInput> SanitizeTargetPlatformsOptions(
UnsanitizedExtractInput unsanitizedInput,
string inputFilePath)
{
var builder = ImmutableArray.CreateBuilder<ExtractTargetPlatformOptions>();
var builder = ImmutableArray.CreateBuilder<ExtractTargetPlatformInput>();

var isAtLeastOneMatchingOperatingSystem = false;
var targetPlatformsUnsanitizedInputByOperatingSystem = unsanitizedInput.TargetPlatforms;
Expand Down Expand Up @@ -109,14 +109,14 @@ private ImmutableArray<ExtractTargetPlatformOptions> 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),
Expand Down

This file was deleted.

Loading

0 comments on commit d520a26

Please sign in to comment.