Skip to content

Commit 7fc0b8b

Browse files
Make the language server accept config nested under the "effekt" key (#975)
Server-side support for effekt-lang/effekt-vscode#71.
1 parent c53c05c commit 7fc0b8b

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

effekt/jvm/src/main/scala/effekt/Server.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,17 @@ class Server(config: EffektConfig, compileOnChange: Boolean=false) extends Langu
502502
//
503503

504504
def didChangeConfiguration(params: DidChangeConfigurationParams): Unit = {
505-
this.settings = params.getSettings.asInstanceOf[JsonElement].getAsJsonObject
505+
// The configuration can be sent as a flat JSON object `{ "showIR": "core", ... }` or
506+
// nested under an "effekt" key `{ "effekt": { "showIR": "core", ... } }`
507+
// The former is sent by the VSCode extension for `initializationOptions`,
508+
// the latter by newer extension versions for `workspace/didChangeConfiguration`.
509+
val newSettings = params.getSettings.asInstanceOf[JsonElement].getAsJsonObject
510+
this.settings = newSettings;
511+
if (newSettings == null) return
512+
val effektSection = newSettings.get("effekt")
513+
if (effektSection != null) {
514+
this.settings = effektSection
515+
}
506516
}
507517

508518
def didChangeWatchedFiles(params: DidChangeWatchedFilesParams): Unit = {}

effekt/jvm/src/test/scala/effekt/LSPTests.scala

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,57 @@ class LSPTests extends FunSuite {
774774
}
775775
}
776776

777+
test("When configuration changes, server should publish requested IR") {
778+
withClientAndServer { (client, server) =>
779+
val source =
780+
raw"""
781+
|val foo = 42
782+
|"""
783+
val textDoc = new TextDocumentItem("file://path/to/test.effekt", "effekt", 0, source.stripMargin)
784+
val initializeParams = new InitializeParams()
785+
val initializationOptions = """{"showIR": "source"}"""
786+
initializeParams.setInitializationOptions(JsonParser.parseString(initializationOptions))
787+
server.initialize(initializeParams).get()
788+
789+
val didOpenParams = new DidOpenTextDocumentParams()
790+
didOpenParams.setTextDocument(helloWorld)
791+
server.getTextDocumentService().didOpen(didOpenParams)
792+
793+
// Receive the initial IR
794+
assertEquals(client.receivedIR().length, 1)
795+
796+
val configParams = new DidChangeConfigurationParams()
797+
// When configuring the VSCode language client with `synchronize: { configurationSection: 'effekt' }`,
798+
// we get a `DidChangeConfigurationParams` with the configuration nested under the "effekt" key.
799+
val settings: JsonElement = JsonParser.parseString("""{"effekt": {"showIR": "core", "showTree": true}}""")
800+
configParams.setSettings(settings)
801+
server.getWorkspaceService().didChangeConfiguration(configParams)
802+
803+
// Send a didSave event to trigger recompilation and IR publication
804+
val didSaveParams = new DidSaveTextDocumentParams()
805+
didSaveParams.setTextDocument(textDoc.versionedTextDocumentIdentifier)
806+
didSaveParams.setText(textDoc.getText)
807+
server.getTextDocumentService().didSave(didSaveParams)
808+
809+
val expectedIRContents =
810+
raw"""ModuleDecl(
811+
| test,
812+
| List(effekt, option, list, result, exception, array, string, ref),
813+
| Nil,
814+
| Nil,
815+
| List(
816+
| Val(foo_whatever, Data(Int_whatever, Nil), Return(Literal(42, Data(Int_whatever, Nil))))
817+
| ),
818+
| List(foo_whatever)
819+
|)""".stripMargin
820+
821+
val receivedIRContent = client.receivedIR()
822+
assertEquals(receivedIRContent.length, 1)
823+
val fixedReceivedIR = receivedIRContent.head.content.replaceAll("Int_\\d+", "Int_whatever").replaceAll("foo_\\d+", "foo_whatever")
824+
assertEquals(fixedReceivedIR, expectedIRContents)
825+
}
826+
}
827+
777828
// Text document DSL
778829
//
779830
//

0 commit comments

Comments
 (0)