Files
whetstone_DSL/editor/src/EditorUtils.h

187 lines
6.0 KiB
C++

#pragma once
#include "EditorState.h"
#include "StringUtils.h"
#include "imgui.h"
#include "SyntaxHighlighter.h"
#include "CodeEditorWidget.h"
#include "FileTree.h"
#include "WelcomeScreen.h"
#include "FileDialog.h"
#include "LSPClient.h"
#include "BufferManager.h"
#include "ast/Serialization.h"
#include "ast/Generator.h"
#include "ast/Annotation.h"
#include <string>
#include <vector>
#include <algorithm>
#include <climits>
#include <memory>
static int countLines(const std::string& text) {
int lines = 1;
for (char c : text) {
if (c == '\n') ++lines;
}
return lines;
}
static std::string generateForLanguage(const Module* ast, const std::string& language) {
if (!ast) return "";
if (language == "python") {
PythonGenerator gen;
return gen.generate(ast);
}
if (language == "cpp") {
CppGenerator gen;
return gen.generate(ast);
}
if (language == "elisp") {
ElispGenerator gen;
return gen.generate(ast);
}
if (language == "javascript") {
JavaScriptGenerator gen;
return gen.generate(ast);
}
if (language == "typescript") {
TypeScriptGenerator gen;
return gen.generate(ast);
}
if (language == "java") {
JavaGenerator gen;
return gen.generate(ast);
}
if (language == "rust") {
RustGenerator gen;
return gen.generate(ast);
}
if (language == "go") {
GoGenerator gen;
return gen.generate(ast);
}
PythonGenerator gen;
return gen.generate(ast);
}
static std::unique_ptr<Module> cloneModule(const Module* ast) {
if (!ast) return nullptr;
json j = toJson(ast);
ASTNode* node = fromJson(j);
if (!node || node->conceptType != "Module") return nullptr;
return std::unique_ptr<Module>(static_cast<Module*>(node));
}
static bool isAnnotationNode(const ASTNode* node) {
if (!node) return false;
if (node->conceptType.find("Annotation") != std::string::npos) return true;
if (node->conceptType == "DerefStrategy") return true;
if (node->conceptType == "OptimizationLock") return true;
if (node->conceptType == "LangSpecific") return true;
return false;
}
static int countAnnotationNodes(const ASTNode* node) {
if (!node) return 0;
int count = isAnnotationNode(node) ? 1 : 0;
for (auto* child : node->allChildren()) {
count += countAnnotationNodes(child);
}
return count;
}
static std::string findOptimizationBlockReason(const ASTNode* node) {
if (!node) return "";
for (auto* anno : node->getChildren("annotations")) {
if (anno->conceptType == "OwnerAnnotation") {
auto* oa = static_cast<const OwnerAnnotation*>(anno);
if (oa->strategy == "Single") {
return "@Owner(Single) blocks optimization (aliasing risk)";
}
}
if (anno->conceptType == "DeallocateAnnotation") {
auto* da = static_cast<const DeallocateAnnotation*>(anno);
if (da->strategy == "Explicit") {
return "@Deallocate(Explicit) blocks optimization (reorder risk)";
}
}
if (anno->conceptType == "AllocateAnnotation") {
auto* aa = static_cast<const AllocateAnnotation*>(anno);
if (aa->strategy == "Static") {
return "@Allocate(Static) blocks optimization (dynamic alloc risk)";
}
}
}
for (auto* child : node->allChildren()) {
std::string found = findOptimizationBlockReason(child);
if (!found.empty()) return found;
}
return "";
}
static std::string findOptimizationLockWarning(const ASTNode* node) {
if (!node) return "";
if (node->conceptType == "OptimizationLock") {
auto* lock = static_cast<const OptimizationLock*>(node);
if (lock->lockLevel == "warning") {
return "OptimizationLock: " + lock->lockReason +
" (locked by " + lock->lockedBy + ")";
}
}
for (auto* child : node->allChildren()) {
std::string found = findOptimizationLockWarning(child);
if (!found.empty()) return found;
}
return "";
}
static ImVec4 transformColorForName(const std::string& name) {
if (name == "constant-fold") return ImVec4(0.45f, 0.85f, 0.45f, 1.0f);
if (name == "dead-code-elim") return ImVec4(0.90f, 0.45f, 0.45f, 1.0f);
return ImVec4(0.75f, 0.75f, 0.75f, 1.0f);
}
// ---------------------------------------------------------------------------
// ImGui InputTextMultiline with std::string resize callback
// ---------------------------------------------------------------------------
struct InputTextCallbackData {
std::string* str;
};
static int InputTextCallback(ImGuiInputTextCallbackData* data) {
auto* userData = static_cast<InputTextCallbackData*>(data->UserData);
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
userData->str->resize(data->BufTextLen);
data->Buf = userData->str->data();
}
return 0;
}
static bool InputTextMultilineStr(const char* label, std::string* str,
const ImVec2& size, ImGuiInputTextFlags flags = 0) {
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallbackData cbData{str};
// Ensure buffer has room
if (str->capacity() < str->size() + 256)
str->reserve(str->size() + 4096);
return ImGui::InputTextMultiline(label, str->data(), str->capacity() + 1,
size, flags, InputTextCallback, &cbData);
}
static bool InputTextStr(const char* label, std::string* str, ImGuiInputTextFlags flags = 0) {
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallbackData cbData{str};
if (str->capacity() < str->size() + 64)
str->reserve(str->size() + 256);
return ImGui::InputText(label, str->data(), str->capacity() + 1,
flags, InputTextCallback, &cbData);
}
#include "editor_utils/EditorUtilsPart1.h"
#include "editor_utils/EditorUtilsPart2.h"
#include "editor_utils/EditorUtilsPart3.h"