in src/debugAdapter/goDebug.ts [1501:1662]
protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void {
log('ScopesRequest');
// TODO(polinasok): this.stackFrameHandles.get should succeed as long as DA
// clients behaves well. Find the documentation around stack frame management
// and in case of a failure caused by misbehavior, consider to indicate it
// in the error response.
const [goroutineId, frameId] = this.stackFrameHandles.get(args.frameId);
const listLocalVarsIn = { goroutineID: goroutineId, frame: frameId };
this.delve.call<DebugVariable[] | ListVarsOut>(
'ListLocalVars',
this.delve.isApiV1 ? [listLocalVarsIn] : [{ scope: listLocalVarsIn, cfg: this.delve.loadConfig }],
(err, out) => {
if (err) {
this.logDelveError(err, 'Failed to get list local variables');
return this.sendErrorResponse(response, 2005, 'Unable to list locals: "{e}"', {
e: err.toString()
});
}
const locals = this.delve.isApiV1 ? <DebugVariable[]>out : (<ListVarsOut>out).Variables;
log('locals', locals);
this.addFullyQualifiedName(locals);
const listLocalFunctionArgsIn = { goroutineID: goroutineId, frame: frameId };
this.delve.call<DebugVariable[] | ListFunctionArgsOut>(
'ListFunctionArgs',
this.delve.isApiV1
? [listLocalFunctionArgsIn]
: [{ scope: listLocalFunctionArgsIn, cfg: this.delve.loadConfig }],
(listFunctionErr, outArgs) => {
if (listFunctionErr) {
this.logDelveError(listFunctionErr, 'Failed to list function args');
return this.sendErrorResponse(response, 2006, 'Unable to list args: "{e}"', {
e: listFunctionErr.toString()
});
}
const vars = this.delve.isApiV1
? <DebugVariable[]>outArgs
: (<ListFunctionArgsOut>outArgs).Args;
log('functionArgs', vars);
this.addFullyQualifiedName(vars);
vars.push(...locals);
// annotate shadowed variables in parentheses
const shadowedVars = new Map<string, Array<number>>();
for (let i = 0; i < vars.length; ++i) {
if ((vars[i].flags & GoVariableFlags.VariableShadowed) === 0) {
continue;
}
const varName = vars[i].name;
if (!shadowedVars.has(varName)) {
const indices = new Array<number>();
indices.push(i);
shadowedVars.set(varName, indices);
} else {
shadowedVars.get(varName).push(i);
}
}
for (const svIndices of shadowedVars.values()) {
// sort by declared line number in descending order
svIndices.sort((lhs: number, rhs: number) => {
return vars[rhs].DeclLine - vars[lhs].DeclLine;
});
// enclose in parentheses, one pair per scope
for (let scope = 0; scope < svIndices.length; ++scope) {
const svIndex = svIndices[scope];
// start at -1 so scope of 0 has one pair of parens
for (let count = -1; count < scope; ++count) {
vars[svIndex].name = `(${vars[svIndex].name})`;
}
}
}
const scopes = new Array<Scope>();
const localVariables: DebugVariable = {
name: 'Local',
addr: 0,
type: '',
realType: '',
kind: 0,
flags: 0,
onlyAddr: false,
DeclLine: 0,
value: '',
len: 0,
cap: 0,
children: vars,
unreadable: '',
fullyQualifiedName: '',
base: 0
};
scopes.push(new Scope('Local', this.variableHandles.create(localVariables), false));
response.body = { scopes };
if (!this.showGlobalVariables) {
this.sendResponse(response);
log('ScopesResponse');
return;
}
this.getPackageInfo(this.debugState).then((packageName) => {
if (!packageName) {
this.sendResponse(response);
log('ScopesResponse');
return;
}
const filter = `^${packageName}\\.`;
this.delve.call<DebugVariable[] | ListVarsOut>(
'ListPackageVars',
this.delve.isApiV1 ? [filter] : [{ filter, cfg: this.delve.loadConfig }],
(listPkgVarsErr, listPkgVarsOut) => {
if (listPkgVarsErr) {
this.logDelveError(listPkgVarsErr, 'Failed to list global vars');
return this.sendErrorResponse(
response,
2007,
'Unable to list global vars: "{e}"',
{ e: listPkgVarsErr.toString() }
);
}
const globals = this.delve.isApiV1
? <DebugVariable[]>listPkgVarsOut
: (<ListVarsOut>listPkgVarsOut).Variables;
let initdoneIndex = -1;
for (let i = 0; i < globals.length; i++) {
globals[i].name = globals[i].name.substr(packageName.length + 1);
if (initdoneIndex === -1 && globals[i].name === this.initdone) {
initdoneIndex = i;
}
}
if (initdoneIndex > -1) {
globals.splice(initdoneIndex, 1);
}
log('global vars', globals);
const globalVariables: DebugVariable = {
name: 'Global',
addr: 0,
type: '',
realType: '',
kind: 0,
flags: 0,
onlyAddr: false,
DeclLine: 0,
value: '',
len: 0,
cap: 0,
children: globals,
unreadable: '',
fullyQualifiedName: '',
base: 0
};
scopes.push(
new Scope('Global', this.variableHandles.create(globalVariables), false)
);
this.sendResponse(response);
log('ScopesResponse');
}
);
});
}
);
}
);
}