MarketAlly.AIPlugin.Extensions/MarketAlly.AIPlugin.Analysis/CompilationManager.cs

190 lines
5.2 KiB
C#
Executable File

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace MarketAlly.AIPlugin.Analysis.Plugins
{
public class CompilationManager
{
public CompilationManager()
{
}
public async Task<CompilationResult> ValidateCompilationAsync(string solutionPath)
{
var result = new CompilationResult
{
StartTime = DateTime.UtcNow,
SolutionPath = solutionPath
};
try
{
// Use dotnet build to validate compilation
var processInfo = new ProcessStartInfo
{
FileName = "dotnet",
Arguments = $"build \"{solutionPath}\" --verbosity quiet --nologo",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var process = Process.Start(processInfo);
if (process == null)
{
throw new InvalidOperationException("Failed to start dotnet build process");
}
var output = await process.StandardOutput.ReadToEndAsync();
var error = await process.StandardError.ReadToEndAsync();
await process.WaitForExitAsync();
result.ExitCode = process.ExitCode;
result.BuildOutput = output;
result.BuildErrors = error;
// Parse compilation results
result.Status = process.ExitCode == 0 ? CompilationStatus.Success : CompilationStatus.Failed;
// Use existing parsing logic from WarningsAnalysisPlugin
result.Warnings = ParseWarningsFromBuildOutput(output + error);
result.Errors = ParseErrorsFromBuildOutput(output + error);
result.ErrorCount = result.Errors.Count;
result.WarningCount = result.Warnings.Count;
// Adjust status based on warnings
if (result.Status == CompilationStatus.Success && result.WarningCount > 0)
{
result.Status = CompilationStatus.Warning;
}
}
catch (Exception ex)
{
result.Status = CompilationStatus.Failed;
result.ErrorMessage = ex.Message;
}
finally
{
result.EndTime = DateTime.UtcNow;
result.Duration = result.EndTime - result.StartTime;
}
return result;
}
private List<CompilationDiagnostic> ParseWarningsFromBuildOutput(string buildOutput)
{
var warnings = new List<CompilationDiagnostic>();
var lines = buildOutput.Split('\n', StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line.Contains("warning", StringComparison.OrdinalIgnoreCase))
{
var warning = TryParseDiagnosticLine(line.Trim(), "warning");
if (warning != null)
{
warnings.Add(warning);
}
}
}
return warnings;
}
private List<CompilationDiagnostic> ParseErrorsFromBuildOutput(string buildOutput)
{
var errors = new List<CompilationDiagnostic>();
var lines = buildOutput.Split('\n', StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line.Contains("error", StringComparison.OrdinalIgnoreCase) &&
!line.Contains("warning", StringComparison.OrdinalIgnoreCase))
{
var error = TryParseDiagnosticLine(line.Trim(), "error");
if (error != null)
{
errors.Add(error);
}
}
}
return errors;
}
private CompilationDiagnostic? TryParseDiagnosticLine(string line, string type)
{
var patterns = new[]
{
@"(.+?)\((\d+),(\d+)\):\s*warning\s+([A-Z]+\d+):\s*(.+)",
@"warning\s+([A-Z]+\d+):\s*(.+)\s*\[(.+?)\]"
};
foreach (var pattern in patterns)
{
var match = System.Text.RegularExpressions.Regex.Match(line, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
if (match.Success)
{
if (match.Groups.Count >= 5 && !string.IsNullOrEmpty(match.Groups[1].Value))
{
return new CompilationDiagnostic
{
File = Path.GetFileName(match.Groups[1].Value),
Line = int.TryParse(match.Groups[2].Value, out var parsedLine) ? parsedLine : 0,
Column = int.TryParse(match.Groups[3].Value, out var parsedCol) ? parsedCol : 0,
Code = match.Groups[4].Value,
Message = match.Groups[5].Value.Trim(),
Type = "warning"
};
}
else if (match.Groups.Count >= 3)
{
return new CompilationDiagnostic
{
Code = match.Groups[1].Value,
Message = match.Groups[2].Value.Trim(),
File = match.Groups.Count > 3 ? Path.GetFileName(match.Groups[3].Value) : "Unknown",
Type = "warning"
};
}
}
}
return null;
}
}
public class CompilationResult
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public TimeSpan Duration { get; set; }
public string SolutionPath { get; set; } = string.Empty;
public CompilationStatus Status { get; set; }
public int ExitCode { get; set; }
public int ErrorCount { get; set; }
public int WarningCount { get; set; }
public int? PreviousErrorCount { get; set; }
public string BuildOutput { get; set; } = string.Empty;
public string BuildErrors { get; set; } = string.Empty;
public string ErrorMessage { get; set; } = string.Empty;
public List<CompilationDiagnostic> Errors { get; set; } = new();
public List<CompilationDiagnostic> Warnings { get; set; } = new();
}
public enum CompilationStatus
{
Success,
Warning,
Failed
}
}