From e4dc4c1e15b6535f64c93675ed8b43eb4665db0f Mon Sep 17 00:00:00 2001 From: David Francoeur Date: Thu, 17 Nov 2022 11:48:09 -0500 Subject: [PATCH 1/2] Improve the debugging experience Add a `lspJavaOpt` setting to forward java-opt to coursier. This allows different thing, but in this context it was to a add a debug options. I've also added the `m2Local` coursier repository because coursier does not support it by default anymore and gradle publishes there. So if you use gradle, rather than mill, in the smithy-language-server then you won't find locally published jar. It was my mistake, I should never have removed it in the first place. --- package.json | 5 +++++ src/extension.ts | 23 +++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 7a4e934..3980c86 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,11 @@ "type": "string", "default": "com.disneystreaming.smithy:smithy-language-server", "description": "Language Server JAR to power the extension" + }, + "smithyLsp.lspJavaOpt": { + "scope": "window", + "type": "string", + "description": "Java options to be forwarded to the Language Server launch. Options should be separated by spaces." } } }, diff --git a/src/extension.ts b/src/extension.ts index 0e63bec..5c21d01 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -58,6 +58,14 @@ export function activate(context: ExtensionContext) { .getConfiguration("smithyLsp") .get("lspCoordinates", "`"); + const lspJavaOpt: string | undefined = vscode.workspace + .getConfiguration("smithyLsp") + .get("lspJavaOpt"); + + const javaOptions: Array = lspJavaOpt + ? lspJavaOpt.split(" ").flatMap((o) => ["--java-opt", o]) + : []; + return Promise.all([ getCoursierExecutable(context.globalStoragePath), parseSmithyBuild(), @@ -69,10 +77,17 @@ export function activate(context: ExtensionContext) { ? projectLanguageServerArtifact : `${lspCoordinates}:${version}`; - const startServer = { - command: csBinaryPath, - args: ["launch", finalLanguageServerArtifact, "--ttl", "1h", "--", "0"], - }; + const launcher = ["launch", finalLanguageServerArtifact]; + // m2Local is relevant when `gradle` is used to publish locally + // coursier default resolvers are ivy2Local and maven central at the time of writing + const coursierOptions = ["--ttl", "1h", "--repository", "m2Local"].concat( + javaOptions + ); + const split = ["--"]; + const lspArguments = ["0"]; // port 0 means we use std in/out to exchange with the language server + const args = launcher.concat(coursierOptions, split, lspArguments); + + const startServer = { command: csBinaryPath, args }; client = new LanguageClient( "smithyLsp", From 5279b0a519e511eaafe8b172e5e688f62de02d5b Mon Sep 17 00:00:00 2001 From: David Francoeur Date: Thu, 17 Nov 2022 12:04:51 -0500 Subject: [PATCH 2/2] Document the debugging process --- README.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/README.md b/README.md index 756717a..5362bc1 100644 --- a/README.md +++ b/README.md @@ -37,3 +37,57 @@ An example Smithy build file looks like this: "mavenRepositories": ["https://full.url.to.your.mavenrepository.tld"] } ``` + +## Debugging guide + +This guide is to help you work on the VS Code extension along with the [Smithy Language Server](https://github.com/awslabs/smithy-language-server). + +### Editor + +We recommend that you use VS Code to debug the extension. The support exists out of the box. + +### Debuging the extension + +To start a debug session: + +1. Open this project in VS Code +2. In a terminal, launch: `yarn && yarn run watch`. This will start a compile watch loop for the extension sources +3. Open the `src/extension.ts` file and press F5. this launches a new VS Code window with the extension installed and in debug mode. +4. Add debug point in the extesion source. + +Note that this extension activates when you open a Smithy file. So to trigger the execution, once you press F5, make sure to open a Smithy file in the `Extension Development Host` VS Code window. + +#### Debugging the language server + +If you believe the issue exists in the language server rather than the extension itself, you may want to use a Java debugger and attach to the language server. + +1. Checkout the code at the link above and cd into it +2. Open the code in your IDE, we suggest IntelliJ because it's the best in class with Java +3. Update the version number in `./VERSION`, and append `-SNAPSHOT`, eg: `0.2.1-SNAPSHOT` +4. In a terminal, launch: `./gradlew -t publishToMavenLocal`. this will publish to your local maven repository (usually somewhere under `~/.m2`) with the following artifact coordinates: `software.amazon.smithy:smithy-language-server:$VERSION` +5. Configure your IDE to use the new language server artifact: + 1. Extension settings: change the `lspCoordinates` value + 2. Per project, via a `smithy-build.json` file that contains: `{"languageServer":"software.amazon.smithy:smithy-language-server:0.2.1-SNAPSHOT"}` + +At this point, you should be able to run custom code within the language-server to work on your issue. To have good visibility though, you may want to use `System.out.println`. **Don't**. Instead, use `LspLog.println("message")` and your message will be printed to a file in the directory where the extension is opened. See below for more information on why you should not print to standard out. + +If you want to start debugging the JVM, change the Extension settings `lspJavaOpts` and set: `-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005,quiet=y`. The important bit here is: `quiet=y`, because as I've said already, it's important to avoid printing to standard out. + +With that, you can reload your VS Code window. At that point, when the extension starts the language server with a debug agent and you'll be able to connect on port `5005`. You can also use `suspend=y` as opposed to `suspend=n` if you have to troubleshoot something in the startup of the language server. + +### Known errors: + +Error in `Log(Extension Host)` channel: + +``` +2022-11-17 10:33:51.138 [error] Error: Header must provide a Content-Length property. + at StreamMessageReader.onData (/Users/David.Francoeur/.vscode/extensions/disneystreaming.smithy-0.0.0/node_modules/vscode-jsonrpc/lib/messageReader.js:163:27) + at Socket. (/Users/David.Francoeur/.vscode/extensions/disneystreaming.smithy-0.0.0/node_modules/vscode-jsonrpc/lib/messageReader.js:148:18) + at Socket.emit (node:events:526:28) + at addChunk (node:internal/streams/readable:315:12) + at readableAddChunk (node:internal/streams/readable:289:9) + at Readable.push (node:internal/streams/readable:228:10) + at Pipe.onStreamRead (node:internal/stream_base_commons:190:23) +``` + +This happens because the extension exchange with the language server via std in/out of the child process. If any of the code that runs in the language server prints to the standard out, VS Code will complain (unless it is specifically formatted that way). \ No newline at end of file