sync: merge microsoft/vscode-go@efb94c8 into master

Change-Id: Ia05ff126a38fde31743c1ad72091b9e5b9e334e0
diff --git a/.travis.yml b/.travis.yml
index b15bd22..b454685 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,18 +17,19 @@
 
 os:
   - osx
+  - linux
 
 before_install:
   # Call xvfb directly on linux runs and give it time to start
   - if [[ $TRAVIS_OS_NAME == "linux" ]]; then
     export DISPLAY=:99.0;
-    Xvfb :99 &
+    Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
     sleep 3;
     sudo apt-get update && sudo apt-get install -y libsecret-1-0;
     fi
 
 install:
-  - TRAVIS_NODE_VERSION="6";
+  - TRAVIS_NODE_VERSION="8";
   # Clear out whatever version of NVM Travis has as it is old.
   - rm -rf ~/.nvm;
     # Grab NVM.
@@ -49,7 +50,7 @@
   - go get -u -v github.com/ramya-rao-a/go-outline
   - go get -u -v github.com/rogpeppe/godef
   - go get -u -v github.com/sqs/goreturns
-  - go get -u -v github.com/uudashr/gopkgs/cmd/gopkgs
+  - go get -u -v github.com/uudashr/gopkgs/v2/cmd/gopkgs
   - go get -u -v github.com/zmb3/gogetdoc
   - go get -u -v golang.org/x/lint/golint
   - go get -u -v golang.org/x/tools/cmd/gorename
diff --git a/README.md b/README.md
index 4dcf26e..d5f4900 100644
--- a/README.md
+++ b/README.md
@@ -107,7 +107,7 @@
 
 This extension uses a set of Go tools to provide the various rich features. These tools are installed in your GOPATH by default. If you wish to have these tools in a separate location, provide the desired location in the setting `go.toolsGopath`. Read more about this and the tools at [Go tools that the Go extension depends on](https://github.com/Microsoft/vscode-go/wiki/Go-tools-that-the-Go-extension-depends-on).
 
-You will see `Analysis Tools Missing` in the bottom right, clicking this will offer to install all of the dependent Go tools. You can also run the [command](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) `Go: Install/Update tools` to install/update the same.
+You will see `Analysis Tools Missing` in the bottom right, clicking this will offer to install all of the dependent Go tools. You can also run the [command](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) `Go: Install/Update tools` to install/update the same. You need to have git installed for these tool installations to work.
 
 **Note 1**: Read [GOPATH in the VS Code Go extension](https://github.com/Microsoft/vscode-go/wiki/GOPATH-in-the-VS-Code-Go-extension) to learn about the different ways you can get the extension to set GOPATH.
 
diff --git a/build/Dockerfile b/build/Dockerfile
index 6f55594..97fd3c0 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:latest AS gobuilder
+FROM golang:1.14 AS gobuilder
 
 ENV GO111MODULE on
 ENV GOBIN /gobin
@@ -29,7 +29,7 @@
   	github.com/ramya-rao-a/go-outline \
   	github.com/rogpeppe/godef \
   	github.com/sqs/goreturns \
-  	github.com/uudashr/gopkgs/cmd/gopkgs \
+  	github.com/uudashr/gopkgs/v2/cmd/gopkgs \
   	github.com/zmb3/gogetdoc \
   	golang.org/x/lint/golint \
   	golang.org/x/tools/cmd/gorename
diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts
index 0e02e2b..a9a309e 100644
--- a/src/debugAdapter/goDebug.ts
+++ b/src/debugAdapter/goDebug.ts
@@ -256,7 +256,6 @@
 	stackTraceDepth: number;
 
 	showGlobalVariables?: boolean;
-	currentFile: string;
 	packagePathToGoModPathMap: { [key: string]: string };
 }
 
@@ -282,7 +281,6 @@
 	stackTraceDepth: number;
 
 	showGlobalVariables?: boolean;
-	currentFile: string;
 }
 
 process.on('uncaughtException', (err: any) => {
@@ -427,46 +425,46 @@
 
 				if (!!launchArgs.noDebug) {
 					if (mode === 'debug') {
-						if (isProgramDirectory && launchArgs.currentFile) {
-							program = launchArgs.currentFile;
-							isProgramDirectory = false;
+						this.noDebug = true;
+						const runArgs = ['run'];
+						const runOptions: { [key: string]: any } = { env };
+						if (launchArgs.buildFlags) {
+							runArgs.push(launchArgs.buildFlags);
+						}
+						if (isProgramDirectory) {
+							runOptions.cwd = program;
+							runArgs.push('.');
+						} else {
+							runArgs.push(program);
+						}
+						if (launchArgs.args) {
+							runArgs.push(...launchArgs.args);
 						}
 
-						if (!isProgramDirectory) {
-							this.noDebug = true;
-							const runArgs = ['run'];
-							if (launchArgs.buildFlags) {
-								runArgs.push(launchArgs.buildFlags);
+						this.debugProcess = spawn(getBinPathWithPreferredGopath('go', []), runArgs, runOptions);
+						this.debugProcess.stderr.on('data', (chunk) => {
+							const str = chunk.toString();
+							if (this.onstderr) {
+								this.onstderr(str);
 							}
-							runArgs.push(program);
-							if (launchArgs.args) {
-								runArgs.push(...launchArgs.args);
+						});
+						this.debugProcess.stdout.on('data', (chunk) => {
+							const str = chunk.toString();
+							if (this.onstdout) {
+								this.onstdout(str);
 							}
-							this.debugProcess = spawn(getBinPathWithPreferredGopath('go', []), runArgs, { env });
-							this.debugProcess.stderr.on('data', (chunk) => {
-								const str = chunk.toString();
-								if (this.onstderr) {
-									this.onstderr(str);
-								}
-							});
-							this.debugProcess.stdout.on('data', (chunk) => {
-								const str = chunk.toString();
-								if (this.onstdout) {
-									this.onstdout(str);
-								}
-							});
-							this.debugProcess.on('close', (code) => {
-								logError('Process exiting with code: ' + code);
-								if (this.onclose) {
-									this.onclose(code);
-								}
-							});
-							this.debugProcess.on('error', (err) => {
-								reject(err);
-							});
-							resolve();
-							return;
-						}
+						});
+						this.debugProcess.on('close', (code) => {
+							logError('Process exiting with code: ' + code);
+							if (this.onclose) {
+								this.onclose(code);
+							}
+						});
+						this.debugProcess.on('error', (err) => {
+							reject(err);
+						});
+						resolve();
+						return;
 					}
 				}
 				this.noDebug = false;
@@ -702,7 +700,7 @@
 					await this.callPromise('Detach', [this.isApiV1 ? true : { Kill: isLocalDebugging }]);
 				} catch (err) {
 					log('DetachResponse');
-					logError(err, 'Failed to detach');
+					logError(`Failed to detach - ${err.toString() || ''}`);
 					shouldForceClean = isLocalDebugging;
 				}
 			}
@@ -841,8 +839,7 @@
 		// So, update it to use the same separator as the remote path to ease
 		// in replacing the local path in it with remote path
 		filePath = filePath.replace(/\/|\\/g, this.remotePathSeparator);
-		return filePath
-			.replace(this.delve.program.replace(/\/|\\/g, this.remotePathSeparator), this.delve.remotePath);
+		return filePath.replace(this.delve.program.replace(/\/|\\/g, this.remotePathSeparator), this.delve.remotePath);
 	}
 
 	protected toLocalPath(pathToConvert: string): string {
@@ -1852,7 +1849,8 @@
 		// https://github.com/go-delve/delve/issues/852
 		// This affects macOS only although we're agnostic of the OS at this stage, only handle the error
 		if (errorMessage === 'bad access') {
-			errorMessage = 'unpropagated fatalpanic: signal SIGSEGV (EXC_BAD_ACCESS). This fatalpanic is not traceable on macOS, see https://github.com/go-delve/delve/issues/852';
+			errorMessage =
+				'unpropagated fatalpanic: signal SIGSEGV (EXC_BAD_ACCESS). This fatalpanic is not traceable on macOS, see https://github.com/go-delve/delve/issues/852';
 		}
 
 		logError(message + ' - ' + errorMessage);
@@ -1887,39 +1885,40 @@
 			Object.assign(stackTraceIn, { full: false, cfg: this.delve.loadConfig });
 		}
 		this.delve.call<DebugLocation[] | StacktraceOut>(
-			this.delve.isApiV1 ?
-				'StacktraceGoroutine' : 'Stacktrace', [stackTraceIn], (err, out) => {
-					if (err) {
-						logError('dumpStacktrace: Failed to produce stack trace' + err);
-						return;
-					}
-					const locations = this.delve.isApiV1 ? <DebugLocation[]>out : (<StacktraceOut>out).Locations;
-					log('locations', locations);
-					const stackFrames = locations.map((location, frameId) => {
-						const uniqueStackFrameId = this.stackFrameHandles.create([goroutineId, frameId]);
-						return new StackFrame(
-							uniqueStackFrameId,
-							location.function ? location.function.name : '<unknown>',
-							location.file === '<autogenerated>' ? null : new Source(
-								path.basename(location.file),
-								this.toLocalPath(location.file)
-							),
-							location.line,
-							0
-						);
-					});
-
-					// Dump stacktrace into error logger
-					logError(`Last known immediate stacktrace (goroutine id ${goroutineId}):`);
-					let output = '';
-					stackFrames.forEach((stackFrame) => {
-						output = output.concat(`\t${stackFrame.source.path}:${stackFrame.line}\n`);
-						if (stackFrame.name) {
-							output = output.concat(`\t\t${stackFrame.name}\n`);
-						}
-					});
-					logError(output);
+			this.delve.isApiV1 ? 'StacktraceGoroutine' : 'Stacktrace',
+			[stackTraceIn],
+			(err, out) => {
+				if (err) {
+					logError('dumpStacktrace: Failed to produce stack trace' + err);
+					return;
+				}
+				const locations = this.delve.isApiV1 ? <DebugLocation[]>out : (<StacktraceOut>out).Locations;
+				log('locations', locations);
+				const stackFrames = locations.map((location, frameId) => {
+					const uniqueStackFrameId = this.stackFrameHandles.create([goroutineId, frameId]);
+					return new StackFrame(
+						uniqueStackFrameId,
+						location.function ? location.function.name : '<unknown>',
+						location.file === '<autogenerated>'
+							? null
+							: new Source(path.basename(location.file), this.toLocalPath(location.file)),
+						location.line,
+						0
+					);
 				});
+
+				// Dump stacktrace into error logger
+				logError(`Last known immediate stacktrace (goroutine id ${goroutineId}):`);
+				let output = '';
+				stackFrames.forEach((stackFrame) => {
+					output = output.concat(`\t${stackFrame.source.path}:${stackFrame.line}\n`);
+					if (stackFrame.name) {
+						output = output.concat(`\t\t${stackFrame.name}\n`);
+					}
+				});
+				logError(output);
+			}
+		);
 	}
 }
 
diff --git a/src/goDebugConfiguration.ts b/src/goDebugConfiguration.ts
index a9b50a5..e4cad2a 100644
--- a/src/goDebugConfiguration.ts
+++ b/src/goDebugConfiguration.ts
@@ -109,8 +109,6 @@
 			debugConfiguration['mode'] =

 				activeEditor && activeEditor.document.fileName.endsWith('_test.go') ? 'test' : 'debug';

 		}

-		debugConfiguration['currentFile'] =

-			activeEditor && activeEditor.document.languageId === 'go' && activeEditor.document.fileName;

 

 		const neverAgain = { title: `Don't Show Again` };

 		const ignoreWarningKey = 'ignoreDebugLaunchRemoteWarning';

diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index a2be111..524bd3e 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -362,7 +362,7 @@
 	const updateMsg = `Your version of ${tool.name} appears to be out of date. Please update for an improved experience.`;
 	const choices: string[] = ['Update'];
 	if (toolName === `gopls`) {
-		choices.push('Release Notes');  // TODO(hyangah): pass more info such as version, release note location.
+		choices.push('Release Notes'); // TODO(hyangah): pass more info such as version, release note location.
 	}
 	vscode.window.showInformationMessage(updateMsg, ...choices).then((selected) => {
 		switch (selected) {
@@ -370,7 +370,10 @@
 				installTools([tool], goVersion);
 				break;
 			case 'Release Notes':
-				vscode.commands.executeCommand('vscode.open', vscode.Uri.parse('https://github.com/golang/go/issues/33030#issuecomment-510151934'));
+				vscode.commands.executeCommand(
+					'vscode.open',
+					vscode.Uri.parse('https://github.com/golang/go/issues/33030#issuecomment-510151934')
+				);
 				break;
 			default:
 				declinedUpdates.push(tool);
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index cf0d0f2..6031a34 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -150,9 +150,12 @@
 					//          { languageId: 'go', uri: document.uri });
 
 					const editorParamHintsEnabled = vscode.workspace.getConfiguration(
-						'editor.parameterHints', document.uri)['enabled'];
-					const goParamHintsEnabled = vscode.workspace.getConfiguration(
-						'[go]', document.uri)['editor.parameterHints.enabled'];
+						'editor.parameterHints',
+						document.uri
+					)['enabled'];
+					const goParamHintsEnabled = vscode.workspace.getConfiguration('[go]', document.uri)[
+						'editor.parameterHints.enabled'
+					];
 
 					let paramHintsEnabled: boolean = false;
 					if (typeof goParamHintsEnabled === 'undefined') {
@@ -166,8 +169,8 @@
 					}
 
 					function configureCommands(
-						r: vscode.CompletionItem[] | vscode.CompletionList | null | undefined):
-						vscode.CompletionItem[] | vscode.CompletionList | null | undefined {
+						r: vscode.CompletionItem[] | vscode.CompletionList | null | undefined
+					): vscode.CompletionItem[] | vscode.CompletionList | null | undefined {
 						if (r) {
 							(Array.isArray(r) ? r : r.items).forEach((i: vscode.CompletionItem) => {
 								i.command = cmd;
@@ -177,12 +180,12 @@
 					}
 					const ret = next(document, position, context, token);
 
-					const isThenable = <T>(obj: vscode.ProviderResult<T>): obj is Thenable<T> => obj && (<any>obj)['then'];
+					const isThenable = <T>(obj: vscode.ProviderResult<T>): obj is Thenable<T> =>
+						obj && (<any>obj)['then'];
 					if (isThenable<vscode.CompletionItem[] | vscode.CompletionList | null | undefined>(ret)) {
 						return ret.then(configureCommands);
 					}
 					return configureCommands(ret);
-
 				}
 			}
 		}
diff --git a/src/telemetry.ts b/src/telemetry.ts
index b198327..4070b43 100644
--- a/src/telemetry.ts
+++ b/src/telemetry.ts
@@ -184,7 +184,7 @@
 	measures?: { [key: string]: number }
 ): void {
 	if (!aiKey) {
-		return;  // cannot enable telemetry
+		return; // cannot enable telemetry
 	}
 	telemtryReporter = telemtryReporter
 		? telemtryReporter