Skip to content

Commit 504c6f9

Browse files
lsp: Override virtual file system
The language server provides its own VirtualFileSystem in order to intercept reads of files that are currently managed by the LSP client. Additionally, parsing dependencies between files are tracked in order to publish diagnostics for dependent files too. Updated LICENSE.md with lsp4j information.
1 parent 853f1d5 commit 504c6f9

File tree

5 files changed

+394
-211
lines changed

5 files changed

+394
-211
lines changed

LICENSE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ with their licence information:
7878
| Apache License 2.0 | Error Prone - compile time analysis tool | https://github.com/google/error-prone |
7979
| MIT License | NullAway - static null checking for java | https://github.com/uber/NullAway |
8080
| MIT License | Z3 - a theorem prover from Microsoft Research | https://github.com/Z3Prover/z3 |
81+
| EPL 2.0 or BSD 3-Clause | Eclipse LSP4J - language server protocol implementation | https://github.com/eclipse-lsp4j/lsp4j |
8182

8283
### Test Libraries
8384

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// SPDX-FileCopyrightText : © 2026 TU Wien <vadl@tuwien.ac.at>
2+
// SPDX-License-Identifier: GPL-3.0-or-later
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
package vadl.lsp;
18+
19+
import java.util.HashMap;
20+
import java.util.HashSet;
21+
import java.util.Map;
22+
import java.util.Set;
23+
24+
/**
25+
* Tracks dependencies between items. You can set an item's dependencies and then request another
26+
* item's dependents (i.e. every item that is dependening on it).
27+
*
28+
* <p>Note: This is effectively a bidirectional multimap. Custom terms are used to avoid
29+
* misunderstandings in the usage context.
30+
*
31+
* @param <T> Item type to track dependencies for
32+
*/
33+
public class DependencyMap<T> {
34+
/**
35+
* Maps items to their dependencies.
36+
*/
37+
private final Map<T, Set<T>> dependencies = new HashMap<>();
38+
/**
39+
* Maps items to their dependents - the inverse of {@code dependencies}.
40+
*/
41+
private final Map<T, Set<T>> dependents = new HashMap<>();
42+
43+
/**
44+
* Overwrites an item's dependencies.
45+
*
46+
* @param newDependencies All existing dependencies for {@code item} that are not contained herein
47+
* are removed. If {@code item} is contained herein it is ignored - i.e.
48+
* an item never depends on itself.
49+
*/
50+
public synchronized void setDependencies(T item, Set<T> newDependencies) {
51+
Set<T> itemSet = dependencies.get(item);
52+
if (itemSet == null) {
53+
itemSet = new HashSet<>();
54+
dependencies.put(item, itemSet);
55+
56+
} else {
57+
// Remove all outdated dependencies
58+
var iter = itemSet.iterator();
59+
while (iter.hasNext()) {
60+
T d = iter.next();
61+
if (!newDependencies.contains(d)) {
62+
iter.remove();
63+
Set<T> ds = dependents.get(d);
64+
if (ds != null) {
65+
ds.remove(item);
66+
}
67+
}
68+
}
69+
}
70+
71+
// Add new dependencies
72+
for (T d : newDependencies) {
73+
if (item.equals(d)) {
74+
// Ignore self-dependencies
75+
continue;
76+
}
77+
if (itemSet.add(d)) {
78+
Set<T> ds = dependents.computeIfAbsent(d, k -> new HashSet<>());
79+
ds.add(item);
80+
}
81+
}
82+
}
83+
84+
/**
85+
* Returns {@code item}'s current dependents (i.e. other items that depend on it).
86+
*/
87+
public synchronized Set<T> getDependents(T item) {
88+
var d = dependents.get(item);
89+
if (d == null) {
90+
return Set.of();
91+
}
92+
return Set.copyOf(d);
93+
}
94+
}

0 commit comments

Comments
 (0)