Skip to content

Commit 1378f4a

Browse files
authored
Fix Path Handling (#30)
1 parent 96a6fec commit 1378f4a

File tree

4 files changed

+73
-57
lines changed

4 files changed

+73
-57
lines changed

server/src/main/java/LJDiagnosticsHandler.java

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import java.nio.charset.StandardCharsets;
21
import java.util.ArrayList;
32
import java.util.Collections;
43
import java.util.List;
@@ -17,10 +16,10 @@
1716
import liquidjava.diagnostics.LJDiagnostic;
1817
import liquidjava.diagnostics.errors.LJError;
1918
import liquidjava.diagnostics.warnings.LJWarning;
19+
import utils.PathUtils;
2020

2121
public class LJDiagnosticsHandler {
2222

23-
private static final String FILE_PREFIX = "file://";
2423
private static final String SOURCE = "liquidjava";
2524

2625
/**
@@ -29,7 +28,7 @@ public class LJDiagnosticsHandler {
2928
* @param path the file path
3029
* @return LJDiagnostics
3130
*/
32-
public static LJDiagnostics getLJDiagnostics(String uri, String path) {
31+
public static LJDiagnostics getLJDiagnostics(String path) {
3332
List<LJError> errors = new ArrayList<>();
3433
List<LJWarning> warnings = new ArrayList<>();
3534

@@ -69,7 +68,7 @@ public static List<PublishDiagnosticsParams> getDiagnostics(List<LJDiagnostic> d
6968
// group diagnostics by file
7069
Map<String, List<Diagnostic>> diagnosticsByFile = diagnostics.stream()
7170
.collect(Collectors.groupingBy(
72-
d -> toFileUri(d.getFile()),
71+
d -> PathUtils.toFileUri(d.getFile()),
7372
Collectors.mapping(d -> {
7473
Range range = getRangeFromErrorPosition(d.getPosition());
7574
String message = String.format("%s: %s", d.getTitle(), d.getMessage());
@@ -83,21 +82,6 @@ public static List<PublishDiagnosticsParams> getDiagnostics(List<LJDiagnostic> d
8382
.toList();
8483
}
8584

86-
/**
87-
* Converts a file path to a file:// URI
88-
* @param filePath the file path
89-
* @return the file URI
90-
*/
91-
private static String toFileUri(String filePath) {
92-
String normalized = filePath.replace("\\", "/");
93-
// Windows (C:/path)
94-
if (!normalized.isEmpty() && normalized.charAt(1) == ':') {
95-
return FILE_PREFIX + "/" + normalized;
96-
}
97-
// Unix (/path)
98-
return FILE_PREFIX + normalized;
99-
}
100-
10185
/**
10286
* Generates empty diagnostics for the given URI
10387
* @param uri the uri used for the verification

server/src/main/java/LJDiagnosticsService.java

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import java.io.File;
22
import java.net.URI;
3-
import java.nio.file.Path;
4-
import java.nio.file.Paths;
53
import java.util.List;
64
import java.util.stream.Collectors;
75
import java.util.stream.Stream;
@@ -18,38 +16,27 @@
1816

1917
import dtos.DiagnosticConverter;
2018
import liquidjava.diagnostics.LJDiagnostic;
19+
import utils.PathUtils;
2120

2221
public class LJDiagnosticsService implements TextDocumentService, WorkspaceService {
2322

2423
private LJLanguageClient client;
25-
private String sourcePath;
24+
private String workspaceRoot;
2625

27-
/**
28-
* Sets the language client
29-
* @param client the language client
30-
*/
3126
public void setClient(LJLanguageClient client) {
3227
this.client = client;
3328
}
3429

35-
/**
36-
* Sets the source path
37-
* Uses workspaceRoot + "/src/main/java" if it exists, otherwise uses workspaceRoot
38-
* @param workspaceRoot the workspace root URI
39-
*/
40-
public void setSourcePath(String workspaceRoot) {
41-
Path workspaceRootPath = Paths.get(URI.create(workspaceRoot));
42-
Path srcMainJava = workspaceRootPath.resolve("src/main/java");
43-
this.sourcePath = srcMainJava.toFile().isDirectory() ? srcMainJava.toString() : workspaceRootPath.toString();
30+
public void setWorkspaceRoot(String workspaceRoot) {
31+
this.workspaceRoot = workspaceRoot;
4432
}
4533

4634
/**
4735
* Sends diagnostics notification to the client
4836
* @param diagnostics the diagnostics to send
4937
*/
5038
public void sendDiagnosticsNotification(List<LJDiagnostic> diagnostics) {
51-
if (this.client == null)
52-
return;
39+
if (this.client == null) return;
5340

5441
System.out.println("Sending diagnostics notification with " + diagnostics.size() + " diagnostics");
5542
List<Object> dtos = diagnostics.stream()
@@ -63,7 +50,8 @@ public void sendDiagnosticsNotification(List<LJDiagnostic> diagnostics) {
6350
* @param uri the URI of the document
6451
*/
6552
public void generateDiagnostics(String uri) {
66-
LJDiagnostics ljDiagnostics = LJDiagnosticsHandler.getLJDiagnostics(uri, sourcePath);
53+
String path = PathUtils.extractBasePath(uri);
54+
LJDiagnostics ljDiagnostics = LJDiagnosticsHandler.getLJDiagnostics(path);
6755
List<PublishDiagnosticsParams> nativeDiagnostics = LJDiagnosticsHandler.getNativeDiagnostics(ljDiagnostics, uri);
6856
nativeDiagnostics.forEach(params -> {
6957
this.client.publishDiagnostics(params);
@@ -72,21 +60,6 @@ public void generateDiagnostics(String uri) {
7260
sendDiagnosticsNotification(diagnostics);
7361
}
7462

75-
/**
76-
* Checks if a file URI is within the source path
77-
* @param uri the file URI
78-
* @return true if the file is within sourcePath, false otherwise
79-
*/
80-
private boolean isFileInSourcePath(String uri) {
81-
try {
82-
Path filePath = Paths.get(new URI(uri));
83-
Path sourcePathObj = Paths.get(sourcePath);
84-
return filePath.startsWith(sourcePathObj);
85-
} catch (Exception e) {
86-
return false;
87-
}
88-
}
89-
9063
/**
9164
* Clear a diagnostic for a specific URI
9265
* @param uri the URI of the document
@@ -104,7 +77,7 @@ public void clearDiagnostic(String uri) {
10477
@Override
10578
public void didOpen(DidOpenTextDocumentParams params) {
10679
String uri = params.getTextDocument().getUri();
107-
if (!isFileInSourcePath(uri)) return;
80+
if (!PathUtils.isFileInDirectory(uri, workspaceRoot)) return;
10881
System.out.println("Document opened — checking diagnostics");
10982
generateDiagnostics(uri);
11083
}
@@ -116,7 +89,7 @@ public void didOpen(DidOpenTextDocumentParams params) {
11689
@Override
11790
public void didSave(DidSaveTextDocumentParams params) {
11891
String uri = params.getTextDocument().getUri();
119-
if (!isFileInSourcePath(uri)) return;
92+
if (!PathUtils.isFileInDirectory(uri, workspaceRoot)) return;
12093
System.out.println("Document saved — checking diagnostics");
12194
clearDiagnostic(uri);
12295
generateDiagnostics(uri);
@@ -129,7 +102,7 @@ public void didSave(DidSaveTextDocumentParams params) {
129102
@Override
130103
public void didClose(DidCloseTextDocumentParams params) {
131104
String uri = params.getTextDocument().getUri();
132-
if (!isFileInSourcePath(uri)) return;
105+
if (!PathUtils.isFileInDirectory(uri, workspaceRoot)) return;
133106
try {
134107
// check if the file still exists on disk
135108
File file = new File(new URI(uri));

server/src/main/java/LJLanguageServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
3333
// extract workspace root from initialization params
3434
if (params.getWorkspaceFolders() != null && !params.getWorkspaceFolders().isEmpty()) {
3535
String workspaceRoot = params.getWorkspaceFolders().get(0).getUri();
36-
diagnosticsService.setSourcePath(workspaceRoot);
36+
diagnosticsService.setWorkspaceRoot(workspaceRoot);
3737
}
3838

3939
// set options
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package utils;
2+
3+
import java.net.URI;
4+
import java.nio.file.Path;
5+
import java.nio.file.Paths;
6+
7+
/**
8+
* Utility class for path operations
9+
*/
10+
public class PathUtils {
11+
private static final String FILE_PREFIX = "file://";
12+
private static final String SRC_SUFFIX = "/src/";
13+
14+
/**
15+
* Checks if a file is in a given directory
16+
* @param fileUri the file URI
17+
* @param directoryUri the directory URI
18+
* @return true if the file is in the directory, false otherwise
19+
*/
20+
public static boolean isFileInDirectory(String fileUri, String directoryUri) {
21+
try {
22+
Path filePath = Paths.get(new URI(fileUri));
23+
Path directoryPath = Paths.get(new URI(directoryUri));
24+
return filePath.startsWith(directoryPath);
25+
} catch (Exception e) {
26+
return false;
27+
}
28+
}
29+
30+
/**
31+
* Extracts the base path from the given full path
32+
* e.g. file://path/to/project/src/main/path/to/File.java => /path/to/project/src/main
33+
* @param fullPath the full path
34+
* @return base path
35+
*/
36+
public static String extractBasePath(String fullPath) {
37+
fullPath = fullPath.replace(FILE_PREFIX, "");
38+
int suffixIndex = fullPath.indexOf(SRC_SUFFIX);
39+
int nextSlashIndex = fullPath.indexOf("/", suffixIndex + SRC_SUFFIX.length());
40+
if (suffixIndex == -1 || nextSlashIndex == -1)
41+
return fullPath; // cannot extract base path
42+
return fullPath.substring(0, nextSlashIndex); // up to and including the next slash after /src/
43+
}
44+
45+
/**
46+
* Converts a file path to a file:// URI
47+
* @param filePath the file path
48+
* @return the file URI
49+
*/
50+
public static String toFileUri(String filePath) {
51+
String normalized = filePath.replace("\\", "/");
52+
// Windows (C:/path)
53+
if (!normalized.isEmpty() && normalized.charAt(1) == ':') {
54+
return FILE_PREFIX + "/" + normalized;
55+
}
56+
// Unix (/path)
57+
return FILE_PREFIX + normalized;
58+
}
59+
}

0 commit comments

Comments
 (0)