567 lines
25 KiB
C#
567 lines
25 KiB
C#
|
using Microsoft.CodeAnalysis;
|
|||
|
using Microsoft.CodeAnalysis.CSharp;
|
|||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.IO;
|
|||
|
using CodeMerger.ViewModels;
|
|||
|
using CodeMerger.Models;
|
|||
|
|
|||
|
public class cCodeMerger
|
|||
|
{
|
|||
|
private const string CONTINUATION_MARKER = "// ... resto del código ...";
|
|||
|
|
|||
|
private class ClassNamespaceMapping
|
|||
|
{
|
|||
|
public Dictionary<string, string> ClassToNamespace { get; } = new Dictionary<string, string>();
|
|||
|
|
|||
|
public void AddMapping(string className, string namespaceName)
|
|||
|
{
|
|||
|
if (!ClassToNamespace.ContainsKey(className))
|
|||
|
{
|
|||
|
ClassToNamespace[className] = namespaceName;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public string GetNamespace(string className)
|
|||
|
{
|
|||
|
return ClassToNamespace.TryGetValue(className, out var ns) ? ns : null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private readonly ClassNamespaceMapping _classNamespaceMapping = new ClassNamespaceMapping();
|
|||
|
|
|||
|
public class MergeResult
|
|||
|
{
|
|||
|
public bool Success { get; set; }
|
|||
|
public string MergedCode { get; set; }
|
|||
|
public List<string> Diagnostics { get; set; } = new List<string>();
|
|||
|
}
|
|||
|
|
|||
|
public MergeResult MergeCode(string originalCode, string llmCode, string outputPath, LogViewModel logger)
|
|||
|
{
|
|||
|
var result = new MergeResult();
|
|||
|
try
|
|||
|
{
|
|||
|
logger.AddLog("Starting code merge process...");
|
|||
|
|
|||
|
logger.AddLog("Parsing original code...", LogLevel.Debug);
|
|||
|
var originalTree = CSharpSyntaxTree.ParseText(originalCode);
|
|||
|
var originalRoot = originalTree.GetRoot() as CompilationUnitSyntax;
|
|||
|
|
|||
|
logger.AddLog("Parsing LLM code...", LogLevel.Debug);
|
|||
|
var llmTree = CSharpSyntaxTree.ParseText(llmCode);
|
|||
|
var llmRoot = llmTree.GetRoot() as CompilationUnitSyntax;
|
|||
|
|
|||
|
if (originalRoot == null || llmRoot == null)
|
|||
|
{
|
|||
|
logger.AddLog("Failed to parse syntax trees", LogLevel.Error);
|
|||
|
result.Success = false;
|
|||
|
result.Diagnostics.Add("Error parsing syntax trees");
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
logger.AddLog("Processing namespaces...");
|
|||
|
var newRoot = ProcessNamespaces(originalRoot, llmRoot, logger);
|
|||
|
|
|||
|
logger.AddLog("Formatting result...");
|
|||
|
var formattedRoot = newRoot.NormalizeWhitespace();
|
|||
|
|
|||
|
logger.AddLog($"Writing output to: {outputPath}");
|
|||
|
File.WriteAllText(outputPath, formattedRoot.ToFullString());
|
|||
|
|
|||
|
result.Success = true;
|
|||
|
result.MergedCode = formattedRoot.ToFullString();
|
|||
|
logger.AddLog("Merge completed successfully!");
|
|||
|
return result;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
logger.AddLog($"Error during merge: {ex.Message}", LogLevel.Error);
|
|||
|
logger.AddLog(ex.StackTrace ?? "", LogLevel.Debug);
|
|||
|
result.Success = false;
|
|||
|
result.Diagnostics.Add($"Error during merge: {ex.Message}");
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private CompilationUnitSyntax ProcessNamespaces(CompilationUnitSyntax originalRoot, CompilationUnitSyntax llmRoot, LogViewModel logger)
|
|||
|
{
|
|||
|
logger.AddLog("Checking for top-level members in LLM code...", LogLevel.Debug);
|
|||
|
var topLevelMembers = GetTopLevelMembers(llmRoot).ToList();
|
|||
|
|
|||
|
if (topLevelMembers.Any())
|
|||
|
{
|
|||
|
logger.AddLog("Found top-level members in LLM code, determining best namespace...", LogLevel.Debug);
|
|||
|
var targetNamespace = FindBestNamespaceForMembers(topLevelMembers, originalRoot, logger);
|
|||
|
|
|||
|
// Create or update namespace with top-level members
|
|||
|
var existingNamespace = llmRoot.Members.OfType<NamespaceDeclarationSyntax>()
|
|||
|
.FirstOrDefault(ns => ns.Name.ToString() == targetNamespace);
|
|||
|
|
|||
|
if (existingNamespace != null)
|
|||
|
{
|
|||
|
logger.AddLog($"Adding top-level members to existing namespace: {targetNamespace}", LogLevel.Debug);
|
|||
|
llmRoot = llmRoot.ReplaceNode(existingNamespace,
|
|||
|
existingNamespace.WithMembers(
|
|||
|
existingNamespace.Members.AddRange(topLevelMembers)));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
logger.AddLog($"Creating new namespace {targetNamespace} for top-level members", LogLevel.Debug);
|
|||
|
var newNamespace = SyntaxFactory.NamespaceDeclaration(
|
|||
|
SyntaxFactory.ParseName(targetNamespace))
|
|||
|
.WithMembers(SyntaxFactory.List(topLevelMembers));
|
|||
|
|
|||
|
llmRoot = llmRoot.WithMembers(
|
|||
|
SyntaxFactory.List(
|
|||
|
llmRoot.Members.Where(m => m is NamespaceDeclarationSyntax)
|
|||
|
.Concat(new[] { newNamespace })));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Continue with existing namespace processing
|
|||
|
logger.AddLog("Analyzing LLM code structure:", LogLevel.Debug);
|
|||
|
var llmNamespaces = new Dictionary<string, NamespaceDeclarationSyntax>();
|
|||
|
|
|||
|
// Log and collect LLM namespaces
|
|||
|
foreach (var ns in llmRoot.Members.OfType<NamespaceDeclarationSyntax>())
|
|||
|
{
|
|||
|
var nsName = ns.Name.ToString();
|
|||
|
logger.AddLog($"Found LLM namespace: {nsName}", LogLevel.Debug);
|
|||
|
llmNamespaces[nsName] = ns;
|
|||
|
|
|||
|
foreach (var cls in ns.Members.OfType<ClassDeclarationSyntax>())
|
|||
|
{
|
|||
|
logger.AddLog($" Class in LLM: {cls.Identifier}", LogLevel.Debug);
|
|||
|
logger.AddLog(" Fields and Properties in LLM class:", LogLevel.Debug);
|
|||
|
|
|||
|
// Log fields
|
|||
|
foreach (var field in cls.Members.OfType<FieldDeclarationSyntax>())
|
|||
|
{
|
|||
|
foreach (var variable in field.Declaration.Variables)
|
|||
|
{
|
|||
|
logger.AddLog($" Field: {variable.Identifier} : {field.Declaration.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Log properties
|
|||
|
foreach (var prop in cls.Members.OfType<PropertyDeclarationSyntax>())
|
|||
|
{
|
|||
|
logger.AddLog($" Property: {prop.Identifier} : {prop.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
|
|||
|
foreach (var method in cls.Members.OfType<MethodDeclarationSyntax>())
|
|||
|
{
|
|||
|
logger.AddLog($" Method: {method.Identifier}", LogLevel.Debug);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
logger.AddLog("\nAnalyzing original code structure:", LogLevel.Debug);
|
|||
|
var namespacesToProcess = originalRoot.Members.OfType<NamespaceDeclarationSyntax>().ToList();
|
|||
|
foreach (var ns in namespacesToProcess)
|
|||
|
{
|
|||
|
var nsName = ns.Name.ToString();
|
|||
|
logger.AddLog($"Found original namespace: {nsName}", LogLevel.Debug);
|
|||
|
|
|||
|
foreach (var cls in ns.Members.OfType<ClassDeclarationSyntax>())
|
|||
|
{
|
|||
|
logger.AddLog($" Class in original: {cls.Identifier}", LogLevel.Debug);
|
|||
|
logger.AddLog(" Fields and Properties in original class:", LogLevel.Debug);
|
|||
|
|
|||
|
// Log fields
|
|||
|
foreach (var field in cls.Members.OfType<FieldDeclarationSyntax>())
|
|||
|
{
|
|||
|
foreach (var variable in field.Declaration.Variables)
|
|||
|
{
|
|||
|
logger.AddLog($" Field: {variable.Identifier} : {field.Declaration.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Log properties
|
|||
|
foreach (var prop in cls.Members.OfType<PropertyDeclarationSyntax>())
|
|||
|
{
|
|||
|
logger.AddLog($" Property: {prop.Identifier} : {prop.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
|
|||
|
foreach (var member in cls.Members)
|
|||
|
{
|
|||
|
switch (member)
|
|||
|
{
|
|||
|
case MethodDeclarationSyntax method:
|
|||
|
logger.AddLog($" Method in original: {method.Identifier}", LogLevel.Debug);
|
|||
|
break;
|
|||
|
case PropertyDeclarationSyntax prop:
|
|||
|
logger.AddLog($" Property in original: {prop.Identifier}", LogLevel.Debug);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var newMembers = new List<MemberDeclarationSyntax>();
|
|||
|
|
|||
|
foreach (var ns in namespacesToProcess)
|
|||
|
{
|
|||
|
var nsName = ns.Name.ToString();
|
|||
|
logger.AddLog($"Processing namespace: {nsName}", LogLevel.Debug);
|
|||
|
|
|||
|
if (llmNamespaces.TryGetValue(nsName, out var llmNs))
|
|||
|
{
|
|||
|
logger.AddLog($"Found matching LLM namespace for: {nsName}", LogLevel.Debug);
|
|||
|
var processedNs = ProcessNamespace(ns, llmNs, logger);
|
|||
|
newMembers.Add(processedNs);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
logger.AddLog($"No matching LLM namespace found for: {nsName}, keeping original", LogLevel.Debug);
|
|||
|
newMembers.Add(ns);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Add new namespaces from LLM code
|
|||
|
foreach (var llmNs in llmNamespaces.Values)
|
|||
|
{
|
|||
|
var nsName = llmNs.Name.ToString();
|
|||
|
if (!namespacesToProcess.Any(ns => ns.Name.ToString() == nsName))
|
|||
|
{
|
|||
|
logger.AddLog($"Adding new namespace from LLM: {nsName}", LogLevel.Debug);
|
|||
|
newMembers.Add(llmNs);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return originalRoot.WithMembers(SyntaxFactory.List(newMembers));
|
|||
|
}
|
|||
|
|
|||
|
private IEnumerable<MemberDeclarationSyntax> GetTopLevelMembers(CompilationUnitSyntax root)
|
|||
|
{
|
|||
|
return root.Members.Where(m => !(m is NamespaceDeclarationSyntax));
|
|||
|
}
|
|||
|
|
|||
|
private string FindBestNamespaceForMembers(
|
|||
|
IEnumerable<MemberDeclarationSyntax> members,
|
|||
|
CompilationUnitSyntax originalRoot,
|
|||
|
LogViewModel logger)
|
|||
|
{
|
|||
|
var methodsByClass = members.OfType<ClassDeclarationSyntax>()
|
|||
|
.ToDictionary(
|
|||
|
c => c.Identifier.ToString(),
|
|||
|
c => c.Members.OfType<MethodDeclarationSyntax>()
|
|||
|
.Select(m => m.Identifier.ToString())
|
|||
|
.ToHashSet()
|
|||
|
);
|
|||
|
|
|||
|
foreach (var ns in originalRoot.Members.OfType<NamespaceDeclarationSyntax>())
|
|||
|
{
|
|||
|
foreach (var cls in ns.Members.OfType<ClassDeclarationSyntax>())
|
|||
|
{
|
|||
|
var className = cls.Identifier.ToString();
|
|||
|
foreach (var method in cls.Members.OfType<MethodDeclarationSyntax>())
|
|||
|
{
|
|||
|
if (methodsByClass.Any(kvp => kvp.Value.Contains(method.Identifier.ToString())))
|
|||
|
{
|
|||
|
var nsName = ns.Name.ToString();
|
|||
|
logger.AddLog($"Found matching method {method.Identifier} in namespace {nsName}", LogLevel.Debug);
|
|||
|
|
|||
|
// Registrar el namespace para la clase que contiene el método coincidente
|
|||
|
var matchingClass = methodsByClass.First(kvp => kvp.Value.Contains(method.Identifier.ToString())).Key;
|
|||
|
_classNamespaceMapping.AddMapping(matchingClass, nsName);
|
|||
|
|
|||
|
return nsName;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// If no matching methods found, use first namespace
|
|||
|
var firstNamespace = originalRoot.Members.OfType<NamespaceDeclarationSyntax>().FirstOrDefault();
|
|||
|
if (firstNamespace != null)
|
|||
|
{
|
|||
|
logger.AddLog($"No matching methods found, using first namespace: {firstNamespace.Name}", LogLevel.Debug);
|
|||
|
return firstNamespace.Name.ToString();
|
|||
|
}
|
|||
|
|
|||
|
logger.AddLog("No namespaces found in original code!", LogLevel.Warning);
|
|||
|
return "DefaultNamespace";
|
|||
|
}
|
|||
|
|
|||
|
private NamespaceDeclarationSyntax ProcessNamespace(NamespaceDeclarationSyntax original, NamespaceDeclarationSyntax llm, LogViewModel logger)
|
|||
|
{
|
|||
|
logger.AddLog($"Processing classes in namespace: {original.Name}", LogLevel.Debug);
|
|||
|
var classesToProcess = original.Members.OfType<ClassDeclarationSyntax>();
|
|||
|
var llmClasses = llm.Members.OfType<ClassDeclarationSyntax>()
|
|||
|
.ToDictionary(c => c.Identifier.ToString());
|
|||
|
|
|||
|
var newMembers = new List<MemberDeclarationSyntax>();
|
|||
|
|
|||
|
foreach (var cls in classesToProcess)
|
|||
|
{
|
|||
|
if (llmClasses.TryGetValue(cls.Identifier.ToString(), out var llmClass))
|
|||
|
{
|
|||
|
// Process methods and properties within the class
|
|||
|
var processedClass = ProcessClass(cls, llmClass, logger);
|
|||
|
newMembers.Add(processedClass);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Keep original class unchanged
|
|||
|
newMembers.Add(cls);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Add any new classes from LLM code
|
|||
|
foreach (var llmClass in llmClasses.Values)
|
|||
|
{
|
|||
|
if (!classesToProcess.Any(c => c.Identifier.ToString() == llmClass.Identifier.ToString()))
|
|||
|
{
|
|||
|
newMembers.Add(llmClass);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return original.WithMembers(SyntaxFactory.List(newMembers));
|
|||
|
}
|
|||
|
|
|||
|
private ClassDeclarationSyntax ProcessClass(ClassDeclarationSyntax original, ClassDeclarationSyntax llm, LogViewModel logger)
|
|||
|
{
|
|||
|
logger.AddLog($"Processing class: {original.Identifier}", LogLevel.Debug);
|
|||
|
|
|||
|
// Log original fields and properties
|
|||
|
logger.AddLog("Original class fields and properties:", LogLevel.Debug);
|
|||
|
foreach (var field in original.Members.OfType<FieldDeclarationSyntax>())
|
|||
|
{
|
|||
|
foreach (var variable in field.Declaration.Variables)
|
|||
|
{
|
|||
|
logger.AddLog($" Field: {variable.Identifier} : {field.Declaration.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
}
|
|||
|
foreach (var prop in original.Members.OfType<PropertyDeclarationSyntax>())
|
|||
|
{
|
|||
|
logger.AddLog($" Property: {prop.Identifier} : {prop.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
|
|||
|
// Log LLM fields and properties
|
|||
|
logger.AddLog("LLM class fields and properties:", LogLevel.Debug);
|
|||
|
foreach (var field in llm.Members.OfType<FieldDeclarationSyntax>())
|
|||
|
{
|
|||
|
foreach (var variable in field.Declaration.Variables)
|
|||
|
{
|
|||
|
logger.AddLog($" Field: {variable.Identifier} : {field.Declaration.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
}
|
|||
|
foreach (var prop in llm.Members.OfType<PropertyDeclarationSyntax>())
|
|||
|
{
|
|||
|
logger.AddLog($" Property: {prop.Identifier} : {prop.Type}", LogLevel.Debug);
|
|||
|
}
|
|||
|
|
|||
|
var newMembers = new List<MemberDeclarationSyntax>();
|
|||
|
var processedMembers = new HashSet<string>();
|
|||
|
var processedFields = new HashSet<string>();
|
|||
|
var processedProperties = new HashSet<string>();
|
|||
|
|
|||
|
// Process existing fields first
|
|||
|
foreach (var member in original.Members)
|
|||
|
{
|
|||
|
if (member is FieldDeclarationSyntax originalField)
|
|||
|
{
|
|||
|
foreach (var variable in originalField.Declaration.Variables)
|
|||
|
{
|
|||
|
var fieldName = variable.Identifier.ToString();
|
|||
|
var llmField = llm.Members.OfType<FieldDeclarationSyntax>()
|
|||
|
.FirstOrDefault(f => f.Declaration.Variables
|
|||
|
.Any(v => v.Identifier.ToString() == fieldName));
|
|||
|
|
|||
|
if (llmField != null)
|
|||
|
{
|
|||
|
logger.AddLog($" Updating field: {fieldName}", LogLevel.Debug);
|
|||
|
newMembers.Add(llmField);
|
|||
|
processedFields.Add(fieldName);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
logger.AddLog($" Keeping original field: {fieldName}", LogLevel.Debug);
|
|||
|
newMembers.Add(originalField);
|
|||
|
processedFields.Add(fieldName);
|
|||
|
}
|
|||
|
break; // Process one field declaration at a time
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Add new fields from LLM
|
|||
|
foreach (var field in llm.Members.OfType<FieldDeclarationSyntax>())
|
|||
|
{
|
|||
|
foreach (var variable in field.Declaration.Variables)
|
|||
|
{
|
|||
|
var fieldName = variable.Identifier.ToString();
|
|||
|
if (!processedFields.Contains(fieldName))
|
|||
|
{
|
|||
|
logger.AddLog($" Adding new field from LLM: {fieldName}", LogLevel.Debug);
|
|||
|
// Add comment to mark new field with separator
|
|||
|
var newField = field.WithLeadingTrivia(
|
|||
|
SyntaxFactory.TriviaList(
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// ----------------------------------------"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// Added: New field"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n")));
|
|||
|
newMembers.Add(newField);
|
|||
|
processedFields.Add(fieldName);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Procesar primero las propiedades existentes
|
|||
|
foreach (var member in original.Members)
|
|||
|
{
|
|||
|
if (member is PropertyDeclarationSyntax originalProperty)
|
|||
|
{
|
|||
|
var propertyName = originalProperty.Identifier.ToString();
|
|||
|
var llmProperty = llm.Members.OfType<PropertyDeclarationSyntax>()
|
|||
|
.FirstOrDefault(p => p.Identifier.ToString() == propertyName);
|
|||
|
|
|||
|
if (llmProperty != null)
|
|||
|
{
|
|||
|
logger.AddLog($" Updating property: {propertyName}", LogLevel.Debug);
|
|||
|
newMembers.Add(llmProperty);
|
|||
|
processedProperties.Add(propertyName);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
logger.AddLog($" Keeping original property: {propertyName}", LogLevel.Debug);
|
|||
|
newMembers.Add(originalProperty);
|
|||
|
processedProperties.Add(propertyName);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Añadir nuevas propiedades del LLM
|
|||
|
foreach (var member in llm.Members.OfType<PropertyDeclarationSyntax>())
|
|||
|
{
|
|||
|
var propertyName = member.Identifier.ToString();
|
|||
|
if (!processedProperties.Contains(propertyName))
|
|||
|
{
|
|||
|
logger.AddLog($" Adding new property from LLM: {propertyName}", LogLevel.Debug);
|
|||
|
// Add comment to mark new property with separator
|
|||
|
var newProperty = member.WithLeadingTrivia(
|
|||
|
SyntaxFactory.TriviaList(
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// ----------------------------------------"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// Added: New property"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n")));
|
|||
|
newMembers.Add(newProperty);
|
|||
|
processedProperties.Add(propertyName);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Procesar métodos como antes
|
|||
|
foreach (var member in original.Members)
|
|||
|
{
|
|||
|
if (member is MethodDeclarationSyntax originalMethod)
|
|||
|
{
|
|||
|
var methodName = originalMethod.Identifier.ToString();
|
|||
|
var llmMethod = llm.Members.OfType<MethodDeclarationSyntax>()
|
|||
|
.FirstOrDefault(m => m.Identifier.ToString() == methodName);
|
|||
|
|
|||
|
if (llmMethod != null)
|
|||
|
{
|
|||
|
logger.AddLog($" Found matching method: {methodName}", LogLevel.Debug);
|
|||
|
var processedMethod = ProcessMethod(originalMethod, llmMethod, logger);
|
|||
|
// Add comment to mark modified method with separator
|
|||
|
var modifiedMethod = processedMethod.WithLeadingTrivia(
|
|||
|
SyntaxFactory.TriviaList(
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// ----------------------------------------"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// Modified: Updated implementation"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n")));
|
|||
|
newMembers.Add(modifiedMethod);
|
|||
|
processedMembers.Add(methodName);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
logger.AddLog($" Keeping original method: {methodName}", LogLevel.Debug);
|
|||
|
newMembers.Add(member);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (!(member is PropertyDeclarationSyntax))
|
|||
|
{
|
|||
|
newMembers.Add(member);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Añadir nuevos métodos del LLM como antes
|
|||
|
foreach (var member in llm.Members)
|
|||
|
{
|
|||
|
if (member is MethodDeclarationSyntax llmMethod &&
|
|||
|
!processedMembers.Contains(llmMethod.Identifier.ToString()))
|
|||
|
{
|
|||
|
logger.AddLog($" Adding new method from LLM: {llmMethod.Identifier}", LogLevel.Debug);
|
|||
|
// Add comment to mark new method with separator
|
|||
|
var newMethod = llmMethod.WithLeadingTrivia(
|
|||
|
SyntaxFactory.TriviaList(
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// ----------------------------------------"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.SingleLineCommentTrivia, "// Added: New method"),
|
|||
|
SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\r\n")));
|
|||
|
newMembers.Add(newMethod);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return original.WithMembers(SyntaxFactory.List(newMembers));
|
|||
|
}
|
|||
|
|
|||
|
private MethodDeclarationSyntax ProcessMethod(MethodDeclarationSyntax original, MethodDeclarationSyntax llm, LogViewModel logger)
|
|||
|
{
|
|||
|
var methodName = original.Identifier.ToString();
|
|||
|
logger.AddLog($" Processing method: {methodName}", LogLevel.Debug);
|
|||
|
|
|||
|
var llmBody = llm.Body?.ToString() ?? "";
|
|||
|
logger.AddLog($" Original signature: {original.Modifiers} {original.ReturnType} {methodName}({string.Join(", ", original.ParameterList.Parameters)})", LogLevel.Debug);
|
|||
|
logger.AddLog($" LLM signature: {llm.Modifiers} {llm.ReturnType} {methodName}({string.Join(", ", llm.ParameterList.Parameters)})", LogLevel.Debug);
|
|||
|
|
|||
|
if (llmBody.Contains(CONTINUATION_MARKER))
|
|||
|
{
|
|||
|
logger.AddLog(" Found continuation marker in LLM code", LogLevel.Debug);
|
|||
|
var originalBody = original.Body?.ToString() ?? "";
|
|||
|
var llmLines = llmBody.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
|||
|
|
|||
|
var lastLlmLine = llmLines
|
|||
|
.Take(Array.FindIndex(llmLines, l => l.Contains(CONTINUATION_MARKER)))
|
|||
|
.Where(l => !string.IsNullOrWhiteSpace(l))
|
|||
|
.LastOrDefault();
|
|||
|
|
|||
|
if (lastLlmLine != null)
|
|||
|
{
|
|||
|
logger.AddLog($" Last LLM line before marker: {lastLlmLine}", LogLevel.Debug);
|
|||
|
var originalLines = originalBody.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
|||
|
var continuationIndex = Array.FindIndex(originalLines, l => l.Trim() == lastLlmLine.Trim());
|
|||
|
|
|||
|
if (continuationIndex >= 0)
|
|||
|
{
|
|||
|
logger.AddLog($" Found continuation point at line {continuationIndex + 1}", LogLevel.Debug);
|
|||
|
var newBody = string.Join(Environment.NewLine,
|
|||
|
llmLines.Take(Array.FindIndex(llmLines, l => l.Contains(CONTINUATION_MARKER)))
|
|||
|
.Concat(originalLines.Skip(continuationIndex + 1)));
|
|||
|
|
|||
|
logger.AddLog(" Successfully merged method bodies", LogLevel.Debug);
|
|||
|
return llm.WithBody(SyntaxFactory.Block(SyntaxFactory.ParseStatement(newBody)));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
logger.AddLog(" Could not find continuation point in original code", LogLevel.Warning);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
logger.AddLog(" Using complete LLM method implementation", LogLevel.Debug);
|
|||
|
}
|
|||
|
|
|||
|
return llm;
|
|||
|
}
|
|||
|
}
|