Améliorations des dépendances circulaire
This commit is contained in:
@@ -5,52 +5,98 @@ import java.util.*;
|
||||
public class DependencyResolver {
|
||||
private boolean debug;
|
||||
private Map<String, Rule> ruleMap;
|
||||
private boolean isCircular;
|
||||
|
||||
public DependencyResolver(boolean debug) {
|
||||
this.debug = debug;
|
||||
this.isCircular = false;
|
||||
}
|
||||
|
||||
public List<Rule> resolve(List<Rule> allRules, List<String> requestedRules) {
|
||||
List<Rule> rulesToBuild = new ArrayList<>();
|
||||
ruleMap = new HashMap<>();
|
||||
Set<String> builtRules = new HashSet<>(); // Éviter d'ajouter des règles déjà vérifiées
|
||||
|
||||
// Construire la map des règles
|
||||
for (Rule rule : allRules) {
|
||||
ruleMap.put(rule.getName(), rule);
|
||||
}
|
||||
|
||||
|
||||
// Premier passage : détection et suppression des cycles
|
||||
Set<String> visited = new HashSet<>();
|
||||
Set<String> stack = new HashSet<>();
|
||||
|
||||
List<String> targetRules = requestedRules.isEmpty() ?
|
||||
Collections.singletonList(BakefileParser.getFirstTarget()) :
|
||||
requestedRules;
|
||||
|
||||
for (String ruleName : requestedRules.isEmpty() ? ruleMap.keySet() : requestedRules) {
|
||||
for (String ruleName : targetRules) {
|
||||
if (ruleMap.containsKey(ruleName)) {
|
||||
detectCycle(ruleName, visited, stack);
|
||||
collectDependencies(ruleName, rulesToBuild, builtRules);
|
||||
detectCycle(ruleName, visited, stack, ruleName);
|
||||
} else if (debug) {
|
||||
System.out.println("Warning: Rule '" + ruleName + "' not found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Deuxième passage : collecte des dépendances dans l'ordre
|
||||
Set<String> processed = new HashSet<>();
|
||||
List<String> buildOrder = new ArrayList<>();
|
||||
|
||||
for (String ruleName : targetRules) {
|
||||
topologicalSort(ruleName, processed, buildOrder);
|
||||
}
|
||||
|
||||
// Construire la liste finale des règles dans l'ordre
|
||||
for (String ruleName : buildOrder) {
|
||||
Rule rule = ruleMap.get(ruleName);
|
||||
if (rule != null) {
|
||||
rulesToBuild.add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
return rulesToBuild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détection des cycles avec DFS
|
||||
*/
|
||||
private void detectCycle(String ruleName, Set<String> visited, Set<String> stack) {
|
||||
if (stack.contains(ruleName)) {
|
||||
throw new RuntimeException("Dependency cycle detected involving rule: " + ruleName);
|
||||
private void topologicalSort(String ruleName, Set<String> processed, List<String> buildOrder) {
|
||||
if (!ruleMap.containsKey(ruleName) || processed.contains(ruleName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
processed.add(ruleName);
|
||||
Rule rule = ruleMap.get(ruleName);
|
||||
|
||||
// D'abord traiter les dépendances
|
||||
for (String dep : rule.getDependencies()) {
|
||||
topologicalSort(dep, processed, buildOrder);
|
||||
}
|
||||
|
||||
// Puis ajouter la règle courante
|
||||
buildOrder.add(ruleName);
|
||||
}
|
||||
|
||||
// La méthode detectCycle reste inchangée
|
||||
private void detectCycle(String ruleName, Set<String> visited, Set<String> stack, String parent) {
|
||||
if (stack.contains(ruleName)) {
|
||||
if (parent != null) {
|
||||
System.out.println("make: Circular " + parent + " <- " + ruleName + " dependency dropped.");
|
||||
this.isCircular = true;
|
||||
Rule parentRule = ruleMap.get(parent);
|
||||
if (parentRule != null) {
|
||||
parentRule.getDependencies().remove(ruleName);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!visited.contains(ruleName)) {
|
||||
visited.add(ruleName);
|
||||
stack.add(ruleName);
|
||||
|
||||
|
||||
Rule rule = ruleMap.get(ruleName);
|
||||
if (rule != null) {
|
||||
for (String dependency : rule.getDependencies()) {
|
||||
List<String> dependenciesCopy = new ArrayList<>(rule.getDependencies());
|
||||
for (String dependency : dependenciesCopy) {
|
||||
if (ruleMap.containsKey(dependency)) {
|
||||
detectCycle(dependency, visited, stack);
|
||||
detectCycle(dependency, visited, stack, ruleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,23 +104,7 @@ public class DependencyResolver {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collecte récursive des règles à construire en évitant les doublons
|
||||
*/
|
||||
private void collectDependencies(String ruleName, List<Rule> rulesToBuild, Set<String> builtRules) {
|
||||
if (builtRules.contains(ruleName)) {
|
||||
return; // Évite d'ajouter une règle plusieurs fois
|
||||
}
|
||||
|
||||
Rule rule = ruleMap.get(ruleName);
|
||||
if (rule != null) {
|
||||
for (String dependency : rule.getDependencies()) {
|
||||
if (ruleMap.containsKey(dependency)) {
|
||||
collectDependencies(dependency, rulesToBuild, builtRules);
|
||||
}
|
||||
}
|
||||
rulesToBuild.add(rule);
|
||||
builtRules.add(ruleName);
|
||||
}
|
||||
public boolean isCircular() {
|
||||
return isCircular;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user