Skip to content

Commit dc2bb84

Browse files
committed
Показ прогресса иницициализации контекста
1 parent 770cf8b commit dc2bb84

File tree

3 files changed

+151
-5
lines changed

3 files changed

+151
-5
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* This file is a part of BSL Language Server.
3+
*
4+
* Copyright (c) 2018-2022
5+
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> and contributors
6+
*
7+
* SPDX-License-Identifier: LGPL-3.0-or-later
8+
*
9+
* BSL Language Server is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 3.0 of the License, or (at your option) any later version.
13+
*
14+
* BSL Language Server is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with BSL Language Server.
21+
*/
22+
package com.github._1c_syntax.bsl.languageserver;
23+
24+
import lombok.AllArgsConstructor;
25+
import lombok.RequiredArgsConstructor;
26+
import lombok.Setter;
27+
import org.eclipse.lsp4j.ClientCapabilities;
28+
import org.eclipse.lsp4j.ProgressParams;
29+
import org.eclipse.lsp4j.WindowClientCapabilities;
30+
import org.eclipse.lsp4j.WorkDoneProgressBegin;
31+
import org.eclipse.lsp4j.WorkDoneProgressCreateParams;
32+
import org.eclipse.lsp4j.WorkDoneProgressEnd;
33+
import org.eclipse.lsp4j.WorkDoneProgressReport;
34+
import org.eclipse.lsp4j.jsonrpc.messages.Either;
35+
import org.eclipse.lsp4j.services.LanguageClient;
36+
import org.springframework.stereotype.Component;
37+
38+
import java.util.UUID;
39+
import java.util.concurrent.atomic.AtomicInteger;
40+
41+
@Component
42+
@RequiredArgsConstructor
43+
public class WorkDoneProgressHelper {
44+
45+
private final LanguageClientHolder languageClientHolder;
46+
private final ClientCapabilitiesHolder clientCapabilitiesHolder;
47+
48+
private boolean isWorkDoneProgressSupported;
49+
50+
public WorkDoneProgressReporter createProgress(int size, String messagePostfix) {
51+
52+
isWorkDoneProgressSupported = clientCapabilitiesHolder.getCapabilities()
53+
.map(ClientCapabilities::getWindow)
54+
.map(WindowClientCapabilities::getWorkDoneProgress)
55+
.orElse(false);
56+
57+
if (!isWorkDoneProgressSupported) {
58+
return new WorkDoneProgressReporter("", 0, "");
59+
}
60+
61+
var token = UUID.randomUUID().toString();
62+
var createProgressParams = new WorkDoneProgressCreateParams(Either.forLeft(token));
63+
64+
languageClientHolder.execIfConnected(languageClient ->
65+
languageClient.createProgress(createProgressParams)
66+
);
67+
68+
return new WorkDoneProgressReporter(token, size, messagePostfix);
69+
}
70+
71+
72+
@AllArgsConstructor
73+
public class WorkDoneProgressReporter {
74+
private final String token;
75+
@Setter
76+
private int size;
77+
private final String messagePostfix;
78+
79+
private final AtomicInteger counter = new AtomicInteger();
80+
81+
public void beginProgress(String title) {
82+
if (!isWorkDoneProgressSupported) {
83+
return;
84+
}
85+
86+
languageClientHolder.execIfConnected((LanguageClient languageClient) -> {
87+
var value = new WorkDoneProgressBegin();
88+
value.setTitle(title);
89+
90+
var params = new ProgressParams(Either.forLeft(token), Either.forLeft(value));
91+
languageClient.notifyProgress(params);
92+
});
93+
}
94+
95+
public void tick(String message, int percentage) {
96+
if (!isWorkDoneProgressSupported) {
97+
return;
98+
}
99+
100+
languageClientHolder.execIfConnected((LanguageClient languageClient) -> {
101+
var value = new WorkDoneProgressReport();
102+
value.setMessage(message);
103+
value.setCancellable(false);
104+
value.setPercentage(percentage);
105+
106+
var params = new ProgressParams(Either.forLeft(token), Either.forLeft(value));
107+
languageClient.notifyProgress(params);
108+
});
109+
}
110+
public void tick() {
111+
var currentCounter = counter.incrementAndGet();
112+
var message = String.format("%d/%d%s", currentCounter, size, messagePostfix);
113+
var percentage = currentCounter / size;
114+
115+
tick(message, percentage);
116+
}
117+
118+
public void endProgress(String message) {
119+
if (!isWorkDoneProgressSupported) {
120+
return;
121+
}
122+
123+
languageClientHolder.execIfConnected((LanguageClient languageClient) -> {
124+
var value = new WorkDoneProgressEnd();
125+
value.setMessage(message);
126+
127+
var params = new ProgressParams(Either.forLeft(token), Either.forLeft(value));
128+
languageClient.notifyProgress(params);
129+
});
130+
}
131+
}
132+
}

src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/AnalyzeCommand.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import java.nio.file.Path;
4646
import java.time.LocalDateTime;
4747
import java.util.ArrayList;
48-
import java.util.Collection;
4948
import java.util.List;
5049
import java.util.Optional;
5150
import java.util.concurrent.Callable;
@@ -167,7 +166,7 @@ public Integer call() {
167166
var configurationPath = LanguageServerConfiguration.getCustomConfigurationRoot(configuration, srcDir);
168167
context.setConfigurationRoot(configurationPath);
169168

170-
Collection<File> files = FileUtils.listFiles(srcDir.toFile(), new String[]{"bsl", "os"}, true);
169+
var files = (List<File>) FileUtils.listFiles(srcDir.toFile(), new String[]{"bsl", "os"}, true);
171170

172171
context.populateContext(files);
173172

src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*/
2222
package com.github._1c_syntax.bsl.languageserver.context;
2323

24+
import com.github._1c_syntax.bsl.languageserver.WorkDoneProgressHelper;
2425
import com.github._1c_syntax.bsl.languageserver.utils.MdoRefBuilder;
2526
import com.github._1c_syntax.bsl.types.ModuleType;
2627
import com.github._1c_syntax.mdclasses.Configuration;
@@ -40,10 +41,10 @@
4041
import java.net.URI;
4142
import java.nio.charset.StandardCharsets;
4243
import java.nio.file.Path;
43-
import java.util.Collection;
4444
import java.util.Collections;
4545
import java.util.EnumMap;
4646
import java.util.HashMap;
47+
import java.util.List;
4748
import java.util.Map;
4849
import java.util.Optional;
4950
import java.util.concurrent.ExecutionException;
@@ -55,6 +56,7 @@
5556
@Component
5657
@RequiredArgsConstructor
5758
public abstract class ServerContext {
59+
private final WorkDoneProgressHelper workDoneProgressHelper;
5860
private final Map<URI, DocumentContext> documents = Collections.synchronizedMap(new HashMap<>());
5961
private final Lazy<Configuration> configurationMetadata = new Lazy<>(this::computeConfigurationMetadata);
6062
@CheckForNull
@@ -70,20 +72,31 @@ public void populateContext() {
7072
LOGGER.info("Can't populate server context. Configuration root is not defined.");
7173
return;
7274
}
75+
76+
var workDoneProgressReporter = workDoneProgressHelper.createProgress(0, "");
77+
workDoneProgressReporter.beginProgress("Finding files to populate context...");
78+
7379
LOGGER.debug("Finding files to populate context...");
74-
Collection<File> files = FileUtils.listFiles(
80+
var files = (List<File>) FileUtils.listFiles(
7581
configurationRoot.toFile(),
7682
new String[]{"bsl", "os"},
7783
true
7884
);
85+
workDoneProgressReporter.endProgress("");
7986
populateContext(files);
8087
}
8188

82-
public void populateContext(Collection<File> uris) {
89+
public void populateContext(List<File> uris) {
90+
var workDoneProgressReporter = workDoneProgressHelper.createProgress(uris.size(), " files");
91+
workDoneProgressReporter.beginProgress("Populating context...");
92+
8393
LOGGER.debug("Populating context...");
8494
contextLock.writeLock().lock();
8595

8696
uris.parallelStream().forEach((File file) -> {
97+
98+
workDoneProgressReporter.tick();
99+
87100
var documentContext = getDocument(file.toURI());
88101
if (documentContext == null) {
89102
documentContext = createDocumentContext(file, 0);
@@ -93,6 +106,8 @@ public void populateContext(Collection<File> uris) {
93106
});
94107

95108
contextLock.writeLock().unlock();
109+
110+
workDoneProgressReporter.endProgress("Context populated.");
96111
LOGGER.debug("Context populated.");
97112
}
98113

0 commit comments

Comments
 (0)