package com.aicheck.analyzer; import com.aicheck.config.AppConfig; import com.aicheck.git.GitChangeScanner; import com.aicheck.model.ChangedClassFile; import com.aicheck.model.ClassChangeReport; import com.aicheck.model.FieldChange; import com.aicheck.model.FieldInfo; import com.aicheck.parser.ClassFieldParser; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; public class ClassChangeAnalyzer { private final GitChangeScanner gitScanner; private final ClassFieldParser classFieldParser = new ClassFieldParser(); private final FieldDiffEngine fieldDiffEngine = new FieldDiffEngine(); private final ImpactAnalyzer impactAnalyzer = new ImpactAnalyzer(); public ClassChangeAnalyzer(GitChangeScanner gitScanner) { this.gitScanner = gitScanner; } public List analyze(Path repoRoot, AppConfig config, String oldSha, String newSha, Map endpointIndex) throws IOException { List changedFiles = gitScanner.scanChangedClasses(oldSha, newSha); List reports = new ArrayList<>(); for (ChangedClassFile changedFile : changedFiles) { if (changedFile.getStatus() == ChangedClassFile.ChangeStatus.DELETED) { ClassChangeReport report = new ClassChangeReport( changedFile.getClassName(), changedFile.getClassType(), changedFile.getRelativePath(), true, config.isDtoEntityConversionEnabled() ); String oldSource = gitScanner.readFileAtCommit(oldSha, changedFile.getRelativePath()); impactAnalyzer.analyze(report, endpointIndex, config, repoRoot, oldSource); reports.add(report); continue; } String oldSource = gitScanner.readFileAtCommit(oldSha, changedFile.getRelativePath()); String newSource = gitScanner.readFileAtCommit(newSha, changedFile.getRelativePath()); if (newSource == null || newSource.isBlank()) { newSource = gitScanner.readFileAtHead(changedFile.getRelativePath()); } List oldFields = classFieldParser.parseFields(oldSource, changedFile.getClassName()); List newFields = classFieldParser.parseFields(newSource, changedFile.getClassName()); List fieldChanges = fieldDiffEngine.diff(oldFields, newFields); if (fieldChanges.isEmpty()) { continue; } ClassChangeReport report = new ClassChangeReport( changedFile.getClassName(), changedFile.getClassType(), changedFile.getRelativePath(), false, config.isDtoEntityConversionEnabled() ); fieldChanges.forEach(report::addFieldChange); impactAnalyzer.analyze(report, endpointIndex, config, repoRoot, newSource); reports.add(report); } return reports; } }