intellij-community
intellij-community copied to clipboard
Make LineMarkersPass constructor public
This would simplify life for plugin-writers and would allow them not to use workarounds.
Hello. LineMarkersPass is extremely internal class. Instantiating it in plugins is undesirable. What do you need to do so hardcore that the LineMarkerProvider is insufficient?
We need to update line markers after a custom highlighting pass is completed, but there is no way to execute our highlighting pass after the line markers pass. We could try to rerun the analysis, but to do this, we need to mark the file dirty and this would mean that other highlighting passes also will be executed the second time, which is not desirable. Anyway, invoking the line marker pass directly seems to be a more sensible solution and it works just fine.
I suggest to do DaemonCodeAnalyzer.restart()
when your model (on which your line markers are based) is changed. UNfortunately, instantiating and running LIneMarkerPass manually can lead to internal data structures corruption because the passes are running in highly concurrent and interruptible environment.
If we do that, this would mean that all passes will be restarted including ours. This means that it will be executed twice and this is not desirable since it is somewhat expensive. We could try to cache the result or do something similar, but this is hard to implement because of the highly concurrent and iterruptible environment you mentioned. It seems much easier just to invoke LineMarkersPass directly from our pass after it completes the required calculations. Since we're invoking one pass from another, I don't think this could lead to any problems you mentioned. I've been testing this implementation for quite some time and never get any problems.
If you need to run these passes twice I guess it means that your line markers pass depends on the data produced by the other pass. Which actually is not a good thing because highlighting passes should be independent because they can run in not-specified order (or even concurrently). Instead, I think it's better to organize your code such that both passes depend on one other data source (let's call it the "model"). This way, your custom highlighting pass runs, queries the model and highlights things accordingly. Meanwhile, your line marker pass runs, queries the same model and highlights line markers. When the model changes, you call daemonCodeAnalyzer.restart()
. No passes should run twice.
Yes, our pass updates the "model" as you call it. You suggest that it should not do that. But we need to update it after every PSI change. I guess I can subscribe to this event and implement this logic manually (instead of relying on the highlight pass infrastructure). This still would mean that every highlighting pass is executed twice after every PSI change (once immediately and once after our process completes and invokes daemonCodeAnalyzer.restart()
). This would not be a big problem since highlighting passes would only read the "model" and not do any expensive calculations, but still this seems somewhat awkward. Moreover, I don't see the point in rewriting working code.