Skip to content

Commit a3cd8e6

Browse files
committed
Document registrations functions and logic.
1 parent 293bb86 commit a3cd8e6

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void registerStaticCapabilities(ServerCapabilities result) {
112112
/**
113113
* Update capabilities for language contributions.
114114
* @param contribs The contributions to represent.
115-
* @return A void future that completes when all capabilities are updated.
115+
* @return A future that completes with a boolean that is false when any registration failed, and true otherwise.
116116
*/
117117
public CompletableFuture<Boolean> updateCapabilities(Collection<ILanguageContributions> contribs) {
118118
// Copy the contributions so we know we are looking at a stable set of elements.
@@ -125,6 +125,15 @@ public CompletableFuture<Boolean> updateCapabilities(Collection<ILanguageContrib
125125
return CompletableFutureUtils.reduce(registrations, CompletableFutureUtils.completedFuture(true, singleExec), Boolean::booleanValue, Boolean::logicalAnd);
126126
}
127127

128+
/**
129+
* Update the registration of a capability.
130+
* - If the capability is not yet registered, register it.
131+
* - If the capability is already registered, and the options changed, update it (by unregistering and registering with new options).
132+
* - If the capability is already registered and the options did not change, do nothing.
133+
* @param cap The capability to update.
134+
* @param registration The computed registration to do, or `null` when this capability is absent.
135+
* @return A future completing with `true` when successful, or `false` otherwise.
136+
*/
128137
private <T> CompletableFuture<Boolean> updateRegistration(AbstractDynamicCapability<T> cap, @Nullable Registration registration) {
129138
var method = cap.methodName();
130139
var existingRegistration = currentRegistrations.get(method);
@@ -152,6 +161,12 @@ private <T> CompletableFuture<Boolean> updateRegistration(AbstractDynamicCapabil
152161
return register(registration);
153162
}
154163

164+
/**
165+
* Unregister this registration.
166+
* Aims to be atomic, i.e. keeps local administration of registered capabilities in sync with the client.
167+
* @param reg The registration to undo.
168+
* @return A future completing with `true` if successful, and `false` otherwise.
169+
*/
155170
private CompletableFuture<Boolean> unregister(Registration reg) {
156171
// If our administration contains exactly this registration, remove it and inform the client
157172
if (!currentRegistrations.remove(reg.getMethod(), reg)) {
@@ -170,6 +185,12 @@ private CompletableFuture<Boolean> unregister(Registration reg) {
170185
});
171186
}
172187

188+
/**
189+
* Register this registration.
190+
* Aims to be atomic, i.e. keeps local administration of registered capabilities in sync with the client.
191+
* @param reg The registration to do.
192+
* @return A future completing with `true` if successful, and `false` otherwise.
193+
*/
173194
private CompletableFuture<Boolean> register(Registration reg) {
174195
// If our administration contains no registration, inform the client
175196
if (currentRegistrations.putIfAbsent(reg.getMethod(), reg) != null) {
@@ -195,10 +216,21 @@ private void handleError(Throwable t, String task, String method) {
195216
logger.error("Exception while {} capability {}", task, method, t);
196217
}
197218

219+
/**
220+
* Update a registration.
221+
* Aims to be atomic, i.e. keeps local administration of registered capabilities in sync with the client.
222+
* @param newRegistration The registration with the updated options.
223+
* @param existingRegistration The registration that we expect to currently be in place.
224+
* @return A future completing with `true` if successful, or `false` otherwise.
225+
*/
198226
private CompletableFuture<Boolean> changeOptions(Registration newRegistration, Registration existingRegistration) {
199227
return unregister(existingRegistration)
200228
.thenCompose(b -> {
201229
if (!b.booleanValue()) {
230+
/* If unregistration fails, this has one of multiple causes:
231+
1. Someone raced us, won, and updated `currentRegistrations`. Our view of the current state is outdated, so we don't do anything and leave it to the winner.
232+
2. The unregistration request failed. This happens when a capability is not supported by the client. Since we successfully registered, this should not happen.
233+
*/
202234
return falsy;
203235
}
204236
return register(newRegistration);

0 commit comments

Comments
 (0)