melt-umn / silver

An attribute grammar-based programming language for composable language extensions
http://melt.cs.umn.edu/silver/
GNU Lesser General Public License v3.0
59 stars 7 forks source link

Unexpected behavior when language server loads an extended compiler jar built against a different version of the host language #731

Closed krame505 closed 1 year ago

krame505 commented 1 year ago

Currently, the Silver LSP server implementation is statically linked against the compiled Silver compiler and runtime. We also support using extended versions of Silver by dynamically loading an alternate Silver compiler jar (with an extended version of the parser.) Note that we essentially have 2 copies of the Silver host language - the version that the LSP server was built against, and the version in the jar being dynamically loaded. The JVM cannot support multiple versions of a class loaded at once - so if we load a new, extended version of the Silver compiler from a jar, we will only load classes for productions, attributes, etc. that are added in the extension.

This leads to unexpected behavior when the extended Silver compiler jar is built from a different version of the host language than what the LSP server was built against. For example if a production changes signature in the host language, and a loaded extension tries to call a host-language production that has a different signature in the loaded jar, it will instead see the older version of the host production's class, and result in an incomprehensible internal runtime error.

The fix for this seems to be to load the extended jar when the server starts up, before calling the various init() methods in SilverLanguageServer.initialize, instead of doing it later on when the settings are changed (it seems that there is a way to pass various configuration settings through the InitializeParams.) This should cause all the needed dependencies of the Silver compiler to be consistently loaded from the specified jar, before the default class loader tries to load the versions of them that were included in the LSP server jar. Doing it this way will also address the slightly-annoying bug where the language server starts to run using the non-extended parser and reports syntax errors that disappear after startup.

Note that more dramatic changes to the Silver runtime or any Silver methods that are directly called from the language server implementation will still cause this sort of issue - however in these situations there would also be changes needed in the language server itself, and an updated version would need to be installed anyway.

I'm assigning myself to this issue - it's honestly probably best if I take a crack at this refactoring, instead of making Allie become acquainted with the intricacies of Java class loaders.