- [NEW] Se mostren les variables locals i upvalues segons en el frame del stack que estem

- [NEW] Breakpoints condicionals
- [NEW] Es poden modificar totes les variables del joc des de la finestra VARIABLES de vscode
This commit is contained in:
2026-03-31 13:01:41 +02:00
parent ecd24bd2e0
commit 8c3c50eae1

View File

@@ -30,18 +30,10 @@ constructor() {
this._nextRef = 1000; // IDs únicos para tablas
this._pendingEval = null;
this.programStarted = false;
this._nextVarRef = 100;
this._varRefMap = new Map();
}
//initializeRequest(response, args) {
// this.sendEvent(new InitializedEvent());
//
// response.body = {
// supportsConfigurationDoneRequest: true
// };
//
// this.sendResponse(response);
//}
initializeRequest(response, args) {
console.log("[ADAPTER] initializeRequest");
this.sendEvent(new InitializedEvent());
@@ -50,7 +42,7 @@ constructor() {
supportsConfigurationDoneRequest: true,
supportsEvaluateForHovers: true,
supportsStepBack: false,
supportsSetVariable: false,
supportsSetVariable: true,
supportsRestartFrame: false,
supportsGotoTargetsRequest: false,
supportsStepInTargetsRequest: false,
@@ -59,12 +51,12 @@ constructor() {
supportsExceptionInfoRequest: false,
supportsDelayedStackTraceLoading: false,
supportsLoadedSourcesRequest: false,
supportsLogPoints: false,
supportsLogPoints: true,
supportsTerminateRequest: true,
supportsTerminateDebuggee: true,
supportsFunctionBreakpoints: false,
supportsConditionalBreakpoints: false,
supportsHitConditionalBreakpoints: false,
supportsConditionalBreakpoints: true,
supportsHitConditionalBreakpoints: true,
supportsConfigurationDoneRequest: true,
supportsSetExpression: false,
supportsClipboardContext: false,
@@ -218,6 +210,17 @@ constructor() {
return;
}
if (json.type === "setVariable") {
if (this._pendingSetVariable) {
//const newValue = String(msg.payload.value);
this._pendingSetVariable.body = {
value: json.payload.value
};
this.sendResponse(this._pendingSetVariable);
this._pendingSetVariable = null;
}
}
// salida normal
this.sendEvent(new OutputEvent(line + "\n", "stdout"));
}
@@ -232,6 +235,7 @@ constructor() {
cwd: cwd,
stdio: ['pipe', 'pipe', 'pipe']
});
this.programStarted = true;
this.stdoutBuffer = "";
@@ -259,12 +263,12 @@ constructor() {
// 3. Ahora que stdout ya está conectado, enviar breakpoints
if (this.breakpoints) {
for (const path in this.breakpoints) {
const lines = this.breakpoints[path];
//const lines = this.breakpoints[path];
this.sendDebugCommand({
cmd: "setBreakpoints",
file: path,
lines: lines
breakpoints: this.breakpoints[path] //lines
});
}
}
@@ -305,14 +309,20 @@ constructor() {
if (!this.breakpoints)
this.breakpoints = {};
this.breakpoints[path] = lines;
//this.breakpoints[path] = lines;
this.breakpoints[path] = clientBreakpoints.map(bp => ({
line: bp.line,
condition: bp.condition || null,
logMessage: bp.logMessage || null,
hitCondition: bp.hitCondition || null
}));
// Si el programa YA está corriendo → enviar breakpoints al motor
if (this.programStarted) {
this.sendDebugCommand({
cmd: "setBreakpoints",
file: path,
lines: lines
breakpoints: this.breakpoints[path]
});
}
@@ -326,42 +336,6 @@ constructor() {
this.sendResponse(response);
}
/*setBreakPointsRequest(response, args) {
const path = args.source.path; // archivo donde se han puesto breakpoints
const clientBreakpoints = args.breakpoints || [];
// Extraemos solo las líneas
const lines = clientBreakpoints.map(bp => bp.line);
// Guardamos internamente los breakpoints
if (!this.breakpoints)
this.breakpoints = {};
this.breakpoints[path] = lines;
// Enviamos los breakpoints a tu aplicación por stdin
const msg = {
cmd: "setBreakpoints",
file: path,
lines: lines
};
this.sendDebugCommand(msg);
//this.process.stdin.write(
// "@@DEBUGCMD@@" + JSON.stringify(msg) + "\n"
//);
// VSCode necesita una respuesta con los breakpoints "verificados"
response.body = {
breakpoints: lines.map(line => ({
verified: true,
line: line
}))
};
this.sendResponse(response);
}*/
continueRequest(response, args) {
const msg = {
cmd: "continue"
@@ -380,38 +354,6 @@ constructor() {
this.sendResponse(response);
}
stackTraceRequest(response, args) {
// Pedimos al motor el stack trace
this.sendDebugCommand({ cmd: "stackTrace" });
// IMPORTANTE: el motor responde async, así que esperamos
// a que llegue el mensaje @@DEBUG@@ con type=stackTrace
const check = () => {
if (this._stackFrames.length > 0) {
const frames = this._stackFrames;
this._stackFrames = [];
response.body = {
stackFrames: frames.map((f, i) => ({
id: i + 1,
name: f.name,
source: { path: f.file },
line: f.line,
column: 1
})),
totalFrames: frames.length
};
this.sendResponse(response);
} else {
setTimeout(check, 5);
}
};
check();
}
disconnectRequest(response, args) {
console.log("[ADAPTER] disconnectRequest");
@@ -474,7 +416,7 @@ constructor() {
response.body = {
stackFrames: frames.map((f, i) => ({
id: i + 1,
id: i,
name: f.name,
source: { path: f.file },
line: f.line,
@@ -482,6 +424,7 @@ constructor() {
})),
totalFrames: frames.length
};
this._lastFrames = frames;
this.sendResponse(response);
} else {
@@ -492,16 +435,22 @@ constructor() {
check();
}
makeVarRef(type, frameId) {
const ref = this._nextVarRef++;
this._varRefMap.set(ref, { type, frameId });
return ref;
}
// Aún no tiene en cuenta el frame
scopesRequest(response, args) {
console.log("[ADAPTER] scopesRequest, frameId =", args.frameId);
const frameId = args.frameId;
response.body = {
scopes: [
new Scope("Locals", 1, false),
new Scope("Upvalues", 2, false),
new Scope("Globals", 3, true)
]
new Scope("Locals", this.makeVarRef("locals", frameId), false),
new Scope("Upvalues", this.makeVarRef("upvalues", frameId), false),
new Scope("Globals", this.makeVarRef("globals", frameId), true) ]
};
this.sendResponse(response);
@@ -509,25 +458,29 @@ constructor() {
variablesRequest(response, args) {
console.log("[ADAPTER] variablesRequest ref =", args.variablesReference);
const info = this._varRefMap.get(args.variablesReference);
if (args.variablesReference === 1) {
if (info) {
const { type, frameId } = info;
if (type === "locals") {
this._pendingLocals = response;
this.sendDebugCommand({ cmd: "locals" });
this.sendDebugCommand({ cmd: "locals", frame: frameId });
return;
}
if (args.variablesReference === 2) {
if (type === "upvalues") {
this._pendingUpvalues = response;
this.sendDebugCommand({ cmd: "upvalues" });
this.sendDebugCommand({ cmd: "upvalues", frame: frameId });
return;
}
if (args.variablesReference === 3) {
if (type === "globals") {
this._pendingGlobals = response;
this.sendDebugCommand({ cmd: "globals" });
return;
}
}
// Expansión de tablas
if (args.variablesReference >= 1000) {
const luaRef = this._refTable.get(args.variablesReference);
@@ -560,6 +513,42 @@ constructor() {
});
}
setVariableRequest(response, args) {
const { variablesReference, name, value } = args;
// Caso 1: locals/upvalues/globals
const info = this._varRefMap.get(variablesReference);
if (info) {
this._pendingSetVariable = response;
this.sendDebugCommand({
cmd: "setVariable",
frame: info.frameId,
scope: info.type,
name: name,
value: value
});
return;
}
// Caso 2: miembros de tabla
if (variablesReference >= 1000) {
const luaRef = this._refTable.get(variablesReference);
this._pendingSetVariable = response;
this.sendDebugCommand({
cmd: "setTableField",
ref: luaRef,
key: name,
value: value
});
return;
}
// fallback
response.body = { value: value };
this.sendResponse(response);
}
configurationDoneRequest(response, args) {
console.log("[ADAPTER] configurationDoneRequest");
this.sendResponse(response);