Files
whetstone_DSL/editor/src/AnnotationConflict.h
2026-02-09 10:39:48 -07:00

74 lines
2.9 KiB
C++

#pragma once
// Step 101: Annotation conflict detection helpers
#include <string>
#include <vector>
#include "ast/ASTNode.h"
#include "ast/Annotation.h"
struct AnnotationConflict {
std::string childAnnoId;
std::string parentAnnoId;
std::string conceptType;
std::string parentStrategy;
std::string message;
int childLine = -1;
int parentLine = -1;
};
inline std::string annotationStrategy(const ASTNode* anno) {
if (!anno) return "";
if (anno->conceptType == "DeallocateAnnotation")
return static_cast<const DeallocateAnnotation*>(anno)->strategy;
if (anno->conceptType == "LifetimeAnnotation")
return static_cast<const LifetimeAnnotation*>(anno)->strategy;
if (anno->conceptType == "ReclaimAnnotation")
return static_cast<const ReclaimAnnotation*>(anno)->strategy;
if (anno->conceptType == "OwnerAnnotation")
return static_cast<const OwnerAnnotation*>(anno)->strategy;
if (anno->conceptType == "AllocateAnnotation")
return static_cast<const AllocateAnnotation*>(anno)->strategy;
return "";
}
inline int nodeLineOrFallback(const ASTNode* node, const ASTNode* fallback) {
if (node && node->hasSpan()) return node->spanStartLine;
if (fallback && fallback->hasSpan()) return fallback->spanStartLine;
return -1;
}
inline void collectAnnotationConflicts(const ASTNode* node,
std::vector<AnnotationConflict>& out) {
if (!node) return;
for (auto* anno : node->getChildren("annotations")) {
std::string strategy = annotationStrategy(anno);
if (strategy.empty()) continue;
const ASTNode* cur = node->parent;
while (cur) {
for (auto* parentAnno : cur->getChildren("annotations")) {
if (parentAnno->conceptType == anno->conceptType) {
std::string parentStrategy = annotationStrategy(parentAnno);
if (!parentStrategy.empty() && parentStrategy != strategy) {
AnnotationConflict c;
c.childAnnoId = anno->id;
c.parentAnnoId = parentAnno->id;
c.conceptType = anno->conceptType;
c.parentStrategy = parentStrategy;
c.childLine = nodeLineOrFallback(anno, node);
c.parentLine = nodeLineOrFallback(parentAnno, cur);
c.message = "Annotation conflict: " + anno->conceptType +
"(" + strategy + ") vs " +
parentAnno->conceptType + "(" + parentStrategy + ")";
out.push_back(std::move(c));
return;
}
}
}
cur = cur->parent;
}
}
for (auto* child : node->allChildren()) {
collectAnnotationConflicts(child, out);
}
}