Skip to content

moved initializeParams to serverOptions class #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions src/main/java/software/amazon/smithy/lsp/ServerOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.smithy.lsp;

//import javax.print.attribute.standard.Severity;
import com.google.gson.JsonObject;
import java.util.Arrays;
import java.util.Optional;
import software.amazon.smithy.model.validation.Severity;

public final class ServerOptions {
private Severity minimumSeverity = Severity.WARNING;
private boolean onlyReloadOnSave = false;

private ServerOptions(Builder builder) {
this.minimumSeverity = builder.minimumSeverity;
this.onlyReloadOnSave = builder.onlyReloadOnSave;
}

public Severity getMinimumSeverity() {
return this.minimumSeverity;
}

public Boolean getOnlyReloadOnSave() {
return this.onlyReloadOnSave;
}

public static Builder builder() {
return new Builder();
}

/**
* Creates a ServerOptions instance from the initialization options provided by the client.
* Parses and validates configuration settings from the initialization parameters.
*
* @param initializationOptions The raw initialization options object from the client,
* expected to be a JsonObject containing server configurations
* @param client The language client used for logging configuration status and errors
* @return A new {@code ServerOptions} instance with parsed configuration values
**/
public static ServerOptions fromInitializeParams(Object initializationOptions, SmithyLanguageClient client) {
// from InitializeParams
Builder builder = builder();
if (initializationOptions instanceof JsonObject jsonObject) {
if (jsonObject.has("diagnostics.minimumSeverity")) {
String configuredMinimumSeverity = jsonObject.get("diagnostics.minimumSeverity").getAsString();
Optional<Severity> severity = Severity.fromString(configuredMinimumSeverity);
if (severity.isPresent()) {
builder.setMinimumSeverity(severity.get());
} else {
client.error(String.format("""
Invalid value for 'diagnostics.minimumSeverity': %s.
Must be one of %s.""", configuredMinimumSeverity, Arrays.toString(Severity.values())));
}
}
if (jsonObject.has("onlyReloadOnSave")) {
builder.setOnlyReloadOnSave(jsonObject.get("onlyReloadOnSave").getAsBoolean());
client.info("Configured only reload on save: " + builder.onlyReloadOnSave);
}
}
return builder.build();
}

public static class Builder {
private Severity minimumSeverity = Severity.WARNING;
private boolean onlyReloadOnSave = false;

public Builder setMinimumSeverity(Severity minimumSeverity) {
this.minimumSeverity = minimumSeverity;
return this;
}

public Builder setOnlyReloadOnSave(boolean onlyReloadOnSave) {
this.onlyReloadOnSave = onlyReloadOnSave;
return this;
}

public ServerOptions build() {
return new ServerOptions(this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@

import static java.util.concurrent.CompletableFuture.completedFuture;

import com.google.gson.JsonObject;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -148,9 +146,8 @@ public class SmithyLanguageServer implements

private SmithyLanguageClient client;
private final ServerState state = new ServerState();
private Severity minimumSeverity = Severity.WARNING;
private boolean onlyReloadOnSave = false;
private ClientCapabilities clientCapabilities;
private ServerOptions serverOptions;

SmithyLanguageServer() {
}
Expand Down Expand Up @@ -186,25 +183,11 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
.flatMap(ProcessHandle::of)
.ifPresent(processHandle -> processHandle.onExit().thenRun(this::exit));

// TODO: Replace with a Gson Type Adapter if more config options are added beyond `logToFile`.
Object initializationOptions = params.getInitializationOptions();
if (initializationOptions instanceof JsonObject jsonObject) {
if (jsonObject.has("diagnostics.minimumSeverity")) {
String configuredMinimumSeverity = jsonObject.get("diagnostics.minimumSeverity").getAsString();
Optional<Severity> severity = Severity.fromString(configuredMinimumSeverity);
if (severity.isPresent()) {
this.minimumSeverity = severity.get();
} else {
client.error(String.format("""
Invalid value for 'diagnostics.minimumSeverity': %s.
Must be one of %s.""", configuredMinimumSeverity, Arrays.toString(Severity.values())));
}
}
if (jsonObject.has("onlyReloadOnSave")) {
this.onlyReloadOnSave = jsonObject.get("onlyReloadOnSave").getAsBoolean();
client.info("Configured only reload on save: " + this.onlyReloadOnSave);
}
}
// Alternate options code
this.serverOptions = ServerOptions.fromInitializeParams(initializationOptions, client);

// TODO: Replace with a Gson Type Adapter if more config options are added beyond `logToFile`.

if (params.getWorkspaceFolders() != null && !params.getWorkspaceFolders().isEmpty()) {
Either<String, Integer> workDoneProgressToken = params.getWorkDoneToken();
Expand Down Expand Up @@ -521,7 +504,7 @@ public void didChange(DidChangeTextDocumentParams params) {
return;
}

if (!onlyReloadOnSave) {
if (!this.serverOptions.getOnlyReloadOnSave()) {
Project project = projectAndFile.project();

// TODO: A consequence of this is that any existing validation events are cleared, which
Expand Down Expand Up @@ -732,7 +715,7 @@ public CompletableFuture<Hover> hover(HoverParams params) {
Project project = projectAndFile.project();

// TODO: Abstract away passing minimum severity
Hover hover = new HoverHandler(project, smithyFile).handle(params, minimumSeverity);
Hover hover = new HoverHandler(project, smithyFile).handle(params, this.serverOptions.getMinimumSeverity());
return completedFuture(hover);
}

Expand Down Expand Up @@ -805,7 +788,8 @@ List<Diagnostic> getFileDiagnostics(String uri) {
String path = LspAdapter.toPath(uri);

List<Diagnostic> diagnostics = project.modelResult().getValidationEvents().stream()
.filter(validationEvent -> validationEvent.getSeverity().compareTo(minimumSeverity) >= 0)
.filter(validationEvent -> validationEvent.getSeverity().compareTo(
this.serverOptions.getMinimumSeverity()) >= 0)
.filter(validationEvent -> validationEvent.getSourceLocation().getFilename().equals(path))
.map(validationEvent -> toDiagnostic(validationEvent, smithyFile))
.collect(Collectors.toCollection(ArrayList::new));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.LengthTrait;
import software.amazon.smithy.model.validation.Severity;

public class SmithyLanguageServerTest {
@Test
Expand Down Expand Up @@ -2561,6 +2562,43 @@ public void reloadsProjectOnBuildFileSave() {
Map.of()));
}

@Test
public void testCustomServerOptions() {
ServerOptions options = ServerOptions.builder()
.setMinimumSeverity(Severity.NOTE)
.setOnlyReloadOnSave(true)
.build();

assertThat(options.getMinimumSeverity(), equalTo(Severity.NOTE));
assertThat(options.getOnlyReloadOnSave(), equalTo(true));
}

@Test
public void testFromInitializeParamsWithValidOptions() {
StubClient client = new StubClient();
JsonObject opts = new JsonObject();
opts.add("diagnostics.minimumSeverity", new JsonPrimitive("ERROR"));
opts.add("onlyReloadOnSave", new JsonPrimitive(true));

ServerOptions options = ServerOptions.fromInitializeParams(opts, new SmithyLanguageClient(client));

assertThat(options.getMinimumSeverity(), equalTo(Severity.ERROR));
assertThat(options.getOnlyReloadOnSave(), equalTo(true));
}

@Test
public void testFromInitializeParamsWithPartialOptions() {
StubClient client = new StubClient();
JsonObject opts = new JsonObject();
opts.add("onlyReloadOnSave", new JsonPrimitive(true));
// Not setting minimumSeverity

ServerOptions options = ServerOptions.fromInitializeParams(opts, new SmithyLanguageClient(client));

assertThat(options.getMinimumSeverity(), equalTo(Severity.WARNING)); // Default value
assertThat(options.getOnlyReloadOnSave(), equalTo(true)); // Explicitly set value
}

private void assertServerState(SmithyLanguageServer server, ServerState expected) {
ServerState actual = ServerState.from(server);
assertThat(actual, equalTo(expected));
Expand Down
Loading