Skip to content

Commit 0527110

Browse files
committed
Add display of macro variables
1 parent fb3cfd5 commit 0527110

File tree

7 files changed

+251
-6
lines changed

7 files changed

+251
-6
lines changed

src/main/java/net/gunivers/sniffer/command/FunctionInAction.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package net.gunivers.sniffer.command;
22

3+
import net.gunivers.sniffer.EncapsulationBreaker;
34
import net.minecraft.command.CommandExecutionContext;
45
import net.minecraft.command.Frame;
56
import net.minecraft.command.SourcedCommandAction;
7+
import net.minecraft.nbt.NbtCompound;
68
import net.minecraft.server.command.AbstractServerCommandSource;
79
import net.minecraft.server.function.CommandFunction;
810
import net.gunivers.sniffer.dap.ScopeManager;
@@ -55,6 +57,8 @@ public void execute(T source, CommandExecutionContext<T> context, Frame frame){
5557
if(function instanceof ExpandedMacro<T> macro) {
5658
id = getId(macro);
5759
}
58-
ScopeManager.get().newScope(id.toString(), source);
60+
61+
var macroVariables = EncapsulationBreaker.getAttribute(frame, "function").flatMap(fun -> EncapsulationBreaker.getAttribute(fun, "arguments"));
62+
ScopeManager.get().newScope(id.toString(), source, (NbtCompound) macroVariables.orElse(null));
5963
}
6064
}

src/main/java/net/gunivers/sniffer/dap/DapServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ public CompletableFuture<VariablesResponse> variables(VariablesArguments args) {
465465
}
466466

467467
var response = new VariablesResponse();
468-
response.setVariables(dapVariables.toArray(Variable[]::new));
468+
response.setVariables(dapVariables.stream().sorted(Comparator.comparingInt(Variable::getVariablesReference)).toArray(Variable[]::new));
469469
LOGGER.debug("Sending Variables response: {}", response);
470470
return CompletableFuture.completedFuture(response);
471471
}
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
package net.gunivers.sniffer.dap;
2+
3+
import net.minecraft.nbt.*;
4+
import net.minecraft.nbt.visitor.NbtElementVisitor;
5+
6+
import java.util.*;
7+
8+
/**
9+
* A visitor implementation for NBT elements that converts them into debugger variables.
10+
* This class traverses NBT data structures and creates corresponding DebuggerVariable objects
11+
* that can be displayed in a debugging client.
12+
*
13+
* @author theogiraudet
14+
*/
15+
public class NbtElementVariableVisitor implements NbtElementVisitor {
16+
17+
private int index;
18+
private final Map<Integer, DebuggerVariable> variables = new HashMap<>();
19+
private DebuggerVariable returnVariable;
20+
private String currentName;
21+
private boolean isRoot;
22+
23+
/**
24+
* Creates a new NBT element visitor.
25+
*
26+
* @param index The starting index for variable IDs
27+
* @param rootName The name of the root variable
28+
* @param isRoot Whether this variable is a root-level variable
29+
*/
30+
public NbtElementVariableVisitor(int index, String rootName, boolean isRoot) {
31+
this.index = index;
32+
this.currentName = rootName;
33+
this.isRoot = isRoot;
34+
}
35+
36+
/**
37+
* Gets the map of created variables.
38+
*
39+
* @return A map of variable IDs to debugger variables
40+
*/
41+
public Map<Integer, DebuggerVariable> get() {
42+
return variables;
43+
}
44+
45+
/**
46+
* Visits a string NBT element and converts it to a debugger variable.
47+
*
48+
* @param element The string NBT element
49+
*/
50+
@Override
51+
public void visitString(NbtString element) {
52+
convertPrimitive(element);
53+
}
54+
55+
/**
56+
* Visits a byte NBT element and converts it to a debugger variable.
57+
*
58+
* @param element The byte NBT element
59+
*/
60+
@Override
61+
public void visitByte(NbtByte element) {
62+
convertPrimitive(element);
63+
}
64+
65+
/**
66+
* Visits a short NBT element and converts it to a debugger variable.
67+
*
68+
* @param element The short NBT element
69+
*/
70+
@Override
71+
public void visitShort(NbtShort element) {
72+
convertPrimitive(element);
73+
}
74+
75+
/**
76+
* Visits an int NBT element and converts it to a debugger variable.
77+
*
78+
* @param element The int NBT element
79+
*/
80+
@Override
81+
public void visitInt(NbtInt element) {
82+
convertPrimitive(element);
83+
}
84+
85+
/**
86+
* Visits a long NBT element and converts it to a debugger variable.
87+
*
88+
* @param element The long NBT element
89+
*/
90+
@Override
91+
public void visitLong(NbtLong element) {
92+
convertPrimitive(element);
93+
}
94+
95+
/**
96+
* Visits a float NBT element and converts it to a debugger variable.
97+
*
98+
* @param element The float NBT element
99+
*/
100+
@Override
101+
public void visitFloat(NbtFloat element) {
102+
convertPrimitive(element);
103+
}
104+
105+
/**
106+
* Visits a double NBT element and converts it to a debugger variable.
107+
*
108+
* @param element The double NBT element
109+
*/
110+
@Override
111+
public void visitDouble(NbtDouble element) {
112+
convertPrimitive(element);
113+
}
114+
115+
/**
116+
* Visits a byte array NBT element and converts it to a debugger variable.
117+
*
118+
* @param element The byte array NBT element
119+
*/
120+
@Override
121+
public void visitByteArray(NbtByteArray element) {
122+
convertList(element);
123+
}
124+
125+
/**
126+
* Visits an int array NBT element and converts it to a debugger variable.
127+
*
128+
* @param element The int array NBT element
129+
*/
130+
@Override
131+
public void visitIntArray(NbtIntArray element) {
132+
convertList(element);
133+
}
134+
135+
/**
136+
* Visits a long array NBT element and converts it to a debugger variable.
137+
*
138+
* @param element The long array NBT element
139+
*/
140+
@Override
141+
public void visitLongArray(NbtLongArray element) {
142+
convertList(element);
143+
}
144+
145+
/**
146+
* Visits a list NBT element and converts it to a debugger variable.
147+
*
148+
* @param element The list NBT element
149+
*/
150+
@Override
151+
public void visitList(NbtList element) {
152+
convertList(element);
153+
}
154+
155+
/**
156+
* Visits a compound NBT element and converts it to a debugger variable.
157+
* This method recursively processes all child elements of the compound.
158+
*
159+
* @param compound The compound NBT element
160+
*/
161+
@Override
162+
public void visitCompound(NbtCompound compound) {
163+
var children = new LinkedList<DebuggerVariable>();
164+
var compoundIndex = this.index++;
165+
var compoundVar = new DebuggerVariable(compoundIndex, this.currentName, compound.asString(), children, isRoot);
166+
isRoot = false;
167+
variables.put(compoundIndex, compoundVar);
168+
for(var key: compound.getKeys()) {
169+
this.currentName = key;
170+
Objects.requireNonNull(compound.get(key)).accept(this);
171+
children.add(returnVariable);
172+
}
173+
returnVariable = compoundVar;
174+
}
175+
176+
/**
177+
* Visits an end NBT element. Does nothing as end tags have no value.
178+
*
179+
* @param element The end NBT element
180+
*/
181+
@Override
182+
public void visitEnd(NbtEnd element) {}
183+
184+
/**
185+
* Converts an NBT list or array into debugger variables.
186+
* This method processes each element in the list and creates child variables.
187+
*
188+
* @param list The NBT list or array to convert
189+
*/
190+
private void convertList(AbstractNbtList<?> list) {
191+
var arrayIndex = index++;
192+
var array = new LinkedList<DebuggerVariable>();
193+
var name = currentName;
194+
var result = new DebuggerVariable(arrayIndex, name, list.asString(), array, false);
195+
variables.put(arrayIndex, result);
196+
for(int i = 0; i < list.size(); i++) {
197+
currentName = Integer.toString(index);
198+
list.get(i).accept(this);
199+
array.add(returnVariable);
200+
}
201+
index++;
202+
returnVariable = result;
203+
}
204+
205+
/**
206+
* Converts a primitive NBT element into a debugger variable.
207+
* Used for simple types like numbers and strings.
208+
*
209+
* @param element The primitive NBT element to convert
210+
*/
211+
private void convertPrimitive(NbtElement element) {
212+
var i = index++;
213+
returnVariable = new DebuggerVariable(i, currentName, element.asString(), List.of(), isRoot);
214+
variables.put(i, returnVariable);
215+
}
216+
}

src/main/java/net/gunivers/sniffer/dap/RealPath.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public record RealPath(String path, Kind kind) {
1717
public enum Kind {
1818
/** Indicates the resource is stored in a ZIP archive */
1919
ZIP,
20+
/** Indicates the resource is stored in a directory on the file system */
2021
DIRECTORY
2122
}
2223

src/main/java/net/gunivers/sniffer/dap/ScopeManager.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.gunivers.sniffer.dap;
22

3+
import net.minecraft.nbt.NbtCompound;
34
import net.minecraft.server.command.AbstractServerCommandSource;
45
import org.jetbrains.annotations.Nullable;
56
import net.minecraft.util.Identifier;
@@ -64,12 +65,14 @@ public static class DebugScope {
6465
* @param function The function mcpath being executed
6566
* @param executor The command source executing the function
6667
*/
67-
protected DebugScope(@Nullable DebugScope parent, String function, AbstractServerCommandSource<?> executor) {
68+
protected DebugScope(@Nullable DebugScope parent, String function, AbstractServerCommandSource<?> executor, NbtCompound macroVariables) {
6869
this.parent = parent;
6970
this.function = function;
7071
this.path = PATHS.get(function);
7172
this.executor = executor;
7273
this.variables = VariableManager.convertCommandSource(executor, ID);
74+
var macro = VariableManager.convertNbtCompound("macro", macroVariables, ID + this.variables.size(), true);
75+
this.variables.putAll(macro);
7376
ID += variables.size();
7477
}
7578

@@ -194,8 +197,8 @@ public Optional<String> getPath(String mcpath) {
194197
* @param function The function mcpath
195198
* @param executor The command source executing the function
196199
*/
197-
public void newScope(String function, AbstractServerCommandSource<?> executor) {
198-
var scope = new DebugScope(this.currentScope, function, executor);
200+
public void newScope(String function, AbstractServerCommandSource<?> executor, NbtCompound macroVariables) {
201+
var scope = new DebugScope(this.currentScope, function, executor, macroVariables);
199202
this.scopeIds.add(scope.id);
200203
this.debugScopeStack.push(scope);
201204
this.currentScope = scope;

src/main/java/net/gunivers/sniffer/dap/VariableManager.java

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

33
import net.minecraft.entity.Entity;
44
import net.minecraft.entity.EntityType;
5+
import net.minecraft.nbt.NbtCompound;
56
import net.minecraft.server.command.AbstractServerCommandSource;
67
import net.minecraft.server.command.ServerCommandSource;
78
import net.minecraft.util.Pair;
@@ -185,4 +186,24 @@ private static void flattenToMap(DebuggerVariable variable, Map<Integer, Debugge
185186
variable.children().forEach(child -> flattenToMap(child, variables));
186187
}
187188

189+
/**
190+
* Converts an NBT compound into a map of debugger variables.
191+
* This method uses a visitor pattern to traverse the NBT structure and create
192+
* corresponding debugger variables for each element.
193+
*
194+
* @param name The name of the root variable
195+
* @param compound The NBT compound to convert, may be null
196+
* @param startIndex The starting index for variable IDs
197+
* @param isRoot Whether this variable is a root-level variable
198+
* @return A map of variable IDs to debugger variables, or an empty map if compound is null
199+
*/
200+
public static Map<Integer, DebuggerVariable> convertNbtCompound(String name, NbtCompound compound, int startIndex, boolean isRoot) {
201+
if(compound != null) {
202+
var visitor = new NbtElementVariableVisitor(startIndex, name, isRoot);
203+
compound.accept(visitor);
204+
return visitor.get();
205+
}
206+
return Map.of();
207+
}
208+
188209
}

vscode/src/SocketDebugSession.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class SocketDebugSession extends ProtocolServer {
8686
private terminateSession() {
8787
console.log('WebSocket connection closed, terminating debug session');
8888
this.sendEvent(new TerminatedEvent());
89-
vscode.window.showWarningMessage('Connection reset detected, terminating debug session');
89+
// vscode.window.showWarningMessage('Connection reset detected, terminating debug session');
9090
}
9191
}
9292

0 commit comments

Comments
 (0)