in src/goDeclaration.ts [126:218]
function definitionLocation_godef(
input: GoDefinitionInput,
token: vscode.CancellationToken,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
useReceivers = true
): Promise<GoDefinitionInformation> {
const godefTool = 'godef';
const godefPath = getBinPath(godefTool);
if (!path.isAbsolute(godefPath)) {
return Promise.reject(missingToolMsg + godefTool);
}
const offset = byteOffsetAt(input.document, input.position);
const env = toolExecutionEnvironment();
env['GOROOT'] = getCurrentGoRoot();
let p: cp.ChildProcess;
if (token) {
token.onCancellationRequested(() => killProcessTree(p));
}
return new Promise<GoDefinitionInformation>((resolve, reject) => {
// Spawn `godef` process
const args = ['-t', '-i', '-f', input.document.fileName, '-o', offset.toString()];
// if (useReceivers) {
// args.push('-r');
// }
p = cp.execFile(godefPath, args, { env, cwd: input.cwd }, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
return reject(missingToolMsg + godefTool);
}
if (err) {
if (
input.isMod &&
!input.includeDocs &&
stderr &&
stderr.startsWith('godef: no declaration found for')
) {
promptToUpdateToolForModules(
'godef',
'To get the Go to Definition feature when using Go modules, please update your version of the "godef" tool.'
);
return reject(stderr);
}
if (stderr.indexOf('flag provided but not defined: -r') !== -1) {
promptForUpdatingTool('godef');
p = null;
return definitionLocation_godef(input, token, false).then(resolve, reject);
}
return reject(err.message || stderr);
}
const result = stdout.toString();
const lines = result.split('\n');
let match = /(.*):(\d+):(\d+)/.exec(lines[0]);
if (!match) {
// TODO: Gotodef on pkg name:
// /usr/local/go/src/html/template\n
return resolve(null);
}
const [, file, line, col] = match;
const pkgPath = path.dirname(file);
const definitionInformation: GoDefinitionInformation = {
file,
line: +line - 1,
column: +col - 1,
declarationlines: lines.slice(1),
toolUsed: 'godef',
doc: null,
name: null
};
if (!input.includeDocs || godefImportDefinitionRegex.test(definitionInformation.declarationlines[0])) {
return resolve(definitionInformation);
}
match = /^\w+ \(\*?(\w+)\)/.exec(lines[1]);
runGodoc(input.cwd, pkgPath, match ? match[1] : '', input.word, token)
.then((doc) => {
if (doc) {
definitionInformation.doc = doc;
}
resolve(definitionInformation);
})
.catch((runGoDocErr) => {
console.log(runGoDocErr);
resolve(definitionInformation);
});
} catch (e) {
reject(e);
}
});
if (p.pid) {
p.stdin.end(input.document.getText());
}
});
}