Skip to content

Commit 44e6f34

Browse files
authored
Replace common get-or-initialize pattern with utility function (#1004)
* Replace common get-or-initialize pattern with utility function. * Clarify semantics with better name and documentation.
1 parent 9977b7b commit 44e6f34

4 files changed

Lines changed: 28 additions & 20 deletions

File tree

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/BaseWorkspaceService.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,7 @@ public void initialize(ClientCapabilities clientCap, @Nullable List<WorkspaceFol
8484
this.workspaceFolders.addAll(currentWorkspaceFolders);
8585
}
8686

87-
if (capabilities.getWorkspace() == null) {
88-
capabilities.setWorkspace(new WorkspaceServerCapabilities());
89-
}
90-
91-
var workspaceCapabilities = capabilities.getWorkspace();
87+
var workspaceCapabilities = Nullables.ensureNonNullAndGet(capabilities, ServerCapabilities::getWorkspace, ServerCapabilities::setWorkspace, WorkspaceServerCapabilities::new);
9288
if (Nullables.has(clientCap.getWorkspace(), WorkspaceClientCapabilities::getWorkspaceFolders)) {
9389
var folderOptions = new WorkspaceFoldersOptions();
9490
folderOptions.setSupported(true);

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/capabilities/FileOperationCapability.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,8 @@ private static FileOperationFilter extensionFilter(String ext) {
103103
}
104104

105105
private static FileOperationsServerCapabilities fileOperationCapabilities(ServerCapabilities caps) {
106-
var workspace = caps.getWorkspace();
107-
if (workspace == null) {
108-
workspace = new WorkspaceServerCapabilities();
109-
caps.setWorkspace(workspace);
110-
}
111-
var fileOps = workspace.getFileOperations();
112-
if (fileOps == null) {
113-
fileOps = new FileOperationsServerCapabilities();
114-
workspace.setFileOperations(fileOps);
115-
}
116-
return fileOps;
106+
var workspace = Nullables.ensureNonNullAndGet(caps, ServerCapabilities::getWorkspace, ServerCapabilities::setWorkspace, WorkspaceServerCapabilities::new);
107+
return Nullables.ensureNonNullAndGet(workspace, WorkspaceServerCapabilities::getFileOperations, WorkspaceServerCapabilities::setFileOperations, FileOperationsServerCapabilities::new);
117108
}
118109

119110
/**

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalWorkspaceService.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.eclipse.lsp4j.ServerCapabilities;
4242
import org.eclipse.lsp4j.WorkspaceClientCapabilities;
4343
import org.eclipse.lsp4j.WorkspaceFolder;
44+
import org.eclipse.lsp4j.WorkspaceServerCapabilities;
4445
import org.rascalmpl.vscode.lsp.BaseWorkspaceService;
4546
import org.rascalmpl.vscode.lsp.IBaseTextDocumentService;
4647
import org.rascalmpl.vscode.lsp.util.Nullables;
@@ -56,10 +57,8 @@ public void initialize(ClientCapabilities clientCap, @Nullable List<WorkspaceFol
5657
ServerCapabilities capabilities) {
5758
super.initialize(clientCap, currentWorkspaceFolders, capabilities);
5859

59-
if (capabilities.getWorkspace().getFileOperations() == null) {
60-
capabilities.getWorkspace().setFileOperations(new FileOperationsServerCapabilities());
61-
}
62-
var fileOperationCapabilities = capabilities.getWorkspace().getFileOperations();
60+
var workspaceCap = Nullables.ensureNonNullAndGet(capabilities, ServerCapabilities::getWorkspace, ServerCapabilities::setWorkspace, WorkspaceServerCapabilities::new);
61+
var fileOperationCapabilities = Nullables.ensureNonNullAndGet(workspaceCap, WorkspaceServerCapabilities::getFileOperations, WorkspaceServerCapabilities::setFileOperations, FileOperationsServerCapabilities::new);
6362

6463
var rascalFile = new FileOperationPattern("**/*.rsc");
6564
rascalFile.setMatches(FileOperationPatternKind.File);

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/Nullables.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
*/
2727
package org.rascalmpl.vscode.lsp.util;
2828

29+
import java.util.function.BiConsumer;
2930
import java.util.function.Function;
31+
import java.util.function.Supplier;
3032
import org.checkerframework.checker.nullness.qual.Nullable;
3133
import org.checkerframework.checker.nullness.qual.PolyNull;
3234

@@ -99,4 +101,24 @@ public static <A, B> boolean has(@Nullable A a, Function<A, @Nullable B> getFunc
99101
return get(get(a, getFunc1, null), getFunc2, defaultVal);
100102
}
101103

104+
/**
105+
* Get a value from an object. If it was not set yet (i.e. `null`), initialize and set it before returning.
106+
* @param <C> The type of the containing object.
107+
* @param <T> The type of the value to get.
108+
* @param container The containing object.
109+
* @param getter The value getter.
110+
* @param setter The value setter. Only called if the value is not initialized yet.
111+
* @param initializer The value initializer (e.g. a constructor). Only called if the value is not initialized yet.
112+
* @return The gotten value, or the initialized value if was not initialized yet.
113+
*/
114+
public static <C, T> T ensureNonNullAndGet(C container, Function<C, @Nullable T> getter, BiConsumer<C, T> setter, Supplier<T> initializer) {
115+
var t = getter.apply(container);
116+
if (t == null) {
117+
t = initializer.get();
118+
setter.accept(container, t);
119+
assert getter.apply(container) != null : "Setter should set same value as getter gets";
120+
}
121+
return t;
122+
}
123+
102124
}

0 commit comments

Comments
 (0)