Skip to content

Commit 597e5fb

Browse files
authored
Merge pull request #2 from sewbacca/master
Allowing inspection of functions
2 parents b5cb6c3 + ca5162a commit 597e5fb

7 files changed

Lines changed: 933 additions & 131 deletions

File tree

debugger/debugger.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,11 @@ export namespace Debugger {
773773
if (s) {
774774
if (type(r) === "table") {
775775
Send.props(r as AnyTable, kind, tonumber(first), tonumber(count));
776+
} else if (type(r) === "function") {
777+
// eslint-disable-next-line @typescript-eslint/ban-types
778+
Send.functionUpvalues(r as Function);
776779
} else {
777-
Send.error(`Expression "${mappedExpression}" is not a table`);
780+
Send.error(`Expression "${mappedExpression}" is not a table nor a function`);
778781
}
779782
} else {
780783
Send.error(r as string);
@@ -1190,6 +1193,16 @@ export namespace Debugger {
11901193
}
11911194
}
11921195
}
1196+
1197+
debug.setmetatable(() => { }, {
1198+
__index(key: string) {
1199+
const info = debug.getinfo(this, "fu");
1200+
if (!info) return undefined;
1201+
const val = getUpvalues(info).vars[key];
1202+
if (!val) return undefined;
1203+
return val.val;
1204+
}
1205+
});
11931206
};
11941207

11951208
export function clearHook(): void {
@@ -1211,6 +1224,8 @@ export namespace Debugger {
12111224
debug.sethook(thread);
12121225
}
12131226
}
1227+
1228+
debug.setmetatable(() => { }, undefined);
12141229
}
12151230

12161231
const breakInCoroutinesEnv: LuaDebug.BreakInCoroutinesEnv = "LOCAL_LUA_DEBUGGER_BREAK_IN_COROUTINES";

debugger/send.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
//SOFTWARE.
2222

23-
import {luaError, luaLenMetamethodSupported, luaRawLen} from "./luafuncs";
23+
import {luaAssert, luaError, luaLenMetamethodSupported, luaRawLen} from "./luafuncs";
2424
import {Format} from "./format";
2525
import {Vars} from "./debugger";
2626
import {Thread, mainThread, mainThreadName} from "./thread";
@@ -197,6 +197,37 @@ export namespace Send {
197197
send(dbgProperties);
198198
}
199199

200+
function getUpvalues(info: debug.FunctionInfo): { [name: string]: unknown } {
201+
const ups: { [name: string]: unknown } = { };
202+
203+
if (!info.nups || !info.func) {
204+
return ups;
205+
}
206+
207+
for (const index of $range(1, info.nups)) {
208+
const [name, val] = debug.getupvalue(info.func, index);
209+
ups[luaAssert(name)] = val;
210+
}
211+
212+
return ups;
213+
}
214+
215+
// eslint-disable-next-line @typescript-eslint/ban-types
216+
export function functionUpvalues(f: Function): void {
217+
const dbgProperties: LuaDebug.Properties = {
218+
tag: "$luaDebug",
219+
type: "properties",
220+
properties: Format.makeExplicitArray()
221+
};
222+
const upvalues = getUpvalues(debug.getinfo(f, "fu") as debug.FunctionInfo);
223+
for (const [key, val] of pairs(upvalues)) {
224+
const name = getPrintableValue(key);
225+
const dbgVar = buildVariable(name, val);
226+
table.insert(dbgProperties.properties, dbgVar);
227+
}
228+
send(dbgProperties);
229+
}
230+
200231
export function breakpoints(breaks: Breakpoint[]): void {
201232
const breakpointList: LuaDebug.Breakpoint[] = [];
202233
for (const breakpoint of breaks) {

extension/luaDebugSession.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,10 @@ export class LuaDebugSession extends LoggingDebugSession {
728728
return {success: true, value: "nil", variablesReference: 0};
729729
} else if (msg.results.length === 1) {
730730
const result = msg.results[0];
731-
const variablesReference = result.type === "table" ? this.variableHandles.create(expression) : 0;
731+
const variablesReference = (result.type === "table" || result.type === "function")
732+
? this.variableHandles.create(expression)
733+
: 0;
734+
732735
return {success: true, value: this.getValueString(result), variablesReference};
733736
} else {
734737
const variablesReference = this.variableHandles.create(`@({${expression}})`);
@@ -754,7 +757,7 @@ export class LuaDebugSession extends LoggingDebugSession {
754757
? `[error: ${this.filterErrorMessage(variable.error)}]`
755758
: `(${variable.value ?? ""})`;
756759
ref = variable.type === "table" ? this.variableHandles.create("@({...})") : 0;
757-
} else if (variable.type === "table") {
760+
} else if (variable.type === "table" || variable.type === "function") {
758761
valueStr = this.getValueString(variable);
759762
ref = this.variableHandles.create(refName);
760763
} else {
@@ -764,7 +767,7 @@ export class LuaDebugSession extends LoggingDebugSession {
764767
const indexedVariables = typeof variable.length !== "undefined" && variable.length > 0
765768
? variable.length + 1
766769
: variable.length;
767-
if (variable.type === "table") {
770+
if (variable.type === "table" || variable.type === "function") {
768771
return new Variable(name, valueStr, ref, indexedVariables, 1);
769772
} else {
770773
return new Variable(name, valueStr, ref, indexedVariables);

0 commit comments

Comments
 (0)