Language Server for Inform 6 (+clients for eclipse and vscode)

Dear IF community! I’ve decided to go open source with my homegrown project that’s been occupying me for some months now. It is a Language Server implementation for Inform 6. It is right now in a really early alpha stage but I’ve come to the conclusion that it might already be useful in its current state for anyone working with Inform 6.

The project is written in the XText framework and is mainly served for eclipse. GitHub - toerob/ls4inform6: Language server implementation for the Inform 6 language. But I’ve also written a bare basic client implementation for visual studio code, found at:
GitHub - toerob/inf6langtools: LSP vscode client for the inform6 language.

Installation instructions for both are found in the readme file.

The really nice thing with a Language Server is that it will only require a thin client (or sometimes none at all) to be fully working in any Editor supporting the Language Server Protocol. (The ones providing this can be found here: Tools supporting the LSP)

I’m interested in hearing what features you might suggest and if there are any collaborators wanting to join in. Writing grammar is very time consuming and at the present stage the plugin is more of an outliner with some pretty nice bonus effects, such as “go to references” on direction properties and class names. (In eclipse it is also possible to navigate via include statements to other files). Plus that it checks the overall syntax of your written code.

Bear in mind though that the parser is a of a “fuzzy” kind, that means it in this case that it won’t parse (to any great extend at least) expressions written inside global or local routines. And therefore only performs analysis on broader code structure. A full parser is something I wish to incorporate further ahead. It won’t happen anytime soon though. Also bear in mind that there are some trickiness involving preprocessed directives. It will have a problem parsing conditional properties inside objects as it will for now simply ignore such rows completely. Those are mostly found in the library files and usually not the game file itself.

Please let me know what you think!

Tomas

6 Likes

That’s great! (Guess I won’t have to write a language server myself, after all!)

I don’t have time to look at your work right now, but I’ll do as soon as possible. I suppose you don’t mind if I include it in my Inform 6 VS Code extension? (If it’s production-ready, of course.)

(I would have prefered a language server written in JavaScript/TypeScript, so that users do not need to have Java installed, but well. I see that xText is based on ANTLR, and that ANTLR can output JavaScript. Do you know if there is a way to have your work output JS? That would be great.)

That’s fine as long as you mention it (at least by including the MIT License file) There’s already a vscode extension (inf6langtools) out there that co-exists with your extension so if you decide to incorporate the LS I think it’s worth mentioning somewhere that if the users have installed both of the extensions it will also analyze the code twice. (And have an additional outliner.) My main objective now will actually be to create thin clients for the most popular editors before improving the server so it is available everywhere.

Regarding “production ready”… It’s more of a pre-alpha and I hope to emphasize that with the 0.5.0 version, but I do believe it is stable (although pretty rudimentary) for what most game writers do with it but there will of course be edge cases where it can’t parse and report an error where the compiler will happily compile. I made it available first and foremost so it can incrementally become more capable and to speed up the bug discovery but also to keep me motivated.

About the JavaScript question, I do believe that is fully possible since xtext supports crafting web editors that run on javascript but I don’t have any further insight in this right now.

I tried the VS Code extension, but couldn’t manage to make it work. I’m not at all familiar with Java (and I suppose it’s the case of a lot of Inform 6 authors) so I found it quite difficult to setup.

The README states that the JRE 10 is required, but a search on the web only brings up the old java.com site that only offers version 8. With more investigation I found out Oracle’s site, which also only offers a JRE download for version 8. To have a more recent version, it seems you have to download the JDK instead (and I’m totally fine with that, but it’s not obvious since the README states it’s the JRE that’s required, not the JDK).

But then there’s also the choice between Oracle and OpenJDK. I first tried the latter because I favour open source. I downloaded the latest version (15.0.2). By looking at the code of your extension, I found out that you have to set the JAVA_HOME environment variable to the path of the JDK folder, which is not obvious if you don’t know it. (Although maybe the installer from Oracle can set it for you?)

So far, everything is fine. The problem is that I get several errors of this kind in the output panel of VS Code:

Internal error: org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException: Cannot invoke "String.startsWith(String)" because "importURI" is null

I tried the version distributed by Oracle, too, and got the same error. I tried with OpenJDK version 10, and I still got an error, but a different one, I think.

Would you care to help a Java newbie? (And thanks for reading this long message!)

Thank you for this feedback! It’s really valuable! JRE/JDK, mistake on my behalf, it doesn’t matter, as long as it can run the launcher.jar file (LSP server) that’s included in the extension you should be fine. (JRE is just all that is necessary for having a runtime environment, a slimmed down version of the development kit that includes the libraries, tools etc that aren’t necessary for the vm when just executing programs but needed when compiling.)

About versions of the JVM, I’ve tried a couple of them, mostly with Open JDK 11 or Azul Zulu 14 I believe.

If running on linux or mac I highly recommend installing the program “sdkman” to easily install and switch between java versions (if you didn’t know about it already).

I’ll update the readme for the extension both about this and the JAVA_HOME environment variable. I didn’t think of it since it is so common for me to set it, but you’re absolutely right. Perhaps there’s not a majority of people that knows inform6 out there that also knows java (and they shouldn’t need to).

About the nullpointer exception you are having. This is at least suggesting that the LSP is up and running. It seems to have a problem with an include statement. Could you provide an example in order to reproduce this? Does it work fine if you just create an example of for instance “cloak of darkness” Cloak of Darkness: Inform or is it happening there as well? I’m especially interested in how the Include statement could end up null. (I should put in a null guard there for sure, but I’m also interested in letting the user know what not to do also in case it happens.)

I quickly understood that the JRE is included in the JDK, but it’s a bit confusing because there is no standalone download (i.e. without the JDK) for Java JRE 10. The first result when searching “java jre 10” on the web brings up the old page to download version 8 of the JRE.

Regarding the null pointer, you’re right, it was because of the Inform 6 file I opened. I was so focused on making Java work that I only tried on the file I already had opened, which is a file for testing syntax highlighting, and which contains a lot of invalid Inform 6. (Although ideally the language server would catch any error and report cleanly in that case.)

Everything works on a “true” Inform 6 file.

However, on the projects I tried, a lot a false positives are reported as errors, so the language server is not really usable in its current state. :slightly_frowning_face: (Except maybe on simple projects.)

Do you accept pull requests? If I have time, I could add things to improve the UX of the VS Code extension. For example, a setting to allow a custom path to the Java executable (instead of using the JAVA_HOME environment variable), or a setting to disable error reporting (so that users can still use the extension for the outline, without having all the false errors reported).

Well, as I wrote in the readme, it’s mostly usable as an outliner at this stage and having some goto references. At least those things should work in most projects.

Since the parsing is only of a fuzzy parsing type it doesn’t evaluate expressions, so anything inside routines/methods are skipped during the parsing. Therefore it cannot be expected to report properly on code errors yet. I released it as a pre-alpha as I thought I could be usable for people to have at least an outliner for inform 6. More features can be added on incrementally if there’s an interest for it.

What kind of false positives does it report on? It should be mostly silent unless it cannot find references (so if there’s a missing

!% +include_path=…/…/lib/

in the beginning of the file it might be reporting on symbols not found due to that for example. But maybe there’s more kinds of reporting.

Anyone is most welcome to add issues /suggestions in the GitHub repo or to do PR:s.

So if you don’t have time to do the coding just raise an issue and I’ll have a go at it myself.

OK so most of the errors are in fact syntax constructs that are not handled by the language server yet. For example:

  • It thinks IFDEF MY_CONSTANT; (without a leading #) is an object declaration of class IFDEF.
  • It doesn’t know the fact that directives are case-insensitive: global x = 0; causes an error, but not Global x = 0;.
  • If an attribute is declared in one file but used in another file that is included in the first one, it thinks the attribute doesn’t exist in that second file.
  • If the standard library is in the currently opened workspace, the language detects a lot (several hundreds) errors in it. I think it’s because the library uses a lot of “non-standard” or uncommon syntax.

I’ll look at these errors in more details and write some bug reports.

Thanks! I’ll fix those you mentioned right away.