src/language: fix strict type errors
For golang/vscode-go#57.
Change-Id: Iec4ee1a78692b913da6cc9f3ec9413367647da73
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/401618
Run-TryBot: Jamal Carvalho <jamal@golang.org>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/goTest/explore.ts b/src/goTest/explore.ts
index 67facfa..8477d50 100644
--- a/src/goTest/explore.ts
+++ b/src/goTest/explore.ts
@@ -272,8 +272,6 @@
const found = find(this.ctrl.items);
if (found) {
dispose(this.resolver, found);
- }
- if (found?.parent) {
disposeIfEmpty(this.resolver, found.parent);
}
}
diff --git a/src/goTest/run.ts b/src/goTest/run.ts
index 0fdb9f2..75f425d 100644
--- a/src/goTest/run.ts
+++ b/src/goTest/run.ts
@@ -675,11 +675,11 @@
}
let current: Location | undefined;
+ if (!test.uri) return messages;
+ const dir = Uri.joinPath(test.uri, '..');
for (const line of output) {
const m = line.match(/^\s*(?<file>.*\.go):(?<line>\d+): ?(?<message>.*\n)$/);
if (m?.groups) {
- if (!test.uri) return [];
- const dir = Uri.joinPath(test.uri, '..');
const file = Uri.joinPath(dir, m.groups.file);
const ln = Number(m.groups.line) - 1; // VSCode uses 0-based line numbering (internally)
current = new Location(file, new Position(ln, 0));
diff --git a/src/goTest/utils.ts b/src/goTest/utils.ts
index de62641..6a4c6f6 100644
--- a/src/goTest/utils.ts
+++ b/src/goTest/utils.ts
@@ -101,7 +101,8 @@
// Dispose of the item if it has no children, recursively. This facilitates
// cleaning up package/file trees that contain no tests.
-export function disposeIfEmpty(resolver: GoTestResolver, item: vscode.TestItem) {
+export function disposeIfEmpty(resolver: GoTestResolver, item: vscode.TestItem | undefined) {
+ if (!item) return;
// Don't dispose of empty top-level items
const { kind } = GoTest.parseId(item.id);
if (kind === 'module' || kind === 'workspace' || (kind === 'package' && !item.parent)) {
@@ -113,9 +114,7 @@
}
dispose(resolver, item);
- if (item.parent) {
- disposeIfEmpty(resolver, item.parent);
- }
+ disposeIfEmpty(resolver, item.parent);
}
// The 'name' group captures the module name, and the unnamed group ignores any comment that might follow the name.
diff --git a/src/language/goLanguageServer.ts b/src/language/goLanguageServer.ts
index 51f2903..3c8007c 100644
--- a/src/language/goLanguageServer.ts
+++ b/src/language/goLanguageServer.ts
@@ -68,7 +68,7 @@
serverName: string;
path: string;
version?: { version: string; goVersion?: string };
- modtime: Date;
+ modtime?: Date;
enabled: boolean;
flags: string[];
env: any;
@@ -84,14 +84,14 @@
// new configurations.
// TODO: refactor it. These can be encapsulated in a single LanguageServer class
// that keeps track of the state of the active language server instance.
-export let languageClient: LanguageClient;
-let languageServerDisposable: vscode.Disposable;
+export let languageClient: LanguageClient | undefined;
+let languageServerDisposable: vscode.Disposable | undefined;
export let latestConfig: LanguageServerConfig;
-export let serverOutputChannel: vscode.OutputChannel;
+export let serverOutputChannel: vscode.OutputChannel | undefined;
export let languageServerIsRunning = false;
// serverInfo is the information from the server received during initialization.
-export let serverInfo: ServerInfo = undefined;
+export let serverInfo: ServerInfo | undefined;
interface ServerInfo {
Name: string;
@@ -100,7 +100,7 @@
Commands?: string[];
}
-let legacyLanguageService: LegacyLanguageService = undefined;
+let legacyLanguageService: LegacyLanguageService | undefined;
const languageServerStartMutex = new Mutex();
@@ -165,7 +165,7 @@
}
}
const schemes = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.scheme);
- if (schemes?.length > 0 && !schemes.includes('file') && !schemes.includes('untitled')) {
+ if (schemes && schemes.length > 0 && !schemes.includes('file') && !schemes.includes('untitled')) {
outputChannel.appendLine(
`None of the folders in this workspace ${schemes.join(
','
@@ -288,7 +288,7 @@
export async function promptAboutGoplsOptOut() {
// Check if the configuration is set in the workspace.
const useLanguageServer = getGoConfig().inspect('useLanguageServer');
- const workspace = useLanguageServer.workspaceFolderValue === false || useLanguageServer.workspaceValue === false;
+ const workspace = useLanguageServer?.workspaceFolderValue === false || useLanguageServer?.workspaceValue === false;
let cfg = getGoplsOptOutConfig(workspace);
const promptFn = async (): Promise<GoplsOptOutConfig> => {
@@ -401,10 +401,10 @@
legacyLanguageService?.dispose();
legacyLanguageService = undefined;
- languageServerDisposable = languageClient.start();
- ctx.subscriptions.push(languageServerDisposable);
- await languageClient.onReady();
- serverInfo = toServerInfo(languageClient.initializeResult);
+ languageServerDisposable = languageClient?.start();
+ languageServerDisposable && ctx.subscriptions.push(languageServerDisposable);
+ await languageClient?.onReady();
+ serverInfo = toServerInfo(languageClient?.initializeResult);
console.log(`Server: ${JSON.stringify(serverInfo, null, 2)}`);
return true;
@@ -572,7 +572,7 @@
'Show Trace'
);
if (answer === 'Show Trace') {
- serverOutputChannel.show();
+ serverOutputChannel?.show();
}
return null;
}
@@ -596,10 +596,10 @@
): Promise<vscode.CodeLens[]> => {
const codeLens = await next(doc, token);
if (!codeLens || codeLens.length === 0) {
- return codeLens;
+ return codeLens ?? [];
}
return codeLens.reduce((lenses: vscode.CodeLens[], lens: vscode.CodeLens) => {
- switch (lens.command.title) {
+ switch (lens.command?.title) {
case 'run test': {
return [...lenses, ...createTestCodeLens(lens)];
}
@@ -753,7 +753,7 @@
// and selects only those the user explicitly specifies in their settings.
// This returns a new object created based on the filtered properties of workspaceConfig.
// Exported for testing.
-export function filterGoplsDefaultConfigValues(workspaceConfig: any, resource: vscode.Uri): any {
+export function filterGoplsDefaultConfigValues(workspaceConfig: any, resource?: vscode.Uri): any {
if (!workspaceConfig) {
workspaceConfig = {};
}
@@ -816,8 +816,8 @@
async function adjustGoplsWorkspaceConfiguration(
cfg: LanguageServerConfig,
workspaceConfig: any,
- section: string,
- resource: vscode.Uri
+ section?: string,
+ resource?: vscode.Uri
): Promise<any> {
// We process only gopls config
if (section !== 'gopls') {
@@ -843,19 +843,20 @@
// CodeLens argument signature in gopls is [fileName: string, testFunctions: string[], benchFunctions: string[]],
// so this needs to be deconstructured here
// Note that there will always only be one test function name in this context
- if (lens.command.arguments.length < 2 || lens.command.arguments[1].length < 1) {
+ if ((lens.command?.arguments?.length ?? 0) < 2 || (lens.command?.arguments?.[1].length ?? 0) < 1) {
return [lens];
}
return [
new vscode.CodeLens(lens.range, {
+ title: '',
...lens.command,
command: 'go.test.cursor',
- arguments: [{ functionName: lens.command.arguments[1][0] }]
+ arguments: [{ functionName: lens.command?.arguments?.[1][0] }]
}),
new vscode.CodeLens(lens.range, {
title: 'debug test',
command: 'go.debug.cursor',
- arguments: [{ functionName: lens.command.arguments[1][0] }]
+ arguments: [{ functionName: lens.command?.arguments?.[1][0] }]
})
];
}
@@ -864,19 +865,20 @@
// CodeLens argument signature in gopls is [fileName: string, testFunctions: string[], benchFunctions: string[]],
// so this needs to be deconstructured here
// Note that there will always only be one benchmark function name in this context
- if (lens.command.arguments.length < 3 || lens.command.arguments[2].length < 1) {
+ if ((lens.command?.arguments?.length ?? 0) < 3 || (lens.command?.arguments?.[2].length ?? 0) < 1) {
return [lens];
}
return [
new vscode.CodeLens(lens.range, {
+ title: '',
...lens.command,
command: 'go.benchmark.cursor',
- arguments: [{ functionName: lens.command.arguments[2][0] }]
+ arguments: [{ functionName: lens.command?.arguments?.[2][0] }]
}),
new vscode.CodeLens(lens.range, {
title: 'debug benchmark',
command: 'go.debug.cursor',
- arguments: [{ functionName: lens.command.arguments[2][0] }]
+ arguments: [{ functionName: lens.command?.arguments?.[2][0] }]
})
];
}
@@ -904,15 +906,15 @@
}
export function buildLanguageServerConfig(goConfig: vscode.WorkspaceConfiguration): LanguageServerConfig {
- let formatter: GoDocumentFormattingEditProvider;
+ let formatter: GoDocumentFormattingEditProvider | undefined;
if (usingCustomFormatTool(goConfig)) {
formatter = new GoDocumentFormattingEditProvider();
}
const cfg: LanguageServerConfig = {
serverName: '',
path: '',
- version: null, // compute version lazily
- modtime: null,
+ version: undefined, // compute version lazily
+ modtime: undefined,
enabled: goConfig['useLanguageServer'] === true,
flags: goConfig['languageServerFlags'] || [],
features: {
@@ -932,7 +934,7 @@
return cfg;
}
cfg.path = languageServerPath;
- cfg.serverName = getToolFromToolPath(cfg.path);
+ cfg.serverName = getToolFromToolPath(cfg.path) ?? '';
if (!cfg.enabled) {
return cfg;
@@ -958,7 +960,7 @@
* Return the absolute path to the correct binary. If the required tool is not available,
* prompt the user to install it. Only gopls is officially supported.
*/
-export function getLanguageServerToolPath(): string {
+export function getLanguageServerToolPath(): string | undefined {
const goConfig = getGoConfig();
// Check that all workspace folders are configured with the same GOPATH.
if (!allFoldersHaveSameGopath()) {
@@ -999,7 +1001,7 @@
function gopathsPerFolder(): string[] {
const result: string[] = [];
- for (const folder of vscode.workspace.workspaceFolders) {
+ for (const folder of vscode.workspace.workspaceFolders ?? []) {
result.push(getCurrentGoPath(folder.uri));
}
return result;
@@ -1009,7 +1011,7 @@
tool: Tool,
cfg: LanguageServerConfig,
mustCheck?: boolean
-): Promise<semver.SemVer> {
+): Promise<semver.SemVer | null | undefined> {
// Only support updating gopls for now.
if (tool.name !== 'gopls' || (!mustCheck && (cfg.checkForUpdates === 'off' || extensionInfo.isInCloudIDE))) {
return null;
@@ -1056,7 +1058,7 @@
// If the user has a pseudoversion, get the timestamp for the latest gopls version and compare.
if (usersTime) {
let latestTime = cfg.checkForUpdates
- ? await getTimestampForVersion(tool, latestVersion)
+ ? await getTimestampForVersion(tool, latestVersion!)
: tool.latestVersionTimestamp;
if (!latestTime) {
latestTime = tool.latestVersionTimestamp;
@@ -1070,7 +1072,7 @@
includePrerelease: true,
loose: true
});
- return semver.lt(usersVersionSemver, latestVersion) ? latestVersion : null;
+ return semver.lt(usersVersionSemver!, latestVersion!) ? latestVersion : null;
}
/**
@@ -1082,7 +1084,7 @@
* configuration.
* @returns true if the tool was updated
*/
-async function suggestUpdateGopls(tool: Tool, cfg: LanguageServerConfig): Promise<boolean> {
+async function suggestUpdateGopls(tool: Tool, cfg: LanguageServerConfig): Promise<boolean | undefined> {
const forceUpdatedGoplsKey = 'forceUpdateForGoplsOnDefault';
// forceUpdated is true when the process of updating has been succesfully completed.
const forceUpdated = getFromGlobalState(forceUpdatedGoplsKey, false);
@@ -1111,7 +1113,7 @@
// parseTimestampFromPseudoversion returns the timestamp for the given
// pseudoversion. The timestamp is the center component, and it has the
// format "YYYYMMDDHHmmss".
-function parseTimestampFromPseudoversion(version: string): moment.Moment {
+function parseTimestampFromPseudoversion(version: string): moment.Moment | null {
const split = version.split('-');
if (split.length < 2) {
return null;
@@ -1253,7 +1255,7 @@
async function goProxyRequest(tool: Tool, endpoint: string): Promise<any> {
// Get the user's value of GOPROXY.
// If it is not set, we cannot make the request.
- const output: string = process.env['GOPROXY'];
+ const output = process.env['GOPROXY'];
if (!output || !output.trim()) {
return null;
}
@@ -1309,7 +1311,7 @@
}
// Show the user the output channel content to alert them to the issue.
- serverOutputChannel.show();
+ serverOutputChannel?.show();
if (latestConfig.serverName !== 'gopls') {
return;
@@ -1336,7 +1338,7 @@
// If the user has invalid values for "go.languageServerFlags", we may get
// this error. Prompt them to double check their flags.
- let selected: string;
+ let selected: string | undefined;
if (failureReason === GoplsFailureModes.INCORRECT_COMMAND_USAGE) {
const languageServerFlags = getGoConfig()['languageServerFlags'] as string[];
if (languageServerFlags && languageServerFlags.length > 0) {
@@ -1445,8 +1447,8 @@
return;
}
// likely show() is asynchronous, despite the documentation
- serverOutputChannel.show();
- let found: vscode.TextDocument;
+ serverOutputChannel?.show();
+ let found: vscode.TextDocument | undefined;
for (const doc of vscode.workspace.textDocuments) {
if (doc.fileName.indexOf('extension-output-') !== -1) {
// despite show() above, this might not get the output we want, so check
@@ -1472,12 +1474,12 @@
}
async function collectGoplsLog(): Promise<{ sanitizedLog?: string; failureReason?: string }> {
- serverOutputChannel.show();
+ serverOutputChannel?.show();
// Find the logs in the output channel. There is no way to read
// an output channel directly, but we can find the open text
// document, since we just surfaced the output channel to the user.
// See https://github.com/microsoft/vscode/issues/65108.
- let logs: string;
+ let logs: string | undefined;
for (let i = 0; i < 10; i++) {
// try a couple of times until successfully finding the channel.
for (const doc of vscode.workspace.textDocuments) {
@@ -1572,5 +1574,5 @@
function languageServerUsingDefault(cfg: vscode.WorkspaceConfiguration): boolean {
const useLanguageServer = cfg.inspect<boolean>('useLanguageServer');
- return useLanguageServer.globalValue === undefined && useLanguageServer.workspaceValue === undefined;
+ return useLanguageServer?.globalValue === undefined && useLanguageServer?.workspaceValue === undefined;
}
diff --git a/src/language/legacy/goCodeAction.ts b/src/language/legacy/goCodeAction.ts
index 488a5a9..c08d1f0 100644
--- a/src/language/legacy/goCodeAction.ts
+++ b/src/language/legacy/goCodeAction.ts
@@ -20,7 +20,7 @@
const promises = context.diagnostics.map((diag) => {
// When a name is not found but could refer to a package, offer to add import
if (diag.message.indexOf('undefined: ') === 0) {
- const [, name] = /^undefined: (\S*)/.exec(diag.message);
+ const [, name] = /^undefined: (\S*)/.exec(diag.message) ?? [];
return listPackages().then((packages) => {
const commands = packages
.filter((pkg) => pkg === name || pkg.endsWith('/' + name))
diff --git a/src/language/legacy/goDeclaration.ts b/src/language/legacy/goDeclaration.ts
index 2a3f202..6b10364 100644
--- a/src/language/legacy/goDeclaration.ts
+++ b/src/language/legacy/goDeclaration.ts
@@ -29,12 +29,12 @@
const missingToolMsg = 'Missing tool: ';
export interface GoDefinitionInformation {
- file: string;
+ file?: string;
line: number;
column: number;
- doc: string;
+ doc?: string;
declarationlines: string[];
- name: string;
+ name?: string;
toolUsed: string;
}
@@ -63,10 +63,10 @@
export function definitionLocation(
document: vscode.TextDocument,
position: vscode.Position,
- goConfig: vscode.WorkspaceConfiguration,
+ goConfig: vscode.WorkspaceConfiguration | undefined,
includeDocs: boolean,
token: vscode.CancellationToken
-): Promise<GoDefinitionInformation> {
+): Promise<GoDefinitionInformation | null> {
const adjustedPos = adjustWordPosition(document, position);
if (!adjustedPos[0]) {
return Promise.resolve(null);
@@ -113,7 +113,7 @@
word.match(/^\d+.?\d+$/) ||
goKeywords.indexOf(word) > 0
) {
- return [false, null, null];
+ return [false, null!, null!];
}
if (position.isEqual(wordRange.end) && position.isAfter(wordRange.start)) {
position = position.translate(0, -1);
@@ -128,7 +128,7 @@
token: vscode.CancellationToken,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
useReceivers = true
-): Promise<GoDefinitionInformation> {
+): Promise<GoDefinitionInformation | null> {
const godefTool = 'godef';
const godefPath = getBinPath(godefTool);
if (!path.isAbsolute(godefPath)) {
@@ -137,12 +137,12 @@
const offset = byteOffsetAt(input.document, input.position);
const env = toolExecutionEnvironment();
env['GOROOT'] = getCurrentGoRoot();
- let p: cp.ChildProcess;
+ let p: cp.ChildProcess | null | undefined;
if (token) {
- token.onCancellationRequested(() => killProcessTree(p));
+ token.onCancellationRequested(() => p && killProcessTree(p));
}
- return new Promise<GoDefinitionInformation>((resolve, reject) => {
+ return new Promise((resolve, reject) => {
// Spawn `godef` process
const args = ['-t', '-i', '-f', input.document.fileName, '-o', offset.toString()];
// if (useReceivers) {
@@ -189,8 +189,8 @@
column: +col - 1,
declarationlines: lines.slice(1),
toolUsed: 'godef',
- doc: null,
- name: null
+ doc: undefined,
+ name: undefined
};
if (!input.includeDocs || godefImportDefinitionRegex.test(definitionInformation.declarationlines[0])) {
return resolve(definitionInformation);
@@ -212,7 +212,7 @@
}
});
if (p.pid) {
- p.stdin.end(input.document.getText());
+ p.stdin?.end(input.document.getText());
}
});
}
@@ -221,19 +221,19 @@
input: GoDefinitionInput,
token: vscode.CancellationToken,
useTags: boolean
-): Promise<GoDefinitionInformation> {
+): Promise<GoDefinitionInformation | null> {
const gogetdoc = getBinPath('gogetdoc');
if (!path.isAbsolute(gogetdoc)) {
return Promise.reject(missingToolMsg + 'gogetdoc');
}
const offset = byteOffsetAt(input.document, input.position);
const env = toolExecutionEnvironment();
- let p: cp.ChildProcess;
+ let p: cp.ChildProcess | null | undefined;
if (token) {
- token.onCancellationRequested(() => killProcessTree(p));
+ token.onCancellationRequested(() => p && killProcessTree(p));
}
- return new Promise<GoDefinitionInformation>((resolve, reject) => {
+ return new Promise((resolve, reject) => {
const gogetdocFlagsWithoutTags = [
'-u',
'-json',
@@ -266,7 +266,7 @@
const goGetDocOutput = <GoGetDocOuput>JSON.parse(stdout.toString());
const match = /(.*):(\d+):(\d+)/.exec(goGetDocOutput.pos);
const definitionInfo: GoDefinitionInformation = {
- file: null,
+ file: undefined,
line: 0,
column: 0,
toolUsed: 'gogetdoc',
@@ -286,7 +286,7 @@
}
});
if (p.pid) {
- p.stdin.end(getFileArchive(input.document));
+ p.stdin?.end(getFileArchive(input.document));
}
});
}
@@ -321,13 +321,13 @@
const guruOutput = <GuruDefinitionOuput>JSON.parse(stdout.toString());
const match = /(.*):(\d+):(\d+)/.exec(guruOutput.objpos);
const definitionInfo: GoDefinitionInformation = {
- file: null,
+ file: undefined,
line: 0,
column: 0,
toolUsed: 'guru',
declarationlines: [guruOutput.desc],
- doc: null,
- name: null
+ doc: undefined,
+ name: undefined
};
if (!match) {
return resolve(definitionInfo);
@@ -343,12 +343,12 @@
}
);
if (p.pid) {
- p.stdin.end(getFileArchive(input.document));
+ p.stdin?.end(getFileArchive(input.document));
}
});
}
-export function parseMissingError(err: any): [boolean, string] {
+export function parseMissingError(err: any): [boolean, string | null] {
if (err) {
// Prompt for missing tool is located here so that the
// prompts dont show up on hover or signature help
@@ -360,7 +360,7 @@
}
export class GoDefinitionProvider implements vscode.DefinitionProvider {
- private goConfig: vscode.WorkspaceConfiguration = null;
+ private goConfig: vscode.WorkspaceConfiguration | undefined;
constructor(goConfig?: vscode.WorkspaceConfiguration) {
this.goConfig = goConfig;
@@ -370,10 +370,10 @@
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
- ): Thenable<vscode.Location> {
+ ): Thenable<vscode.Location | null> {
return definitionLocation(document, position, this.goConfig, false, token).then(
(definitionInfo) => {
- if (definitionInfo === null || definitionInfo.file === null) {
+ if (!definitionInfo || !definitionInfo.file) {
return null;
}
const definitionResource = vscode.Uri.file(definitionInfo.file);
@@ -382,7 +382,7 @@
},
(err) => {
const miss = parseMissingError(err);
- if (miss[0]) {
+ if (miss[0] && miss[1]) {
promptForMissingTool(miss[1]);
} else if (err) {
return Promise.reject(err);
diff --git a/src/language/legacy/goExtraInfo.ts b/src/language/legacy/goExtraInfo.ts
index 1c5c84c..a5d162e 100644
--- a/src/language/legacy/goExtraInfo.ts
+++ b/src/language/legacy/goExtraInfo.ts
@@ -19,7 +19,7 @@
this.goConfig = goConfig;
}
- public provideHover(document: TextDocument, position: Position, token: CancellationToken): Thenable<Hover> {
+ public provideHover(document: TextDocument, position: Position, token: CancellationToken): Thenable<Hover | null> {
if (!this.goConfig) {
this.goConfig = getGoConfig(document.uri);
}
diff --git a/src/language/legacy/goImplementations.ts b/src/language/legacy/goImplementations.ts
index 68aa8b0..7414f75 100644
--- a/src/language/legacy/goImplementations.ts
+++ b/src/language/legacy/goImplementations.ts
@@ -41,7 +41,7 @@
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
- ): Thenable<vscode.Definition> {
+ ): Thenable<vscode.Definition | null> | undefined {
// To keep `guru implements` fast we want to restrict the scope of the search to current workspace
// If no workspace is open, then no-op
const root = getWorkspaceFolderPath(document.uri);
@@ -58,7 +58,7 @@
return;
}
- return new Promise<vscode.Definition>((resolve, reject) => {
+ return new Promise((resolve, reject) => {
if (token.isCancellationRequested) {
return resolve(null);
}
diff --git a/src/language/legacy/goLiveErrors.ts b/src/language/legacy/goLiveErrors.ts
index b70c671..3e24235 100644
--- a/src/language/legacy/goLiveErrors.ts
+++ b/src/language/legacy/goLiveErrors.ts
@@ -22,7 +22,7 @@
enabled: boolean;
}
-let runner: NodeJS.Timer;
+let runner: NodeJS.Timer | null;
export function goLiveErrorsEnabled() {
const goConfig = getGoConfig();
@@ -104,7 +104,7 @@
return;
}
// extract the line, column and error message from the gotype output
- const [, file, line, column, message] = /^(.+):(\d+):(\d+):\s+(.+)/.exec(error);
+ const [, file, line, column, message] = /^(.+):(\d+):(\d+):\s+(.+)/.exec(error) ?? [];
// get canonical file path
const canonicalFilePath = vscode.Uri.file(file).toString();
const range = new vscode.Range(+line - 1, +column, +line - 1, +column);
@@ -122,6 +122,6 @@
}
});
if (p.pid) {
- p.stdin.end(fileContents);
+ p.stdin?.end(fileContents);
}
}
diff --git a/src/language/legacy/goOutline.ts b/src/language/legacy/goOutline.ts
index 73d65d4..6c7e162 100644
--- a/src/language/legacy/goOutline.ts
+++ b/src/language/legacy/goOutline.ts
@@ -60,22 +60,24 @@
export async function documentSymbols(
options: GoOutlineOptions,
- token: vscode.CancellationToken
+ token?: vscode.CancellationToken
): Promise<vscode.DocumentSymbol[]> {
const decls = await runGoOutline(options, token);
- return convertToCodeSymbols(
- options.document,
- decls,
- options.importsOption !== GoOutlineImportsOptions.Exclude,
- makeMemoizedByteOffsetConverter(Buffer.from(options.document.getText()))
- );
+ return options.document
+ ? convertToCodeSymbols(
+ options.document,
+ decls,
+ options.importsOption !== GoOutlineImportsOptions.Exclude,
+ makeMemoizedByteOffsetConverter(Buffer.from(options.document.getText()))
+ )
+ : [];
}
export function runGoOutline(
options: GoOutlineOptions,
- token: vscode.CancellationToken
+ token?: vscode.CancellationToken
): Promise<GoOutlineDeclaration[]> {
- return new Promise<GoOutlineDeclaration[]>((resolve, reject) => {
+ return new Promise((resolve, reject) => {
const gooutline = getBinPath('go-outline');
const gooutlineFlags = ['-f', options.fileName];
if (options.importsOption === GoOutlineImportsOptions.Only) {
@@ -85,9 +87,9 @@
gooutlineFlags.push('-modified');
}
- let p: cp.ChildProcess;
+ let p: cp.ChildProcess | null | undefined;
if (token) {
- token.onCancellationRequested(() => killProcess(p));
+ token.onCancellationRequested(() => p && killProcess(p));
}
// Spawn `go-outline` process
@@ -102,7 +104,7 @@
options.importsOption = GoOutlineImportsOptions.Include;
}
if (stderr.startsWith('flag provided but not defined: -modified')) {
- options.document = null;
+ options.document = undefined;
}
p = null;
return runGoOutline(options, token).then((results) => {
@@ -110,7 +112,7 @@
});
}
if (err) {
- return resolve(null);
+ return resolve([]);
}
const result = stdout.toString();
const decls = <GoOutlineDeclaration[]>JSON.parse(result);
@@ -120,7 +122,7 @@
}
});
if (options.document && p.pid) {
- p.stdin.end(getFileArchive(options.document));
+ p.stdin?.end(getFileArchive(options.document));
}
});
}
@@ -198,7 +200,7 @@
public async provideDocumentSymbols(
document: vscode.TextDocument,
- token: vscode.CancellationToken
+ token?: vscode.CancellationToken
): Promise<vscode.DocumentSymbol[]> {
if (typeof this.includeImports !== 'boolean') {
const gotoSymbolConfig = getGoConfig(document.uri)['gotoSymbol'];
@@ -207,7 +209,7 @@
// TODO(suzmue): Check the commands available instead of the version.
if (languageClient && serverInfo?.Commands?.includes(GOPLS_LIST_IMPORTS)) {
- const symbols: vscode.DocumentSymbol[] = await vscode.commands.executeCommand(
+ const symbols: vscode.DocumentSymbol[] | undefined = await vscode.commands.executeCommand(
'vscode.executeDocumentSymbolProvider',
document.uri
);
@@ -265,7 +267,7 @@
return this.runGoOutline(document, token);
}
- private runGoOutline(document: vscode.TextDocument, token: vscode.CancellationToken) {
+ private runGoOutline(document: vscode.TextDocument, token?: vscode.CancellationToken) {
const options: GoOutlineOptions = {
fileName: document.fileName,
document,
@@ -276,7 +278,7 @@
}
async function listImports(document: vscode.TextDocument): Promise<{ Path: string; Name: string }[]> {
- const uri = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document).uri;
+ const uri = languageClient?.code2ProtocolConverter.asTextDocumentIdentifier(document).uri;
const params: ExecuteCommandParams = {
command: GOPLS_LIST_IMPORTS,
arguments: [
@@ -285,6 +287,6 @@
}
]
};
- const resp = await languageClient.sendRequest(ExecuteCommandRequest.type, params);
+ const resp = await languageClient?.sendRequest(ExecuteCommandRequest.type, params);
return resp.Imports;
}
diff --git a/src/language/legacy/goReferences.ts b/src/language/legacy/goReferences.ts
index 674a1b7..2239f25 100644
--- a/src/language/legacy/goReferences.ts
+++ b/src/language/legacy/goReferences.ts
@@ -96,7 +96,7 @@
}
});
if (process.pid) {
- process.stdin.end(getFileArchive(document));
+ process.stdin?.end(getFileArchive(document));
}
token.onCancellationRequested(() => killProcessTree(process));
});
diff --git a/src/language/legacy/goSignature.ts b/src/language/legacy/goSignature.ts
index e4f84a6..7163ef8 100755
--- a/src/language/legacy/goSignature.ts
+++ b/src/language/legacy/goSignature.ts
@@ -27,7 +27,7 @@
document: TextDocument,
position: Position,
token: CancellationToken
- ): Promise<SignatureHelp> {
+ ): Promise<SignatureHelp | null> {
let goConfig = this.goConfig || getGoConfig(document.uri);
const theCall = this.walkBackwardsToBeginningOfCall(document, position);
@@ -45,7 +45,7 @@
// The definition was not found
return null;
}
- if (res.line === callerPos.line) {
+ if (res.line === callerPos?.line) {
// This must be a function definition
return null;
}
@@ -54,8 +54,8 @@
return null;
}
const result = new SignatureHelp();
- let sig: string;
- let si: SignatureInformation;
+ let sig: string | undefined;
+ let si: SignatureInformation | undefined;
if (res.toolUsed === 'godef') {
// declaration is of the form "Add func(a int, b int) int"
const nameEnd = declarationText.indexOf(' ');
@@ -71,8 +71,9 @@
declarationText = declarationText.substring(funcNameStart);
}
si = new SignatureInformation(declarationText, res.doc);
- sig = declarationText.substring(res.name.length);
+ sig = declarationText.substring(res.name?.length ?? 0);
}
+ if (!si || !sig) return result;
si.parameters = getParametersAndReturnType(sig).params.map(
(paramText) => new ParameterInformation(paramText)
);
@@ -93,7 +94,7 @@
}
position = position.translate(0, -1);
}
- return null;
+ return position;
}
/**
diff --git a/src/language/legacy/goSuggest.ts b/src/language/legacy/goSuggest.ts
index 95afca8..ca39c89 100644
--- a/src/language/legacy/goSuggest.ts
+++ b/src/language/legacy/goSuggest.ts
@@ -65,7 +65,7 @@
class ExtendedCompletionItem extends vscode.CompletionItem {
public package?: string;
public receiver?: string;
- public fileName: string;
+ public fileName!: string;
}
const lineCommentFirstWordRegex = /^\s*\/\/\s+[\S]*$/;
@@ -77,10 +77,10 @@
private killMsgShown = false;
private setGocodeOptions = true;
private isGoMod = false;
- private globalState: vscode.Memento;
- private previousFile: string;
- private previousFileDir: string;
- private gocodeFlags: string[];
+ private globalState: vscode.Memento | undefined;
+ private previousFile?: string;
+ private previousFileDir?: string;
+ private gocodeFlags?: string[];
private excludeDocs = false;
constructor(globalState?: vscode.Memento) {
@@ -213,8 +213,9 @@
const pkgPath = this.getPackagePathFromLine(lineTillCurrentPosition);
if (pkgPath.length === 1) {
// Now that we have the package path, import it right after the "package" statement
- const v = parseFilePrelude(vscode.window.activeTextEditor.document.getText());
+ const v = parseFilePrelude(vscode.window.activeTextEditor?.document.getText() ?? '');
const pkg = v.pkg;
+ if (!pkg) return;
const posToAddImport = document.offsetAt(new vscode.Position(pkg.start + 1, 0));
const textToAdd = `import "${pkgPath[0]}"\n`;
inputText =
@@ -301,7 +302,7 @@
let stderr = '';
// stamblerre/gocode does not support -unimported-packages flags.
- if (this.isGoMod) {
+ if (this.isGoMod && this.gocodeFlags) {
const unimportedPkgIndex = this.gocodeFlags.indexOf('-unimported-packages');
if (unimportedPkgIndex >= 0) {
this.gocodeFlags.splice(unimportedPkgIndex, 1);
@@ -309,14 +310,14 @@
}
// -exclude-docs is something we use internally and is not related to gocode
- const excludeDocsIndex = this.gocodeFlags.indexOf('-exclude-docs');
- if (excludeDocsIndex >= 0) {
+ const excludeDocsIndex = this.gocodeFlags?.indexOf('-exclude-docs') ?? -1;
+ if (excludeDocsIndex >= 0 && this.gocodeFlags) {
this.gocodeFlags.splice(excludeDocsIndex, 1);
this.excludeDocs = true;
}
// Spawn `gocode` process
- const p = cp.spawn(gocode, [...this.gocodeFlags, 'autocomplete', filename, '' + offset], { env });
+ const p = cp.spawn(gocode, [...(this.gocodeFlags || []), 'autocomplete', filename, '' + offset], { env });
p.stdout.on('data', (data) => (stdout += data));
p.stderr.on('data', (data) => (stderr += data));
p.on('error', (err) => {
@@ -526,7 +527,7 @@
)
.then((selected) => {
if (selected === "Don't show again") {
- this.globalState.update(gocodeNoSupportForgbMsgKey, true);
+ this.globalState?.update(gocodeNoSupportForgbMsgKey, true);
}
});
}
@@ -537,7 +538,7 @@
const existingOptions = stdout.split(/\r\n|\n/);
const optionsToSet: string[][] = [];
const setOption = () => {
- const [name, value] = optionsToSet.pop();
+ const [name, value] = optionsToSet.pop() ?? [];
cp.execFile(gocode, ['set', name, value], { env }, () => {
if (optionsToSet.length) {
setOption();
@@ -603,14 +604,17 @@
* @param document The current document
* @param position The cursor position
*/
-function getCommentCompletion(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem {
+function getCommentCompletion(
+ document: vscode.TextDocument,
+ position: vscode.Position
+): vscode.CompletionItem | undefined {
const lineText = document.lineAt(position.line).text;
const lineTillCurrentPosition = lineText.substr(0, position.character);
// triggering completions in comments on exported members
if (lineCommentFirstWordRegex.test(lineTillCurrentPosition) && position.line + 1 < document.lineCount) {
const nextLine = document.lineAt(position.line + 1).text.trim();
const memberType = nextLine.match(exportedMemberRegex);
- let suggestionItem: vscode.CompletionItem;
+ let suggestionItem: vscode.CompletionItem | undefined;
if (memberType && memberType.length === 4) {
suggestionItem = new vscode.CompletionItem(memberType[3], vscodeKindFromGoCodeClass(memberType[1], ''));
}
diff --git a/src/language/legacy/goSymbol.ts b/src/language/legacy/goSymbol.ts
index 75588b6..0aab278 100644
--- a/src/language/legacy/goSymbol.ts
+++ b/src/language/legacy/goSymbol.ts
@@ -51,7 +51,7 @@
const pos = new vscode.Position(decl.line, decl.character);
const symbolInfo = new vscode.SymbolInformation(
decl.name,
- kind,
+ kind!,
new vscode.Range(pos, pos),
vscode.Uri.file(decl.path),
''
@@ -59,14 +59,13 @@
symbols.push(symbolInfo);
}
};
- const root = getWorkspaceFolderPath(
- vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.uri
- );
+ const root =
+ getWorkspaceFolderPath(vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.uri) ?? '';
const goConfig = getGoConfig();
if (!root && !goConfig.gotoSymbol.includeGoroot) {
vscode.window.showInformationMessage('No workspace is open to find symbols.');
- return;
+ return Promise.resolve([]);
}
return getWorkspaceSymbols(root, query, token, goConfig).then((results) => {
@@ -103,7 +102,7 @@
}
return Promise.all(calls)
- .then(([...results]) => <GoSymbolDeclaration[]>[].concat(...results))
+ .then(([...results]) => <GoSymbolDeclaration[]>[].concat(...(results as any)))
.catch((err: Error) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('go-symbols');
@@ -112,6 +111,7 @@
promptForUpdatingTool('go-symbols');
return getWorkspaceSymbols(workspacePath, query, token, goConfig, false);
}
+ return [];
});
}
diff --git a/src/language/legacy/goTypeDefinition.ts b/src/language/legacy/goTypeDefinition.ts
index c9c6e40..b4249b7 100644
--- a/src/language/legacy/goTypeDefinition.ts
+++ b/src/language/legacy/goTypeDefinition.ts
@@ -47,7 +47,7 @@
}
position = adjustedPos[2];
- return new Promise<vscode.Definition>((resolve, reject) => {
+ return new Promise<vscode.Definition | null>((resolve, reject) => {
const goGuru = getBinPath('guru');
if (!path.isAbsolute(goGuru)) {
promptForMissingTool('guru');
@@ -84,9 +84,9 @@
}
// Fall back to position of declaration
- return definitionLocation(document, position, null, false, token).then(
+ return definitionLocation(document, position, undefined, false, token).then(
(definitionInfo) => {
- if (definitionInfo === null || definitionInfo.file === null) {
+ if (!definitionInfo || !definitionInfo.file) {
return null;
}
const definitionResource = vscode.Uri.file(definitionInfo.file);
@@ -95,7 +95,7 @@
},
(err) => {
const miss = parseMissingError(err);
- if (miss[0]) {
+ if (miss[0] && miss[1]) {
promptForMissingTool(miss[1]);
} else if (err) {
return Promise.reject(err);
@@ -123,7 +123,7 @@
}
});
if (process.pid) {
- process.stdin.end(getFileArchive(document));
+ process.stdin?.end(getFileArchive(document));
}
token.onCancellationRequested(() => killProcessTree(process));
});