How to update when RTL changes #733
Replies: 2 comments 7 replies
-
1 & 2: Text loaded into the SourceManager can't be safely unloaded because everything downstream from it (syntax trees, AST symbols, etc) contain pointers into that text instead of copying. When the source changes you need to load a new buffer and reparse it, and then rebuild the AST from the new buffer. To unload the old text, the only way currently is to destroy the SourceManager and make a new one. This is obviously wasteful if you have a bunch of buffers loaded into memory and only want to change one of them, so it would make sense to me to add a method to migrate buffer memory between SourceManagers so you could recreate quickly with all of the files that did not change and then just load the one that did. Such a method does not exist currently but it would not be too hard to add I think, but you would need to ensure that there are no existing syntax or AST objects that reference the old buffer memory.
If you're using the first method, then you create a separate SyntaxTree per buffer and only need to reparse (i.e. recreate a new SyntaxTree) for a single file whenever it changes. If you're using the second method then you create a single SyntaxTree from all of the buffers (using fromBuffers) and need to reparse everything whenever a file changes (because you don't know how parsing later files will change based on macro definitions that happen inside the changed file). |
Beta Was this translation helpful? Give feedback.
-
Hi there ! So, I'm currently trying to do more or less the same thing as the OP (in my case a Language Server, LS) and would like to minimize file re-parsing. After reading this discussion, I understand that, in order to reload a single file you need to delete the Now, as I want to be able to performs actions on the elaborated design (like getting diagnostics, references and so on), I need to compile the design. void DiplomatLSP::_compile()
{
spdlog::info("Request design compilation");
// Create a structure which holds a source manager and a syntax tree per-file.
_read_workspace_modules();
// Reset the internal compilation object
_compilation.reset(new slang::ast::Compilation());
//Prepare the diagnostics
slang::DiagnosticEngine de(*(_compilation->getSourceManager()));
de.addClient(std::shared_ptr<DiplomatLSP>(this)); // NB : This is probably quite bad
spdlog::info("Add syntax trees");
for (const auto& [key, value] : _documents)
{
_compilation->addSyntaxTree(value->st);
}
// Run the compilation
_compilation->getRoot();
spdlog::info("Issuing diagnostics");
for (const slang::Diagnostic& diag : _compilation->getAllDiagnostics())
de.issue(diag);
} This version is a bit simple (I actually re-real all sources) but the idea is here. Each element stored in Now, when I add the syntax trees to the compilation through
Which seems reasonable to me. But then my question, should I have used the same |
Beta Was this translation helpful? Give feedback.
-
Sorry, I have a super basic question, probably caused by me just not using things in the right way. Basically, I am trying to use slang with my RTL editor to do syntax highlighting and error detection. I have one global SourceManager (that uses getDefaultSourceManager()), and I add files via
slang::SourceBuffer buffer = sm.assignText(path, code, loc);
I can then make a SyntaxTree with SyntaxTree::fromBuffer(), get the compilation with Compilation::addSyntaxTree(), and then get errors with Compilation::getAllDiagnostics()
All of that works. However, I am not sure what needs to get called when a source file changes. I'm not immediately seeing a way to remove/readd a buffer to the source manager, and I don't immediately see a way to update the text in an existing buffer.
I guess the larger more general questions are
am I even using things correctly, or is it meant to be used in a different way?
if I want to update errors and syntax highlighting in real time, what needs to be done when an existing RTL file changes?
if I add a file to SourceManager and get a buffer back, does SourceManager need to know when a registered file is deleted/changed
am I meant to have one syntax tree per buffer? Would it know about definitions of things in other files? Does it need to be destroyed/rebuilt when a file changes?
So sorry if these are basic questions, but I don't really see any documentation on how to use things so I am just taking random guesses based on useful-sounding function names I see
Beta Was this translation helpful? Give feedback.
All reactions