haxe
haxe copied to clipboard
"Hybrid" compiler server.
It would be nice if one could use the server in a hybrid mode that uses the cache only for display/diagnostics and is ignored in any build (if the build succeeds, it should replace the cache used by IDE services). Motivation:
- The most obvious one is that one may be using macros that don't play well with the server. Of course as I'm sure @Gama11 would point out if didn't: the long term solution here is to fix such macros and/or report compiler issues if it can be reduced to something in the compiler. This is not always practical though.
- Fully deterministic builds. Things get typed in the same order. Any incremental ids one may generate wind up in a stable order (at least for local changes).
I don't know... diagnostics is just building with extra steps and separating these two seems questionable. You could get diagnostics for something which then doesn't show up in the actual build, which would constantly make you think "maybe the compiler isn't serious about this diagnostic, let me rebuild".
I do like this idea, as a temporary partial solution to a problem. As an example, here is how I usually work with Haxe:
- Build cache disabled because I can't really trust the builds as they can have errors, if it builds at all.
- Diagnostics/completion usually won't work reliably, to a point where I don't even bother restarting the server and just work without it.
- And instead I keep an extra CLI window where I do pure
haxe build.hxmlbuilds without any server, and fix the errors based on that. - Sometimes I do use VSCode build, as it's usable when cache is disabled, but often CLI is more readable for me.
I suppose if this got implemented, I could just keep using VSCode builds, with the diagnostics working slightly better as the cache would keep getting replaced with correct data.
Since there seems to be some activity regarding the compilation server, I thought I might try to revive this conversation a bit.
I don't know... diagnostics is just building with extra steps and separating these two seems questionable. You could get diagnostics for something which then doesn't show up in the actual build, which would constantly make you think "maybe the compiler isn't serious about this diagnostic, let me rebuild".
If I understand what you're saying, I think the solution would be to rerun diagnostics after a successful rebuild, which should be cheap, because the cache was just freshly populated. Or well, the old diagnostics issue could be left untouched and would update next time when diagnostics would normally run.
Let me try to illustrate the user perspective, which consists of two options:
- Compilation server disabled. IDE provides services, but they degrade over time, up to the point where one is stuck in a plain text editor (with syntax highlighting and fancy shortcuts, but still). At some point one will restart the server and everything's fluffy again, for a while.
- Compilation server enabled. Builds are fast, but somewhat non-deterministic and fragile. If one manages to blow up the server with some "smart" trick, it won't even compile anymore. This point takes longer to reach and IDE services only decrease very slightly between builds. But when the server is finally gone, one must restart (and since at this point one can't even verify whether or not the build is broken, that can fail).
I'd like to think that the hybrid approach offers a good third tradeoff. When I build, it's slower than an incremental build, but it's full, clean, deterministic build, that produces the same output as the CI (this is not always necessary, but at times quite useful). During a successful clean build, the compiler has coherent and up-to-date information about the code, which is simply thrown away, while I would like to be fed back into the IDE services.
Basically, if I run an actual build instead of an IDE request, the build could be made in a fresh context and then if that succeeds said context could be committed to the cache. I don't know if diagnostics has any extra information that could be lost at this point, but if so, it could be repopulated from either the previous cache state or by rerunning diagnostics on the new cache state (which should be relatively cheap, because the cache is known to be hot and thus there's no need to check for modification).