Skip to content

Commit c5e355a

Browse files
committed
Move errors, warnings, and colors to their own package
1 parent 374e895 commit c5e355a

18 files changed

Lines changed: 286 additions & 321 deletions

‎src/main/java/org/javacs/CompileBatch.java‎

Lines changed: 0 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import java.util.function.Consumer;
1414
import java.util.function.Predicate;
1515
import java.util.logging.Logger;
16-
import java.util.regex.Pattern;
1716
import java.util.stream.Collectors;
1817
import javax.lang.model.element.*;
1918
import javax.lang.model.type.ArrayType;
@@ -177,161 +176,10 @@ Optional<Element> element(TreePath tree) {
177176
return Optional.ofNullable(el);
178177
}
179178

180-
List<org.javacs.lsp.Diagnostic> reportErrors(Path file) {
181-
var root = root(file);
182-
var diags = new ArrayList<org.javacs.lsp.Diagnostic>();
183-
// Convert diags
184-
for (var d : parent.diags) {
185-
var source = d.getSource();
186-
if (source == null) continue;
187-
var path = Paths.get(source.toUri());
188-
if (!file.equals(path)) continue;
189-
if (!isValidFileRange(d)) continue;
190-
diags.add(lspDiagnostic(d, root.getLineMap()));
191-
}
192-
// Check for unused privates
193-
var warnUnused = new WarnUnused(borrow.task);
194-
warnUnused.scan(root, null);
195-
for (var unusedEl : warnUnused.notUsed()) {
196-
diags.add(warnUnused(unusedEl));
197-
}
198-
// Check for unused exceptions
199-
var notThrown = new HashMap<String, TreePath>();
200-
new WarnNotThrown(borrow.task).scan(root, notThrown);
201-
for (var name : notThrown.keySet()) {
202-
diags.add(warnNotThrown(name, notThrown.get(name)));
203-
}
204-
// TODO hint fields that could be final
205-
206-
return diags;
207-
}
208-
209179
private boolean isValidFileRange(javax.tools.Diagnostic<? extends JavaFileObject> d) {
210180
return d.getSource().toUri().getScheme().equals("file") && d.getStartPosition() >= 0 && d.getEndPosition() >= 0;
211181
}
212182

213-
/**
214-
* lspDiagnostic(d, lines) converts d to LSP format, with its position shifted appropriately for the latest version
215-
* of the file.
216-
*/
217-
private org.javacs.lsp.Diagnostic lspDiagnostic(javax.tools.Diagnostic<? extends JavaFileObject> d, LineMap lines) {
218-
var start = (int) d.getStartPosition();
219-
var end = (int) d.getEndPosition();
220-
var severity = severity(d.getKind());
221-
var code = d.getCode();
222-
var message = d.getMessage(null);
223-
var result = new org.javacs.lsp.Diagnostic();
224-
result.severity = severity;
225-
result.code = code;
226-
result.message = message;
227-
result.range = new Span(start, end).asRange(lines);
228-
return result;
229-
}
230-
231-
private int severity(javax.tools.Diagnostic.Kind kind) {
232-
switch (kind) {
233-
case ERROR:
234-
return DiagnosticSeverity.Error;
235-
case WARNING:
236-
case MANDATORY_WARNING:
237-
return DiagnosticSeverity.Warning;
238-
case NOTE:
239-
return DiagnosticSeverity.Information;
240-
case OTHER:
241-
default:
242-
return DiagnosticSeverity.Hint;
243-
}
244-
}
245-
246-
private org.javacs.lsp.Diagnostic warnNotThrown(String name, TreePath path) {
247-
var pos = trees.getSourcePositions();
248-
var root = path.getCompilationUnit();
249-
var lines = root.getLineMap();
250-
var start = pos.getStartPosition(root, path.getLeaf());
251-
var startLine = (int) lines.getLineNumber(start);
252-
var startColumn = (int) lines.getColumnNumber(start);
253-
var startPos = new Position(startLine - 1, startColumn - 1);
254-
var end = pos.getEndPosition(root, path.getLeaf());
255-
var endLine = (int) lines.getLineNumber(end);
256-
var endColumn = (int) lines.getColumnNumber(end);
257-
var endPos = new Position(endLine - 1, endColumn - 1);
258-
var d = new org.javacs.lsp.Diagnostic();
259-
d.message = String.format("'%s' is not thrown in the body of the method", name);
260-
d.range = new Range(startPos, endPos);
261-
d.code = "unused_throws";
262-
d.severity = DiagnosticSeverity.Information;
263-
d.tags = List.of(DiagnosticTag.Unnecessary);
264-
return d;
265-
}
266-
267-
private org.javacs.lsp.Diagnostic warnUnused(Element unusedEl) {
268-
var path = trees.getPath(unusedEl);
269-
var root = path.getCompilationUnit();
270-
var leaf = path.getLeaf();
271-
var pos = trees.getSourcePositions();
272-
var start = (int) pos.getStartPosition(root, leaf);
273-
var end = (int) pos.getEndPosition(root, leaf);
274-
if (leaf instanceof VariableTree) {
275-
var v = (VariableTree) leaf;
276-
var offset = (int) pos.getEndPosition(root, v.getType());
277-
if (offset != -1) {
278-
start = offset;
279-
}
280-
}
281-
var file = Paths.get(root.getSourceFile().toUri());
282-
var contents = FileStore.contents(file);
283-
var name = unusedEl.getSimpleName();
284-
if (name.contentEquals("<init>")) {
285-
name = unusedEl.getEnclosingElement().getSimpleName();
286-
}
287-
var region = contents.subSequence(start, end);
288-
var matcher = Pattern.compile("\\b" + name + "\\b").matcher(region);
289-
if (matcher.find()) {
290-
start += matcher.start();
291-
end = start + name.length();
292-
}
293-
var message = String.format("'%s' is not used", name);
294-
String code;
295-
int severity;
296-
if (leaf instanceof VariableTree) {
297-
var parent = path.getParentPath().getLeaf();
298-
if (parent instanceof MethodTree) {
299-
code = "unused_param";
300-
severity = DiagnosticSeverity.Hint;
301-
} else if (parent instanceof BlockTree) {
302-
code = "unused_local";
303-
severity = DiagnosticSeverity.Information;
304-
} else if (parent instanceof ClassTree) {
305-
code = "unused_field";
306-
severity = DiagnosticSeverity.Information;
307-
} else {
308-
code = "unused_other";
309-
severity = DiagnosticSeverity.Hint;
310-
}
311-
} else if (leaf instanceof MethodTree) {
312-
code = "unused_method";
313-
severity = DiagnosticSeverity.Information;
314-
} else if (leaf instanceof ClassTree) {
315-
code = "unused_class";
316-
severity = DiagnosticSeverity.Information;
317-
} else {
318-
code = "unused_other";
319-
severity = DiagnosticSeverity.Information;
320-
}
321-
return lspWarnUnused(severity, code, message, start, end, root.getLineMap());
322-
}
323-
324-
static org.javacs.lsp.Diagnostic lspWarnUnused(
325-
int severity, String code, String message, int start, int end, LineMap lines) {
326-
var result = new org.javacs.lsp.Diagnostic();
327-
result.severity = severity;
328-
result.code = code;
329-
result.message = message;
330-
result.tags = List.of(DiagnosticTag.Unnecessary);
331-
result.range = new Span(start, end).asRange(lines);
332-
return result;
333-
}
334-
335183
public static final List<TreePath> CODE_NOT_FOUND = List.of();
336184

337185
List<TreePath> references(Path toFile, int toLine, int toColumn) {
@@ -1458,12 +1306,5 @@ private JsonElement data(Ptr ptr, int plusOverloads) {
14581306
return JavaLanguageServer.GSON.toJsonTree(data);
14591307
}
14601308

1461-
SemanticColors colors(Path file) {
1462-
var root = root(file);
1463-
var colorizer = new Colorizer(borrow.task);
1464-
colorizer.scan(root, null);
1465-
return colorizer.colors.lspSemanticColors(file, root.getLineMap());
1466-
}
1467-
14681309
private static final Logger LOG = Logger.getLogger("main");
14691310
}

‎src/main/java/org/javacs/CompilerProvider.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.nio.file.Path;
44
import java.nio.file.Paths;
5+
import java.util.Collection;
56
import java.util.Optional;
67
import java.util.Set;
78
import javax.tools.JavaFileObject;
@@ -27,5 +28,7 @@ public interface CompilerProvider {
2728

2829
CompileTask compile(Path... files);
2930

31+
CompileTask compile(Collection<? extends JavaFileObject> sources);
32+
3033
Path NOT_FOUND = Paths.get("");
3134
}

‎src/main/java/org/javacs/FileStore.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import org.javacs.lsp.DidOpenTextDocumentParams;
1414
import org.javacs.lsp.TextDocumentContentChangeEvent;
1515

16-
class FileStore {
16+
public class FileStore {
1717

1818
private static final Set<Path> workspaceRoots = new HashSet<>();
1919

@@ -243,7 +243,7 @@ static int version(Path file) {
243243
return activeDocuments.get(file).version;
244244
}
245245

246-
static String contents(Path file) {
246+
public static String contents(Path file) {
247247
if (!isJavaFile(file)) {
248248
throw new RuntimeException(file + " is not a java file");
249249
}

‎src/main/java/org/javacs/JavaCompilerService.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ public CompileTask compile(Path... files) {
307307
for (var f : files) {
308308
sources.add(new SourceFileObject(f));
309309
}
310+
return compile(sources);
311+
}
312+
313+
@Override
314+
public CompileTask compile(Collection<? extends JavaFileObject> sources) {
310315
var compile = compileBatch(sources);
311316
return new CompileTask(compile.task, compile.roots, diags, compile::close);
312317
}

‎src/main/java/org/javacs/JavaLanguageServer.java‎

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import javax.lang.model.type.TypeKind;
1616
import javax.tools.JavaFileObject;
1717
import org.javacs.lsp.*;
18+
import org.javacs.markup.ColorProvider;
19+
import org.javacs.markup.ErrorProvider;
1820
import org.javacs.rewrite.*;
1921

2022
class JavaLanguageServer extends LanguageServer {
@@ -47,40 +49,23 @@ private boolean needsCompiler() {
4749
}
4850

4951
void lint(Collection<Path> files) {
50-
if (files.isEmpty()) {
51-
return;
52-
}
52+
if (files.isEmpty()) return;
5353
LOG.info("Lint " + files.size() + " files...");
5454
var started = Instant.now();
55-
var sources = asSourceFiles(files);
56-
try (var batch = compiler().compileBatch(sources)) {
57-
LOG.info(String.format("...compiled in %d ms", elapsed(started)));
58-
publishDiagnostics(files, batch);
59-
}
60-
LOG.info(String.format("...linted in %d ms", elapsed(started)));
61-
}
62-
63-
private List<SourceFileObject> asSourceFiles(Collection<Path> files) {
64-
var sources = new ArrayList<SourceFileObject>();
65-
for (var f : files) {
66-
sources.add(new SourceFileObject(f));
67-
}
68-
return sources;
69-
}
70-
71-
private void publishDiagnostics(Collection<Path> files, CompileBatch batch) {
72-
for (var f : files) {
73-
var errors = batch.reportErrors(f);
74-
var colors = batch.colors(f);
75-
client.publishDiagnostics(new PublishDiagnosticsParams(f.toUri(), errors));
76-
client.customNotification("java/colors", GSON.toJsonTree(colors));
55+
try (var task = compiler().compile(files.toArray(Path[]::new))) {
56+
var compiled = Instant.now();
57+
LOG.info("...compiled in " + Duration.between(started, compiled).toMillis() + " ms");
58+
for (var errs : new ErrorProvider(task).errors()) {
59+
client.publishDiagnostics(errs);
60+
}
61+
for (var colors : new ColorProvider(task).colors()) {
62+
client.customNotification("java/colors", GSON.toJsonTree(colors));
63+
}
64+
var published = Instant.now();
65+
LOG.info("...published in " + Duration.between(started, published).toMillis() + " ms");
7766
}
7867
}
7968

80-
private long elapsed(Instant since) {
81-
return Duration.between(since, Instant.now()).toMillis();
82-
}
83-
8469
static final Gson GSON = new GsonBuilder().registerTypeAdapter(Ptr.class, new PtrAdapter()).create();
8570

8671
private void javaStartProgress(JavaStartProgressParams params) {

‎src/main/java/org/javacs/Parser.java‎

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -894,23 +894,6 @@ String prune(long cursor) {
894894
return prune(root, pos, buffer, cursors, true);
895895
}
896896

897-
String prune(Span block) {
898-
if (block == Span.EMPTY || block == Span.INVALID) return contents;
899-
var pos = Trees.instance(task).getSourcePositions();
900-
var buffer = new StringBuilder(contents);
901-
/*
902-
TODO: This will erase inner blocks like
903-
void test() {
904-
foo.|
905-
{
906-
innerBlock();
907-
}
908-
}
909-
*/
910-
long[] cursors = {block.start + 1, block.until - 1};
911-
return prune(root, pos, buffer, cursors, false);
912-
}
913-
914897
String eraseCase(long cursor) {
915898
var path = findPath(cursor);
916899
while (path != null && path.getLeaf().getKind() != Tree.Kind.CASE) {
@@ -948,27 +931,6 @@ String prune(String name) {
948931
return prune(root, pos, buffer, offsets, false);
949932
}
950933

951-
Span enclosingMethod(int start, int end) {
952-
var pos = Trees.instance(task).getSourcePositions();
953-
class FindEnclosingMethod extends TreeScanner<Void, Void> {
954-
Span found = Span.INVALID;
955-
956-
@Override
957-
public Void visitMethod(MethodTree method, Void __) {
958-
var body = method.getBody();
959-
var startBody = (int) pos.getStartPosition(root, body);
960-
var endBody = (int) pos.getEndPosition(root, body);
961-
if (startBody < start && end < endBody) {
962-
found = new Span(startBody, endBody);
963-
}
964-
return super.visitMethod(method, null);
965-
}
966-
}
967-
var find = new FindEnclosingMethod();
968-
find.scan(root, null);
969-
return find.found;
970-
}
971-
972934
static Set<Path> potentialReferences(Path file, String name, boolean isType, Set<Modifier> flags) {
973935
LOG.info(String.format("...find potential references to `%s`...", name));
974936
var pkg = FileStore.packageName(file);

‎src/main/java/org/javacs/SemanticColors.java‎

Lines changed: 0 additions & 11 deletions
This file was deleted.

‎src/main/java/org/javacs/Span.java‎

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)