Skip to content

Commit

Permalink
Use newer java features (#161)
Browse files Browse the repository at this point in the history
Refactors various things to make use of newer java features, including
record classes, text blocks, and new APIs.
  • Loading branch information
milesziemer authored Sep 7, 2024
1 parent 5ef6b14 commit ac2eda8
Show file tree
Hide file tree
Showing 38 changed files with 864 additions and 957 deletions.
62 changes: 27 additions & 35 deletions src/main/java/software/amazon/smithy/lsp/SmithyLanguageServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@
import software.amazon.smithy.lsp.document.Document;
import software.amazon.smithy.lsp.document.DocumentParser;
import software.amazon.smithy.lsp.document.DocumentShape;
import software.amazon.smithy.lsp.ext.serverstatus.OpenProject;
import software.amazon.smithy.lsp.ext.serverstatus.ServerStatus;
import software.amazon.smithy.lsp.ext.OpenProject;
import software.amazon.smithy.lsp.ext.SelectorParams;
import software.amazon.smithy.lsp.ext.ServerStatus;
import software.amazon.smithy.lsp.ext.SmithyProtocolExtensions;
import software.amazon.smithy.lsp.handler.CompletionHandler;
import software.amazon.smithy.lsp.handler.DefinitionHandler;
import software.amazon.smithy.lsp.handler.FileWatcherRegistrationHandler;
Expand Down Expand Up @@ -191,25 +193,22 @@ public void connect(LanguageClient client) {
public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
LOGGER.finest("Initialize");

// TODO: Use this to manage shutdown if the parent process exits, after upgrading jdk
// Optional.ofNullable(params.getProcessId())
// .flatMap(ProcessHandle::of)
// .ifPresent(processHandle -> {
// processHandle.onExit().thenRun(this::exit);
// });
Optional.ofNullable(params.getProcessId())
.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 jsonObject = (JsonObject) initializationOptions;
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("Invalid value for 'diagnostics.minimumSeverity': " + configuredMinimumSeverity
+ ".\nMust be one of " + Arrays.toString(Severity.values()));
client.error(String.format("""
Invalid value for 'diagnostics.minimumSeverity': %s.
Must be one of %s.""", configuredMinimumSeverity, Arrays.toString(Severity.values())));
}
}
if (jsonObject.has("onlyReloadOnSave")) {
Expand Down Expand Up @@ -365,7 +364,7 @@ public CompletableFuture<List<? extends Location>> selectorCommand(SelectorParam
LOGGER.finest("SelectorCommand");
Selector selector;
try {
selector = Selector.parse(selectorParams.getExpression());
selector = Selector.parse(selectorParams.expression());
} catch (Exception e) {
LOGGER.info("Invalid selector");
// TODO: Respond with error somehow
Expand Down Expand Up @@ -513,14 +512,15 @@ public void didChange(DidChangeTextDocumentParams params) {
}

if (!onlyReloadOnSave) {
// TODO: A consequence of this is that any existing validation events are cleared, which
// is kinda annoying.
// Report any parse/shape/trait loading errors
Project project = projects.getProject(uri);
if (project == null) {
client.unknownFileError(uri, "change");
return;
}

// TODO: A consequence of this is that any existing validation events are cleared, which
// is kinda annoying.
// Report any parse/shape/trait loading errors
CompletableFuture<Void> future = CompletableFuture
.runAsync(() -> project.updateModelWithoutValidating(uri))
.thenComposeAsync(unused -> sendFileDiagnostics(uri));
Expand Down Expand Up @@ -628,10 +628,6 @@ public CompletableFuture<CompletionItem> resolveCompletionItem(CompletionItem un
SmithyFile smithyFile = project.getSmithyFile(uri);

return CompletableFutures.computeAsync((cc) -> {
if (smithyFile == null) {
return Collections.emptyList();
}

Collection<DocumentShape> documentShapes = smithyFile.documentShapes();
if (documentShapes.isEmpty()) {
return Collections.emptyList();
Expand All @@ -643,10 +639,6 @@ public CompletableFuture<CompletionItem> resolveCompletionItem(CompletionItem un

List<Either<SymbolInformation, DocumentSymbol>> documentSymbols = new ArrayList<>(documentShapes.size());
for (DocumentShape documentShape : documentShapes) {
if (cc.isCanceled()) {
client.info("canceled document symbols");
return Collections.emptyList();
}
SymbolKind symbolKind;
switch (documentShape.kind()) {
case Inline:
Expand All @@ -662,6 +654,11 @@ public CompletableFuture<CompletionItem> resolveCompletionItem(CompletionItem un
symbolKind = SymbolKind.Class;
break;
}

// Check before copying shapeName, which is actually a reference to the underlying document, and may
// be changed.
cc.checkCanceled();

String symbolName = documentShape.shapeName().toString();
if (symbolName.isEmpty()) {
LOGGER.warning("[DocumentSymbols] Empty shape name for " + documentShape);
Expand Down Expand Up @@ -813,16 +810,11 @@ private static Diagnostic toDiagnostic(ValidationEvent validationEvent, SmithyFi
}

private static DiagnosticSeverity toDiagnosticSeverity(Severity severity) {
switch (severity) {
case ERROR:
case DANGER:
return DiagnosticSeverity.Error;
case WARNING:
return DiagnosticSeverity.Warning;
case NOTE:
return DiagnosticSeverity.Information;
default:
return DiagnosticSeverity.Hint;
}
return switch (severity) {
case ERROR, DANGER -> DiagnosticSeverity.Error;
case WARNING -> DiagnosticSeverity.Warning;
case NOTE -> DiagnosticSeverity.Information;
default -> DiagnosticSeverity.Hint;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@

package software.amazon.smithy.lsp.codeactions;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.WorkspaceEdit;
import software.amazon.smithy.lsp.protocol.LspAdapter;

public final class DefineVersionCodeAction {
private static final int DEFAULT_VERSION = 1;
Expand All @@ -42,10 +40,9 @@ public static CodeAction build(String fileUri) {
codeAction.setKind(SmithyCodeActions.SMITHY_DEFINE_VERSION);
WorkspaceEdit wEdit = new WorkspaceEdit();
TextEdit edit = new TextEdit(
new Range(new Position(0, 0), new Position(0, 0)),
"$version: \"" + DEFAULT_VERSION + "\"\n\n"
);
Map<String, List<TextEdit>> changes = Collections.singletonMap(fileUri, Collections.singletonList(edit));
LspAdapter.origin(),
String.format("$version: \"%s\"%n%n", DEFAULT_VERSION));
Map<String, List<TextEdit>> changes = Map.of(fileUri, List.of(edit));
wEdit.setChanges(changes);
codeAction.setEdit(wEdit);
return codeAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,8 @@ public static List<CodeAction> versionCodeActions(CodeActionParams params) {
}
Optional<Diagnostic> updateVersionDiagnostic = params.getContext().getDiagnostics().stream()
.filter(diagnosticCodePredicate(SmithyDiagnostics.UPDATE_VERSION)).findFirst();
if (updateVersionDiagnostic.isPresent()) {
actions.add(
UpdateVersionCodeAction.build(fileUri, updateVersionDiagnostic.get().getRange())
);
}
updateVersionDiagnostic.ifPresent(diagnostic -> actions.add(
UpdateVersionCodeAction.build(fileUri, diagnostic.getRange())));

return actions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

package software.amazon.smithy.lsp.codeactions;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.lsp4j.CodeAction;
Expand All @@ -41,7 +40,7 @@ public static CodeAction build(String fileUri, Range versionStatementRange) {
codeAction.setKind(SmithyCodeActions.SMITHY_UPDATE_VERSION);
WorkspaceEdit wEdit = new WorkspaceEdit();
TextEdit edit = new TextEdit(versionStatementRange, "$version: \"" + LATEST_VERSION + "\"");
Map<String, List<TextEdit>> changes = Collections.singletonMap(fileUri, Collections.singletonList(edit));
Map<String, List<TextEdit>> changes = Map.of(fileUri, List.of(edit));
wEdit.setChanges(changes);
codeAction.setEdit(wEdit);
return codeAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ public CharBuffer borrowId(Position position) {
if (id == null) {
return null;
}
return id.borrowIdValue();
return id.idSlice();
}

/**
Expand Down
32 changes: 7 additions & 25 deletions src/main/java/software/amazon/smithy/lsp/document/DocumentId.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
* An inaccurate representation of an identifier within a model. It is
* inaccurate in the sense that the string value it references isn't
* necessarily a valid identifier, it just looks like an identifier.
*
* @param type The type of the id
* @param idSlice A borrowed slice containing the id's value
* @param range The range the id occupies
*/
public final class DocumentId {
public record DocumentId(Type type, CharBuffer idSlice, Range range) {
/**
* Represents the different kinds of identifiers that can be used to match.
*/
Expand Down Expand Up @@ -41,32 +45,10 @@ public enum Type {
/**
* Same as {@link Type#ID}, but with a member - will have a {@code $}.
*/
RELATIVE_WITH_MEMBER;
}

private final Type type;
private final CharBuffer buffer;
private final Range range;

DocumentId(Type type, CharBuffer buffer, Range range) {
this.type = type;
this.buffer = buffer;
this.range = range;
}

public Type type() {
return type;
RELATIVE_WITH_MEMBER
}

public String copyIdValue() {
return buffer.toString();
}

public CharBuffer borrowIdValue() {
return buffer;
}

public Range range() {
return range;
return idSlice.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,8 @@

/**
* The imports of a document, including the range they occupy.
*
* @param importsRange The range of the imports
* @param imports The set of imported shape ids. They are not guaranteed to be valid shape ids
*/
public final class DocumentImports {
private final Range importsRange;
private final Set<String> imports;

DocumentImports(Range importsRange, Set<String> imports) {
this.importsRange = importsRange;
this.imports = imports;
}

/**
* @return The range of the imports
*/
public Range importsRange() {
return importsRange;
}

/**
* @return The set of imported shape ids. They are not guaranteed
* to be valid shape ids
*/
public Set<String> imports() {
return imports;
}
}
public record DocumentImports(Range importsRange, Set<String> imports) {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,8 @@

/**
* The namespace of the document, including the range it occupies.
*
* @param statementRange The range of the statement, including {@code namespace}
* @param namespace The namespace of the document. Not guaranteed to be a valid namespace
*/
public final class DocumentNamespace {
private final Range statementRange;
private final CharSequence namespace;

DocumentNamespace(Range statementRange, CharSequence namespace) {
this.statementRange = statementRange;
this.namespace = namespace;
}

/**
* @return The range of the statement, including {@code namespace}
*/
public Range statementRange() {
return statementRange;
}

/**
* @return The namespace of the document. Not guaranteed to be
* a valid namespace
*/
public CharSequence namespace() {
return namespace;
}
}
public record DocumentNamespace(Range statementRange, CharSequence namespace) {}
Loading

0 comments on commit ac2eda8

Please sign in to comment.