[vscode-go] src/language/legacy: delete legacy language feature providers

36 views
Skip to first unread message

Hyang-Ah Hana Kim (Gerrit)

unread,
Oct 12, 2023, 11:47:16 PM10/12/23
to goph...@pubsubhelper.golang.org, Hyang-Ah Hana Kim, golang-co...@googlegroups.com

Hyang-Ah Hana Kim has uploaded this change for review.

View Change

src/language/legacy: delete legacy language feature providers

Except the legacy goFormat provider. It is still used for custom
formatter feature implementation.

Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
---
M src/commands/startLanguageServer.ts
M src/goDocumentSymbols.ts
M src/goGenerateTests.ts
M src/goImport.ts
M src/goTools.ts
D src/language/legacy/goCodeAction.ts
D src/language/legacy/goDeclaration.ts
D src/language/legacy/goExtraInfo.ts
D src/language/legacy/goImplementations.ts
D src/language/legacy/goLiveErrors.ts
D src/language/legacy/goOutline.ts
D src/language/legacy/goRefactor.ts
D src/language/legacy/goReferences.ts
D src/language/legacy/goRename.ts
D src/language/legacy/goSignature.ts
D src/language/legacy/goSuggest.ts
D src/language/legacy/goSymbol.ts
D src/language/legacy/goTypeDefinition.ts
M src/language/registerDefaultProviders.ts
M test/integration/extension.test.ts
20 files changed, 11 insertions(+), 3,510 deletions(-)

diff --git a/src/commands/startLanguageServer.ts b/src/commands/startLanguageServer.ts
index 42ccefa..7f56f3e 100644
--- a/src/commands/startLanguageServer.ts
+++ b/src/commands/startLanguageServer.ts
@@ -86,7 +86,7 @@
}

if (!cfg.enabled) {
- const legacyService = new LegacyLanguageService(ctx, goCtx);
+ const legacyService = new LegacyLanguageService();
goCtx.legacyLanguageService = legacyService;
ctx.subscriptions.push(legacyService);
updateStatus(goCtx, goConfig, false);
diff --git a/src/goDocumentSymbols.ts b/src/goDocumentSymbols.ts
index 1aa814e..ce233a1 100644
--- a/src/goDocumentSymbols.ts
+++ b/src/goDocumentSymbols.ts
@@ -7,24 +7,15 @@
import { ExecuteCommandParams, ExecuteCommandRequest } from 'vscode-languageserver-protocol';
import { getGoConfig } from './config';
import { GoExtensionContext } from './context';
-import { GoLegacyDocumentSymbolProvider } from './language/legacy/goOutline';
-
-export function GoDocumentSymbolProvider(
- goCtx: GoExtensionContext,
- includeImports?: boolean
-): GoplsDocumentSymbolProvider | GoLegacyDocumentSymbolProvider {
- const { latestConfig } = goCtx;
- if (!latestConfig?.enabled) {
- return new GoLegacyDocumentSymbolProvider(includeImports);
- }
- return new GoplsDocumentSymbolProvider(goCtx, includeImports);
-}

const GOPLS_LIST_IMPORTS = 'gopls.list_imports';
-export class GoplsDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
+export class GoDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
constructor(private readonly goCtx: GoExtensionContext, private includeImports?: boolean) {}

public async provideDocumentSymbols(document: vscode.TextDocument): Promise<vscode.DocumentSymbol[]> {
+ if (!this.goCtx.languageServerIsRunning) {
+ return [];
+ }
// TODO(suzmue): consider providing an interface for providing document symbols that only requires
// the URI. Getting a TextDocument from a filename requires opening the file, which can lead to
// files being opened that were not requested by the user in order to get information that we just
diff --git a/src/goGenerateTests.ts b/src/goGenerateTests.ts
index 12e0e42..37b31b2 100644
--- a/src/goGenerateTests.ts
+++ b/src/goGenerateTests.ts
@@ -242,8 +242,11 @@
}

async function getFunctions(goCtx: GoExtensionContext, doc: vscode.TextDocument): Promise<vscode.DocumentSymbol[]> {
- const documentSymbolProvider = GoDocumentSymbolProvider(goCtx);
+ const documentSymbolProvider = new GoDocumentSymbolProvider(goCtx);
const symbols = await documentSymbolProvider.provideDocumentSymbols(doc);
+ if (!symbols || symbols.length == 0) {
+ return [];
+ }
return symbols[0].children.filter((sym) =>
[vscode.SymbolKind.Function, vscode.SymbolKind.Method].includes(sym.kind)
);
diff --git a/src/goImport.ts b/src/goImport.ts
index 9525164..1693d0b 100644
--- a/src/goImport.ts
+++ b/src/goImport.ts
@@ -12,7 +12,6 @@
import { ExecuteCommandRequest, ExecuteCommandParams } from 'vscode-languageserver-protocol';
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
-import { documentSymbols, GoOutlineImportsOptions } from './language/legacy/goOutline';
import { getImportablePackages } from './goPackages';
import { getBinPath, getImportPath, parseFilePrelude } from './util';
import { getEnvPath, getCurrentGoRoot } from './utils/pathUtils';
@@ -21,30 +20,6 @@

const missingToolMsg = 'Missing tool: ';

-// listPackages returns 'importable' packages and places std packages first.
-export async function listPackages(excludeImportedPkgs = false): Promise<string[]> {
- const importedPkgs =
- excludeImportedPkgs && vscode.window.activeTextEditor
- ? await getImports(vscode.window.activeTextEditor.document)
- : [];
- const pkgMap = vscode.window.activeTextEditor
- ? await getImportablePackages(vscode.window.activeTextEditor?.document.fileName, true)
- : new Map();
- const stdLibs: string[] = [];
- const nonStdLibs: string[] = [];
- pkgMap.forEach((value, key) => {
- if (importedPkgs.some((imported) => imported === key)) {
- return;
- }
- if (value.isStd) {
- stdLibs.push(key);
- } else {
- nonStdLibs.push(key);
- }
- });
- return [...stdLibs.sort(), ...nonStdLibs.sort()];
-}
-
async function golist(goCtx: GoExtensionContext): Promise<string[]> {
const { languageClient, serverInfo } = goCtx;
const COMMAND = 'gopls.list_known_packages';
@@ -71,31 +46,7 @@
}
}

- // fallback to calling listPackages
- return listPackages(true);
-}
-
-/**
- * Returns the imported packages in the given file
- *
- * @param document TextDocument whose imports need to be returned
- * @returns Array of imported package paths wrapped in a promise
- */
-async function getImports(document: vscode.TextDocument): Promise<string[]> {
- const options = {
- fileName: document.fileName,
- importsOption: GoOutlineImportsOptions.Only,
- document
- };
- const symbols = await documentSymbols(options);
- if (!symbols || !symbols.length) {
- return [];
- }
- // import names will be of the form "math", so strip the quotes in the beginning and the end
- const imports = symbols[0].children
- .filter((x: any) => x.kind === vscode.SymbolKind.Namespace)
- .map((x: any) => x.name.substr(1, x.name.length - 2));
- return imports;
+ return [];
}

async function askUserForImport(goCtx: GoExtensionContext): Promise<string | undefined> {
@@ -108,62 +59,6 @@
}
}
}
-
-export function getTextEditForAddImport(arg: string | undefined): vscode.TextEdit[] | undefined {
- // Import name wasn't provided
- if (arg === undefined) {
- return undefined;
- }
- const editor = vscode.window.activeTextEditor;
- if (!editor) {
- vscode.window.showErrorMessage('No active editor found.');
- return [];
- }
-
- const { imports, pkg } = parseFilePrelude(editor.document.getText());
- if (imports.some((block) => block.pkgs.some((pkgpath) => pkgpath === arg))) {
- return [];
- }
-
- const multis = imports.filter((x) => x.kind === 'multi');
- const minusCgo = imports.filter((x) => x.kind !== 'pseudo');
-
- if (multis.length > 0) {
- // There is a multiple import declaration, add to the last one
- const lastImportSection = multis[multis.length - 1];
- if (lastImportSection.end === -1) {
- // For some reason there was an empty import section like `import ()`
- return [vscode.TextEdit.insert(new vscode.Position(lastImportSection.start + 1, 0), `import "${arg}"\n`)];
- }
- // Add import at the start of the block so that goimports/goreturns can order them correctly
- return [vscode.TextEdit.insert(new vscode.Position(lastImportSection.start + 1, 0), '\t"' + arg + '"\n')];
- } else if (minusCgo.length > 0) {
- // There are some number of single line imports, which can just be collapsed into a block import.
- const edits = [];
-
- edits.push(vscode.TextEdit.insert(new vscode.Position(minusCgo[0].start, 0), 'import (\n\t"' + arg + '"\n'));
- minusCgo.forEach((element) => {
- const currentLine = editor.document.lineAt(element.start).text;
- const updatedLine = currentLine.replace(/^\s*import\s*/, '\t');
- edits.push(
- vscode.TextEdit.replace(
- new vscode.Range(element.start, 0, element.start, currentLine.length),
- updatedLine
- )
- );
- });
- edits.push(vscode.TextEdit.insert(new vscode.Position(minusCgo[minusCgo.length - 1].end + 1, 0), ')\n'));
-
- return edits;
- } else if (pkg && pkg.start >= 0) {
- // There are no import declarations, but there is a package declaration
- return [vscode.TextEdit.insert(new vscode.Position(pkg.start + 1, 0), '\nimport (\n\t"' + arg + '"\n)\n')];
- } else {
- // There are no imports and no package declaration - give up
- return [];
- }
-}
-
export const addImport: CommandFactory = (ctx, goCtx) => (arg: { importPath: string }) => {
const { languageClient, serverInfo } = goCtx;
const editor = vscode.window.activeTextEditor;
@@ -201,14 +96,6 @@
console.log(`error executing gopls.add_import: ${e}`);
}
}
-
- // fallback to adding imports directly from client
- const edits = getTextEditForAddImport(imp);
- if (edits && edits.length > 0) {
- const edit = new vscode.WorkspaceEdit();
- edit.set(editor.document.uri, edits);
- vscode.workspace.applyEdit(edit);
- }
});
};

diff --git a/src/goTools.ts b/src/goTools.ts
index ddd82cd..90c7cb5 100644
--- a/src/goTools.ts
+++ b/src/goTools.ts
@@ -12,7 +12,6 @@
import semver = require('semver');
import util = require('util');
import { getFormatTool, usingCustomFormatTool } from './language/legacy/goFormat';
-import { goLiveErrorsEnabled } from './language/legacy/goLiveErrors';
import { allToolsInformation } from './goToolsInformation';
import { getBinPath, GoVersion } from './util';

@@ -208,11 +207,6 @@
if (useLanguageServer) {
maybeAddTool('gopls');
}
-
- if (goLiveErrorsEnabled()) {
- maybeAddTool('gotype-live');
- }
-
return tools;
}

diff --git a/src/language/legacy/goCodeAction.ts b/src/language/legacy/goCodeAction.ts
deleted file mode 100644
index c08d1f0..0000000
--- a/src/language/legacy/goCodeAction.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import vscode = require('vscode');
-import { listPackages } from '../../goImport';
-
-export class GoCodeActionProvider implements vscode.CodeActionProvider {
- public provideCodeActions(
- document: vscode.TextDocument,
- range: vscode.Range,
- context: vscode.CodeActionContext,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- token: vscode.CancellationToken
- ): Thenable<vscode.Command[]> {
- 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) ?? [];
- return listPackages().then((packages) => {
- const commands = packages
- .filter((pkg) => pkg === name || pkg.endsWith('/' + name))
- .map((pkg) => {
- return {
- title: 'import "' + pkg + '"',
- command: 'go.import.add',
- arguments: [{ importPath: pkg, from: 'codeAction' }]
- };
- });
- return commands;
- });
- }
- return [];
- });
-
- return Promise.all(promises).then((arrs) => {
- const results: { [key: string]: any } = {};
- for (const segment of arrs) {
- for (const item of segment) {
- results[item.title] = item;
- }
- }
- const ret = [];
- for (const title of Object.keys(results).sort()) {
- ret.push(results[title]);
- }
- return ret;
- });
- }
-}
diff --git a/src/language/legacy/goDeclaration.ts b/src/language/legacy/goDeclaration.ts
deleted file mode 100644
index 6b10364..0000000
--- a/src/language/legacy/goDeclaration.ts
+++ /dev/null
@@ -1,394 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import path = require('path');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool, promptForUpdatingTool } from '../../goInstallTools';
-import { getModFolderPath, promptToUpdateToolForModules } from '../../goModules';
-import {
- byteOffsetAt,
- getBinPath,
- getFileArchive,
- getModuleCache,
- getWorkspaceFolderPath,
- goKeywords,
- isPositionInString,
- runGodoc
-} from '../../util';
-import { getCurrentGoRoot } from '../../utils/pathUtils';
-import { killProcessTree } from '../../utils/processUtils';
-
-const missingToolMsg = 'Missing tool: ';
-
-export interface GoDefinitionInformation {
- file?: string;
- line: number;
- column: number;
- doc?: string;
- declarationlines: string[];
- name?: string;
- toolUsed: string;
-}
-
-interface GoDefinitionInput {
- document: vscode.TextDocument;
- position: vscode.Position;
- word: string;
- includeDocs: boolean;
- isMod: boolean;
- cwd: string;
-}
-
-interface GoGetDocOuput {
- name: string;
- import: string;
- decl: string;
- doc: string;
- pos: string;
-}
-
-interface GuruDefinitionOuput {
- objpos: string;
- desc: string;
-}
-
-export function definitionLocation(
- document: vscode.TextDocument,
- position: vscode.Position,
- goConfig: vscode.WorkspaceConfiguration | undefined,
- includeDocs: boolean,
- token: vscode.CancellationToken
-): Promise<GoDefinitionInformation | null> {
- const adjustedPos = adjustWordPosition(document, position);
- if (!adjustedPos[0]) {
- return Promise.resolve(null);
- }
- const word = adjustedPos[1];
- position = adjustedPos[2];
-
- if (!goConfig) {
- goConfig = getGoConfig(document.uri);
- }
- const toolForDocs = goConfig['docsTool'] || 'godoc';
- return getModFolderPath(document.uri).then((modFolderPath) => {
- const input: GoDefinitionInput = {
- document,
- position,
- word,
- includeDocs,
- isMod: !!modFolderPath,
- cwd:
- modFolderPath && modFolderPath !== getModuleCache()
- ? modFolderPath
- : getWorkspaceFolderPath(document.uri) || path.dirname(document.fileName)
- };
- if (toolForDocs === 'godoc') {
- return definitionLocation_godef(input, token);
- } else if (toolForDocs === 'guru') {
- return definitionLocation_guru(input, token);
- }
- return definitionLocation_gogetdoc(input, token, true);
- });
-}
-
-export function adjustWordPosition(
- document: vscode.TextDocument,
- position: vscode.Position
-): [boolean, string, vscode.Position] {
- const wordRange = document.getWordRangeAtPosition(position);
- const lineText = document.lineAt(position.line).text;
- const word = wordRange ? document.getText(wordRange) : '';
- if (
- !wordRange ||
- lineText.startsWith('//') ||
- isPositionInString(document, position) ||
- word.match(/^\d+.?\d+$/) ||
- goKeywords.indexOf(word) > 0
- ) {
- return [false, null!, null!];
- }
- if (position.isEqual(wordRange.end) && position.isAfter(wordRange.start)) {
- position = position.translate(0, -1);
- }
-
- return [true, word, position];
-}
-
-const godefImportDefinitionRegex = /^import \(.* ".*"\)$/;
-function definitionLocation_godef(
- input: GoDefinitionInput,
- token: vscode.CancellationToken,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- useReceivers = true
-): Promise<GoDefinitionInformation | null> {
- 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 | null | undefined;
- if (token) {
- token.onCancellationRequested(() => p && killProcessTree(p));
- }
-
- return new Promise((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: undefined,
- name: undefined
- };
- 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());
- }
- });
-}
-
-function definitionLocation_gogetdoc(
- input: GoDefinitionInput,
- token: vscode.CancellationToken,
- useTags: boolean
-): 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 | null | undefined;
- if (token) {
- token.onCancellationRequested(() => p && killProcessTree(p));
- }
-
- return new Promise((resolve, reject) => {
- const gogetdocFlagsWithoutTags = [
- '-u',
- '-json',
- '-modified',
- '-pos',
- input.document.fileName + ':#' + offset.toString()
- ];
- const buildTags = getGoConfig(input.document.uri)['buildTags'];
- const gogetdocFlags =
- buildTags && useTags ? [...gogetdocFlagsWithoutTags, '-tags', buildTags] : gogetdocFlagsWithoutTags;
- p = cp.execFile(gogetdoc, gogetdocFlags, { env, cwd: input.cwd }, (err, stdout, stderr) => {
- try {
- if (err && (<any>err).code === 'ENOENT') {
- return reject(missingToolMsg + 'gogetdoc');
- }
- if (stderr && stderr.startsWith('flag provided but not defined: -tags')) {
- p = null;
- return definitionLocation_gogetdoc(input, token, false).then(resolve, reject);
- }
- if (err) {
- if (input.isMod && !input.includeDocs && stdout.startsWith("gogetdoc: couldn't get package for")) {
- promptToUpdateToolForModules(
- 'gogetdoc',
- 'To get the Go to Definition feature when using Go modules, please update your version of the "gogetdoc" tool.'
- );
- return resolve(null);
- }
- return reject(err.message || stderr);
- }
- const goGetDocOutput = <GoGetDocOuput>JSON.parse(stdout.toString());
- const match = /(.*):(\d+):(\d+)/.exec(goGetDocOutput.pos);
- const definitionInfo: GoDefinitionInformation = {
- file: undefined,
- line: 0,
- column: 0,
- toolUsed: 'gogetdoc',
- declarationlines: goGetDocOutput.decl.split('\n'),
- doc: goGetDocOutput.doc,
- name: goGetDocOutput.name
- };
- if (!match) {
- return resolve(definitionInfo);
- }
- definitionInfo.file = match[1];
- definitionInfo.line = +match[2] - 1;
- definitionInfo.column = +match[3] - 1;
- return resolve(definitionInfo);
- } catch (e) {
- reject(e);
- }
- });
- if (p.pid) {
- p.stdin?.end(getFileArchive(input.document));
- }
- });
-}
-
-function definitionLocation_guru(
- input: GoDefinitionInput,
- token: vscode.CancellationToken
-): Promise<GoDefinitionInformation> {
- const guru = getBinPath('guru');
- if (!path.isAbsolute(guru)) {
- return Promise.reject(missingToolMsg + 'guru');
- }
- const offset = byteOffsetAt(input.document, input.position);
- const env = toolExecutionEnvironment();
- let p: cp.ChildProcess;
- if (token) {
- token.onCancellationRequested(() => killProcessTree(p));
- }
- return new Promise<GoDefinitionInformation>((resolve, reject) => {
- p = cp.execFile(
- guru,
- ['-json', '-modified', 'definition', input.document.fileName + ':#' + offset.toString()],
- { env },
- (err, stdout, stderr) => {
- try {
- if (err && (<any>err).code === 'ENOENT') {
- return reject(missingToolMsg + 'guru');
- }
- if (err) {
- return reject(err.message || stderr);
- }
- const guruOutput = <GuruDefinitionOuput>JSON.parse(stdout.toString());
- const match = /(.*):(\d+):(\d+)/.exec(guruOutput.objpos);
- const definitionInfo: GoDefinitionInformation = {
- file: undefined,
- line: 0,
- column: 0,
- toolUsed: 'guru',
- declarationlines: [guruOutput.desc],
- doc: undefined,
- name: undefined
- };
- if (!match) {
- return resolve(definitionInfo);
- }
- // const [_, file, line, col] = match;
- definitionInfo.file = match[1];
- definitionInfo.line = +match[2] - 1;
- definitionInfo.column = +match[3] - 1;
- return resolve(definitionInfo);
- } catch (e) {
- reject(e);
- }
- }
- );
- if (p.pid) {
- p.stdin?.end(getFileArchive(input.document));
- }
- });
-}
-
-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
- if (typeof err === 'string' && err.startsWith(missingToolMsg)) {
- return [true, err.substr(missingToolMsg.length)];
- }
- }
- return [false, null];
-}
-
-export class GoDefinitionProvider implements vscode.DefinitionProvider {
- private goConfig: vscode.WorkspaceConfiguration | undefined;
-
- constructor(goConfig?: vscode.WorkspaceConfiguration) {
- this.goConfig = goConfig;
- }
-
- public provideDefinition(
- document: vscode.TextDocument,
- position: vscode.Position,
- token: vscode.CancellationToken
- ): Thenable<vscode.Location | null> {
- return definitionLocation(document, position, this.goConfig, false, token).then(
- (definitionInfo) => {
- if (!definitionInfo || !definitionInfo.file) {
- return null;
- }
- const definitionResource = vscode.Uri.file(definitionInfo.file);
- const pos = new vscode.Position(definitionInfo.line, definitionInfo.column);
- return new vscode.Location(definitionResource, pos);
- },
- (err) => {
- const miss = parseMissingError(err);
- if (miss[0] && miss[1]) {
- promptForMissingTool(miss[1]);
- } else if (err) {
- return Promise.reject(err);
- }
- return Promise.resolve(null);
- }
- );
- }
-}
diff --git a/src/language/legacy/goExtraInfo.ts b/src/language/legacy/goExtraInfo.ts
deleted file mode 100644
index a5d162e..0000000
--- a/src/language/legacy/goExtraInfo.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/* eslint-disable prefer-const */
-/* eslint-disable eqeqeq */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import vscode = require('vscode');
-import { CancellationToken, Hover, HoverProvider, Position, TextDocument, WorkspaceConfiguration } from 'vscode';
-import { getGoConfig } from '../../config';
-import { definitionLocation } from './goDeclaration';
-
-export class GoHoverProvider implements HoverProvider {
- private goConfig: WorkspaceConfiguration | undefined;
-
- constructor(goConfig?: WorkspaceConfiguration) {
- this.goConfig = goConfig;
- }
-
- public provideHover(document: TextDocument, position: Position, token: CancellationToken): Thenable<Hover | null> {
- if (!this.goConfig) {
- this.goConfig = getGoConfig(document.uri);
- }
- let goConfig = this.goConfig;
-
- // Temporary fix to fall back to godoc if guru is the set docsTool
- if (goConfig['docsTool'] === 'guru') {
- goConfig = Object.assign({}, goConfig, { docsTool: 'godoc' });
- }
- return definitionLocation(document, position, goConfig, true, token).then(
- (definitionInfo) => {
- if (definitionInfo == null) {
- return null;
- }
- const lines = definitionInfo.declarationlines
- .filter((line) => line !== '')
- .map((line) => line.replace(/\t/g, ' '));
- let text;
- text = lines.join('\n').replace(/\n+$/, '');
- const hoverTexts = new vscode.MarkdownString();
- hoverTexts.appendCodeblock(text, 'go');
- if (definitionInfo.doc != null) {
- hoverTexts.appendMarkdown(definitionInfo.doc);
- }
- const hover = new Hover(hoverTexts);
- return hover;
- },
- () => {
- return null;
- }
- );
- }
-}
diff --git a/src/language/legacy/goImplementations.ts b/src/language/legacy/goImplementations.ts
deleted file mode 100644
index dfff48f..0000000
--- a/src/language/legacy/goImplementations.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import path = require('path');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool } from '../../goInstallTools';
-import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath, getWorkspaceFolderPath } from '../../util';
-import { getEnvPath, getCurrentGoRoot } from '../../utils/pathUtils';
-import { killProcessTree } from '../../utils/processUtils';
-
-interface GoListOutput {
- Dir: string;
- ImportPath: string;
- Root: string;
-}
-
-interface GuruImplementsRef {
- name: string;
- pos: string;
- kind: string;
-}
-
-interface GuruImplementsOutput {
- type: GuruImplementsRef;
- to: GuruImplementsRef[];
- to_method: GuruImplementsRef[];
- from: GuruImplementsRef[];
- fromptr: GuruImplementsRef[];
-}
-
-export class GoImplementationProvider implements vscode.ImplementationProvider {
- public provideImplementation(
- document: vscode.TextDocument,
- position: vscode.Position,
- token: vscode.CancellationToken
- ): 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);
- if (!root) {
- vscode.window.showInformationMessage('Cannot find implementations when there is no workspace open.');
- return;
- }
-
- const goRuntimePath = getBinPath('go');
- if (!goRuntimePath) {
- vscode.window.showErrorMessage(
- `Failed to run "go list" to get the scope to find implementations as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${getEnvPath()})`
- );
- return;
- }
-
- return new Promise((resolve, reject) => {
- if (token.isCancellationRequested) {
- return resolve(null);
- }
- const env = toolExecutionEnvironment();
- const listProcess = cp.execFile(
- goRuntimePath,
- ['list', '-e', '-json'],
- { cwd: root, env },
- (err, stdout) => {
- if (err) {
- return reject(err);
- }
- const listOutput = <GoListOutput>JSON.parse(stdout.toString());
- const filename = canonicalizeGOPATHPrefix(document.fileName);
- const cwd = path.dirname(filename);
- const offset = byteOffsetAt(document, position);
- const goGuru = getBinPath('guru');
- const buildTags = getGoConfig(document.uri)['buildTags'];
- const args = buildTags ? ['-tags', buildTags] : [];
- if (listOutput.Root && listOutput.ImportPath) {
- args.push('-scope', `${listOutput.ImportPath}/...`);
- }
- args.push('-json', 'implements', `${filename}:#${offset.toString()}`);
-
- const guruProcess = cp.execFile(goGuru, args, { env }, (guruErr, guruStdOut) => {
- if (guruErr && (<any>guruErr).code === 'ENOENT') {
- promptForMissingTool('guru');
- return resolve(null);
- }
-
- if (guruErr) {
- return reject(guruErr);
- }
-
- const guruOutput = <GuruImplementsOutput>JSON.parse(guruStdOut.toString());
- const results: vscode.Location[] = [];
- const addResults = (list: GuruImplementsRef[]) => {
- list.forEach((ref: GuruImplementsRef) => {
- const match = /^(.*):(\d+):(\d+)/.exec(ref.pos);
- if (!match) {
- return;
- }
- const [, file, lineStartStr, colStartStr] = match;
- const referenceResource = vscode.Uri.file(path.resolve(cwd, file));
- const range = new vscode.Range(
- +lineStartStr - 1,
- +colStartStr - 1,
- +lineStartStr - 1,
- +colStartStr
- );
- results.push(new vscode.Location(referenceResource, range));
- });
- };
-
- // If we looked for implementation of method go to method implementations only
- if (guruOutput.to_method) {
- addResults(guruOutput.to_method);
- } else if (guruOutput.to) {
- addResults(guruOutput.to);
- } else if (guruOutput.from) {
- addResults(guruOutput.from);
- } else if (guruOutput.fromptr) {
- addResults(guruOutput.fromptr);
- }
-
- return resolve(results);
- });
- token.onCancellationRequested(() => killProcessTree(guruProcess));
- }
- );
- token.onCancellationRequested(() => killProcessTree(listProcess));
- });
- }
-}
diff --git a/src/language/legacy/goLiveErrors.ts b/src/language/legacy/goLiveErrors.ts
deleted file mode 100644
index 318df4c..0000000
--- a/src/language/legacy/goLiveErrors.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import path = require('path');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { GoExtensionContext } from '../../context';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool } from '../../goInstallTools';
-import { isModSupported } from '../../goModules';
-import { getBinPath } from '../../util';
-
-// Interface for settings configuration for adding and removing tags
-interface GoLiveErrorsConfig {
- delay: number;
- enabled: boolean;
-}
-
-let runner: NodeJS.Timer | null;
-
-export function goLiveErrorsEnabled() {
- const goConfig = getGoConfig();
- // If the language server is enabled, there is no need for live errors.
- if (goConfig['useLanguageServer'] === true) {
- return false;
- }
- const liveErrorsConfig = <GoLiveErrorsConfig>goConfig['liveErrors'];
- if (liveErrorsConfig === null || liveErrorsConfig === undefined || !liveErrorsConfig.enabled) {
- return false;
- }
- const files = vscode.workspace.getConfiguration('files', null);
- const autoSave = files['autoSave'];
- const autoSaveDelay = files['autoSaveDelay'];
- if (
- autoSave !== null &&
- autoSave !== undefined &&
- autoSave === 'afterDelay' &&
- autoSaveDelay < liveErrorsConfig.delay * 1.5
- ) {
- return false;
- }
- return liveErrorsConfig.enabled;
-}
-
-// parseLiveFile runs the gotype command in live mode to check for any syntactic or
-// semantic errors and reports them immediately
-export function parseLiveFile(goCtx: GoExtensionContext, e: vscode.TextDocumentChangeEvent) {
- if (e.document.isUntitled) {
- return;
- }
- if (e.document.languageId !== 'go') {
- return;
- }
- if (!goLiveErrorsEnabled()) {
- return;
- }
-
- if (runner !== null) {
- clearTimeout(runner);
- }
- runner = setTimeout(() => {
- processFile(goCtx, e);
- runner = null;
- }, getGoConfig(e.document.uri)['liveErrors']['delay']);
-}
-
-// processFile does the actual work once the timeout has fired
-async function processFile(goCtx: GoExtensionContext, e: vscode.TextDocumentChangeEvent) {
- const isMod = await isModSupported(e.document.uri);
- if (isMod) {
- return;
- }
-
- const gotypeLive = getBinPath('gotype-live');
- if (!path.isAbsolute(gotypeLive)) {
- return promptForMissingTool('gotype-live');
- }
-
- const fileContents = e.document.getText();
- const fileName = e.document.fileName;
- const args = ['-e', '-a', '-lf=' + fileName, path.dirname(fileName)];
- const env = toolExecutionEnvironment();
- const p = cp.execFile(gotypeLive, args, { env }, (err, stdout, stderr) => {
- if (err && (<any>err).code === 'ENOENT') {
- promptForMissingTool('gotype-live');
- return;
- }
-
- goCtx.buildDiagnosticCollection?.clear();
-
- if (err) {
- // we want to take the error path here because the command we are calling
- // returns a non-zero exit status if the checks fail
- const diagnosticMap: Map<string, vscode.Diagnostic[]> = new Map();
-
- stderr.split('\n').forEach((error) => {
- if (error === null || error.length === 0) {
- return;
- }
- // extract the line, column and error message from the gotype output
- 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);
- const diagnostic = new vscode.Diagnostic(range, message, vscode.DiagnosticSeverity.Error);
- diagnostic.source = 'go';
-
- const diagnostics = diagnosticMap.get(canonicalFilePath) || [];
- diagnostics.push(diagnostic);
- diagnosticMap.set(canonicalFilePath, diagnostics);
- });
-
- diagnosticMap.forEach((diagnostics, file) => {
- goCtx.buildDiagnosticCollection?.set(vscode.Uri.parse(file), diagnostics);
- });
- }
- });
- if (p.pid) {
- p.stdin?.end(fileContents);
- }
-}
diff --git a/src/language/legacy/goOutline.ts b/src/language/legacy/goOutline.ts
deleted file mode 100644
index f8d4a70..0000000
--- a/src/language/legacy/goOutline.ts
+++ /dev/null
@@ -1,212 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool, promptForUpdatingTool } from '../../goInstallTools';
-import { getBinPath, getFileArchive, makeMemoizedByteOffsetConverter } from '../../util';
-import { killProcess } from '../../utils/processUtils';
-
-// Keep in sync with https://github.com/ramya-rao-a/go-outline
-export interface GoOutlineRange {
- start: number;
- end: number;
-}
-
-export interface GoOutlineDeclaration {
- label: string;
- type: string;
- receiverType?: string;
- icon?: string; // icon class or null to use the default images based on the type
- start: number;
- end: number;
- children?: GoOutlineDeclaration[];
- signature?: GoOutlineRange;
- comment?: GoOutlineRange;
-}
-
-export enum GoOutlineImportsOptions {
- Include,
- Exclude,
- Only
-}
-
-export interface GoOutlineOptions {
- /**
- * Path of the file for which outline is needed
- */
- fileName: string;
-
- /**
- * Option to decide if the output includes, excludes or only includes imports
- * If the option is to only include imports, then the file will be parsed only till imports are collected
- */
- importsOption: GoOutlineImportsOptions;
-
- /**
- * Document to be parsed. If not provided, saved contents of the given fileName is used
- */
- document?: vscode.TextDocument;
-}
-
-export async function documentSymbols(
- options: GoOutlineOptions,
- token?: vscode.CancellationToken
-): Promise<vscode.DocumentSymbol[]> {
- const decls = await runGoOutline(options, token);
- 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
-): Promise<GoOutlineDeclaration[]> {
- return new Promise((resolve, reject) => {
- const gooutline = getBinPath('go-outline');
- const gooutlineFlags = ['-f', options.fileName];
- if (options.importsOption === GoOutlineImportsOptions.Only) {
- gooutlineFlags.push('-imports-only');
- }
- if (options.document) {
- gooutlineFlags.push('-modified');
- }
-
- let p: cp.ChildProcess | null | undefined;
- if (token) {
- token.onCancellationRequested(() => p && killProcess(p));
- }
-
- // Spawn `go-outline` process
- p = cp.execFile(gooutline, gooutlineFlags, { env: toolExecutionEnvironment() }, (err, stdout, stderr) => {
- try {
- if (err && (<any>err).code === 'ENOENT') {
- promptForMissingTool('go-outline');
- }
- if (stderr && stderr.startsWith('flag provided but not defined: ')) {
- promptForUpdatingTool('go-outline');
- if (stderr.startsWith('flag provided but not defined: -imports-only')) {
- options.importsOption = GoOutlineImportsOptions.Include;
- }
- if (stderr.startsWith('flag provided but not defined: -modified')) {
- options.document = undefined;
- }
- p = null;
- return runGoOutline(options, token).then((results) => {
- return resolve(results);
- });
- }
- if (err) {
- return resolve([]);
- }
- const result = stdout.toString();
- const decls = <GoOutlineDeclaration[]>JSON.parse(result);
- return resolve(decls);
- } catch (e) {
- reject(e);
- }
- });
- if (options.document && p.pid) {
- p.stdin?.end(getFileArchive(options.document));
- }
- });
-}
-
-const goKindToCodeKind: { [key: string]: vscode.SymbolKind } = {
- package: vscode.SymbolKind.Package,
- import: vscode.SymbolKind.Namespace,
- variable: vscode.SymbolKind.Variable,
- constant: vscode.SymbolKind.Constant,
- type: vscode.SymbolKind.TypeParameter,
- function: vscode.SymbolKind.Function,
- struct: vscode.SymbolKind.Struct,
- interface: vscode.SymbolKind.Interface
-};
-
-function convertToCodeSymbols(
- document: vscode.TextDocument,
- decls: GoOutlineDeclaration[],
- includeImports: boolean,
- byteOffsetToDocumentOffset: (byteOffset: number) => number
-): vscode.DocumentSymbol[] {
- const symbols: vscode.DocumentSymbol[] = [];
- (decls || []).forEach((decl) => {
- if (!includeImports && decl.type === 'import') {
- return;
- }
- if (decl.label === '_' && decl.type === 'variable') {
- return;
- }
-
- const label = decl.receiverType ? `(${decl.receiverType}).${decl.label}` : decl.label;
-
- const start = byteOffsetToDocumentOffset(decl.start - 1);
- const end = byteOffsetToDocumentOffset(decl.end - 1);
- const startPosition = document.positionAt(start);
- const endPosition = document.positionAt(end);
- const symbolRange = new vscode.Range(startPosition, endPosition);
- const selectionRange =
- startPosition.line === endPosition.line
- ? symbolRange
- : new vscode.Range(startPosition, document.lineAt(startPosition.line).range.end);
-
- if (decl.type === 'type') {
- const line = document.lineAt(document.positionAt(start));
- const regexStruct = new RegExp(`^\\s*type\\s+${decl.label}\\s+struct\\b`);
- const regexInterface = new RegExp(`^\\s*type\\s+${decl.label}\\s+interface\\b`);
- decl.type = regexStruct.test(line.text) ? 'struct' : regexInterface.test(line.text) ? 'interface' : 'type';
- }
-
- const symbolInfo = new vscode.DocumentSymbol(
- label,
- decl.type,
- goKindToCodeKind[decl.type],
- symbolRange,
- selectionRange
- );
-
- symbols.push(symbolInfo);
- if (decl.children) {
- symbolInfo.children = convertToCodeSymbols(
- document,
- decl.children,
- includeImports,
- byteOffsetToDocumentOffset
- );
- }
- });
- return symbols;
-}
-
-export class GoLegacyDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
- constructor(private includeImports?: boolean) {}
-
- public async provideDocumentSymbols(
- document: vscode.TextDocument,
- token?: vscode.CancellationToken
- ): Promise<vscode.DocumentSymbol[]> {
- if (typeof this.includeImports !== 'boolean') {
- const gotoSymbolConfig = getGoConfig(document.uri)['gotoSymbol'];
- this.includeImports = gotoSymbolConfig ? gotoSymbolConfig['includeImports'] : false;
- }
- const options: GoOutlineOptions = {
- fileName: document.fileName,
- document,
- importsOption: this.includeImports ? GoOutlineImportsOptions.Include : GoOutlineImportsOptions.Exclude
- };
- return documentSymbols(options, token);
- }
-}
diff --git a/src/language/legacy/goRefactor.ts b/src/language/legacy/goRefactor.ts
deleted file mode 100644
index 0e1b8cc..0000000
--- a/src/language/legacy/goRefactor.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import vscode = require('vscode');
-
-export class GoRefactorProvider implements vscode.CodeActionProvider {
- public provideCodeActions(
- document: vscode.TextDocument,
- range: vscode.Range,
- context: vscode.CodeActionContext,
- token: vscode.CancellationToken
- ): vscode.ProviderResult<vscode.CodeAction[]> {
- if (range.isEmpty) {
- return [];
- }
- const extractFunction = new vscode.CodeAction(
- 'Extract to function in package scope',
- vscode.CodeActionKind.RefactorExtract
- );
- const extractVar = new vscode.CodeAction(
- 'Extract to variable in local scope',
- vscode.CodeActionKind.RefactorExtract
- );
- extractFunction.command = {
- title: 'Extract to function in package scope',
- command: 'go.godoctor.extract'
- };
- extractVar.command = {
- title: 'Extract to variable in local scope',
- command: 'go.godoctor.var'
- };
-
- return [extractFunction, extractVar];
- }
-}
diff --git a/src/language/legacy/goReferences.ts b/src/language/legacy/goReferences.ts
deleted file mode 100644
index 2239f25..0000000
--- a/src/language/legacy/goReferences.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import path = require('path');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool } from '../../goInstallTools';
-import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath, getFileArchive } from '../../util';
-import { killProcessTree } from '../../utils/processUtils';
-
-export class GoReferenceProvider implements vscode.ReferenceProvider {
- public provideReferences(
- document: vscode.TextDocument,
- position: vscode.Position,
- options: { includeDeclaration: boolean },
- token: vscode.CancellationToken
- ): Thenable<vscode.Location[]> {
- return this.doFindReferences(document, position, options, token);
- }
-
- private doFindReferences(
- document: vscode.TextDocument,
- position: vscode.Position,
- options: { includeDeclaration: boolean },
- token: vscode.CancellationToken
- ): Thenable<vscode.Location[]> {
- return new Promise<vscode.Location[]>((resolve, reject) => {
- // get current word
- const wordRange = document.getWordRangeAtPosition(position);
- if (!wordRange) {
- return resolve([]);
- }
-
- const goGuru = getBinPath('guru');
- if (!path.isAbsolute(goGuru)) {
- promptForMissingTool('guru');
- return reject('Cannot find tool "guru" to find references.');
- }
-
- const filename = canonicalizeGOPATHPrefix(document.fileName);
- const cwd = path.dirname(filename);
- const offset = byteOffsetAt(document, wordRange.start);
- const env = toolExecutionEnvironment();
- const buildTags = getGoConfig(document.uri)['buildTags'];
- const args = buildTags ? ['-tags', buildTags] : [];
- args.push('-modified', 'referrers', `${filename}:#${offset.toString()}`);
-
- const process = cp.execFile(goGuru, args, { env }, (err, stdout, stderr) => {
- try {
- if (err && (<any>err).code === 'ENOENT') {
- promptForMissingTool('guru');
- return reject('Cannot find tool "guru" to find references.');
- }
-
- if (err && (<any>err).killed !== true) {
- return reject(`Error running guru: ${err.message || stderr}`);
- }
-
- const lines = stdout.toString().split('\n');
- const results: vscode.Location[] = [];
- for (const line of lines) {
- const match = /^(.*):(\d+)\.(\d+)-(\d+)\.(\d+):/.exec(line);
- if (!match) {
- continue;
- }
- const [, file, lineStartStr, colStartStr, lineEndStr, colEndStr] = match;
- const referenceResource = vscode.Uri.file(path.resolve(cwd, file));
-
- if (!options.includeDeclaration) {
- if (
- document.uri.fsPath === referenceResource.fsPath &&
- position.line === Number(lineStartStr) - 1
- ) {
- continue;
- }
- }
-
- const range = new vscode.Range(
- +lineStartStr - 1,
- +colStartStr - 1,
- +lineEndStr - 1,
- +colEndStr
- );
- results.push(new vscode.Location(referenceResource, range));
- }
- resolve(results);
- } catch (e) {
- reject(e);
- }
- });
- if (process.pid) {
- process.stdin?.end(getFileArchive(document));
- }
- token.onCancellationRequested(() => killProcessTree(process));
- });
- }
-}
diff --git a/src/language/legacy/goRename.ts b/src/language/legacy/goRename.ts
deleted file mode 100644
index 5a864c2..0000000
--- a/src/language/legacy/goRename.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { Edit, FilePatch, getEditsFromUnifiedDiffStr, isDiffToolAvailable } from '../../diffUtils';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool } from '../../goInstallTools';
-import { outputChannel } from '../../goStatus';
-import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath } from '../../util';
-import { killProcessTree } from '../../utils/processUtils';
-
-export class GoRenameProvider implements vscode.RenameProvider {
- public provideRenameEdits(
- document: vscode.TextDocument,
- position: vscode.Position,
- newName: string,
- token: vscode.CancellationToken
- ): Thenable<vscode.WorkspaceEdit> {
- return vscode.workspace.saveAll(false).then(() => {
- return this.doRename(document, position, newName, token);
- });
- }
-
- private doRename(
- document: vscode.TextDocument,
- position: vscode.Position,
- newName: string,
- token: vscode.CancellationToken
- ): Thenable<vscode.WorkspaceEdit> {
- return new Promise<vscode.WorkspaceEdit>((resolve, reject) => {
- const filename = canonicalizeGOPATHPrefix(document.fileName);
- const range = document.getWordRangeAtPosition(position);
- const pos = range ? range.start : position;
- const offset = byteOffsetAt(document, pos);
- const env = toolExecutionEnvironment();
- const gorename = getBinPath('gorename');
- const buildTags = getGoConfig(document.uri)['buildTags'];
- const gorenameArgs = ['-offset', filename + ':#' + offset, '-to', newName];
- if (buildTags) {
- gorenameArgs.push('-tags', buildTags);
- }
- const canRenameToolUseDiff = isDiffToolAvailable();
- if (canRenameToolUseDiff) {
- gorenameArgs.push('-d');
- }
-
- // eslint-disable-next-line prefer-const
- let p: cp.ChildProcess;
- if (token) {
- token.onCancellationRequested(() => killProcessTree(p));
- }
-
- p = cp.execFile(gorename, gorenameArgs, { env }, (err, stdout, stderr) => {
- try {
- if (err && (<any>err).code === 'ENOENT') {
- promptForMissingTool('gorename');
- return reject('Could not find gorename tool.');
- }
- if (err) {
- const errMsg = stderr ? 'Rename failed: ' + stderr.replace(/\n/g, ' ') : 'Rename failed';
- console.log(errMsg);
- outputChannel.appendLine(errMsg);
- outputChannel.show();
- return reject();
- }
-
- const result = new vscode.WorkspaceEdit();
-
- if (canRenameToolUseDiff) {
- const filePatches = getEditsFromUnifiedDiffStr(stdout);
- filePatches.forEach((filePatch: FilePatch) => {
- const fileUri = vscode.Uri.file(filePatch.fileName);
- filePatch.edits.forEach((edit: Edit) => {
- edit.applyUsingWorkspaceEdit(result, fileUri);
- });
- });
- }
-
- return resolve(result);
- } catch (e) {
- reject(e);
- }
- });
- });
- }
-}
diff --git a/src/language/legacy/goSignature.ts b/src/language/legacy/goSignature.ts
deleted file mode 100755
index 7163ef8..0000000
--- a/src/language/legacy/goSignature.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-/* eslint-disable eqeqeq */
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-'use strict';
-
-import {
- CancellationToken,
- ParameterInformation,
- Position,
- SignatureHelp,
- SignatureHelpProvider,
- SignatureInformation,
- TextDocument,
- WorkspaceConfiguration
-} from 'vscode';
-import { getGoConfig } from '../../config';
-import { definitionLocation } from './goDeclaration';
-import { getParametersAndReturnType, isPositionInComment, isPositionInString } from '../../util';
-
-export class GoSignatureHelpProvider implements SignatureHelpProvider {
- constructor(private goConfig?: WorkspaceConfiguration) {}
-
- public async provideSignatureHelp(
- document: TextDocument,
- position: Position,
- token: CancellationToken
- ): Promise<SignatureHelp | null> {
- let goConfig = this.goConfig || getGoConfig(document.uri);
-
- const theCall = this.walkBackwardsToBeginningOfCall(document, position);
- if (theCall == null) {
- return Promise.resolve(null);
- }
- const callerPos = this.previousTokenPosition(document, theCall.openParen);
- // Temporary fix to fall back to godoc if guru is the set docsTool
- if (goConfig['docsTool'] === 'guru') {
- goConfig = Object.assign({}, goConfig, { docsTool: 'godoc' });
- }
- try {
- const res = await definitionLocation(document, callerPos, goConfig, true, token);
- if (!res) {
- // The definition was not found
- return null;
- }
- if (res.line === callerPos?.line) {
- // This must be a function definition
- return null;
- }
- let declarationText: string = (res.declarationlines || []).join(' ').trim();
- if (!declarationText) {
- return null;
- }
- const result = new SignatureHelp();
- 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(' ');
- const sigStart = nameEnd + 5; // ' func'
- const funcName = declarationText.substring(0, nameEnd);
- sig = declarationText.substring(sigStart);
- si = new SignatureInformation(funcName + sig, res.doc);
- } else if (res.toolUsed === 'gogetdoc') {
- // declaration is of the form "func Add(a int, b int) int"
- declarationText = declarationText.substring(5);
- const funcNameStart = declarationText.indexOf(res.name + '('); // Find 'functionname(' to remove anything before it
- if (funcNameStart > 0) {
- declarationText = declarationText.substring(funcNameStart);
- }
- si = new SignatureInformation(declarationText, res.doc);
- sig = declarationText.substring(res.name?.length ?? 0);
- }
- if (!si || !sig) return result;
- si.parameters = getParametersAndReturnType(sig).params.map(
- (paramText) => new ParameterInformation(paramText)
- );
- result.signatures = [si];
- result.activeSignature = 0;
- result.activeParameter = Math.min(theCall.commas.length, si.parameters.length - 1);
- return result;
- } catch (e) {
- return null;
- }
- }
-
- private previousTokenPosition(document: TextDocument, position: Position): Position {
- while (position.character > 0) {
- const word = document.getWordRangeAtPosition(position);
- if (word) {
- return word.start;
- }
- position = position.translate(0, -1);
- }
- return position;
- }
-
- /**
- * Goes through the function params' lines and gets the number of commas and the start position of the call.
- */
- private walkBackwardsToBeginningOfCall(
- document: TextDocument,
- position: Position
- ): { openParen: Position; commas: Position[] } | null {
- let parenBalance = 0;
- let maxLookupLines = 30;
- const commas = [];
-
- for (let lineNr = position.line; lineNr >= 0 && maxLookupLines >= 0; lineNr--, maxLookupLines--) {
- const line = document.lineAt(lineNr);
-
- // Stop processing if we're inside a comment
- if (isPositionInComment(document, position)) {
- return null;
- }
-
- // if its current line, get the text until the position given, otherwise get the full line.
- const [currentLine, characterPosition] =
- lineNr === position.line
- ? [line.text.substring(0, position.character), position.character]
- : [line.text, line.text.length - 1];
-
- for (let char = characterPosition; char >= 0; char--) {
- switch (currentLine[char]) {
- case '(':
- parenBalance--;
- if (parenBalance < 0) {
- return {
- openParen: new Position(lineNr, char),
- commas
- };
- }
- break;
- case ')':
- parenBalance++;
- break;
- case ',':
- {
- const commaPos = new Position(lineNr, char);
- if (parenBalance === 0 && !isPositionInString(document, commaPos)) {
- commas.push(commaPos);
- }
- }
- break;
- }
- }
- }
- return null;
- }
-}
diff --git a/src/language/legacy/goSuggest.ts b/src/language/legacy/goSuggest.ts
deleted file mode 100644
index ca39c89..0000000
--- a/src/language/legacy/goSuggest.ts
+++ /dev/null
@@ -1,708 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import path = require('path');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { getTextEditForAddImport } from '../../goImport';
-import { promptForMissingTool, promptForUpdatingTool } from '../../goInstallTools';
-import { isModSupported } from '../../goModules';
-import { getImportablePackages, PackageInfo } from '../../goPackages';
-import {
- byteOffsetAt,
- getBinPath,
- getCurrentGoPath,
- getParametersAndReturnType,
- goBuiltinTypes,
- goKeywords,
- guessPackageNameFromFile,
- isPositionInComment,
- isPositionInString,
- parseFilePrelude,
- runGodoc
-} from '../../util';
-import { getCurrentGoWorkspaceFromGOPATH } from '../../utils/pathUtils';
-
-function vscodeKindFromGoCodeClass(kind: string, type: string): vscode.CompletionItemKind {
- switch (kind) {
- case 'const':
- return vscode.CompletionItemKind.Constant;
- case 'package':
- return vscode.CompletionItemKind.Module;
- case 'type':
- switch (type) {
- case 'struct':
- return vscode.CompletionItemKind.Class;
- case 'interface':
- return vscode.CompletionItemKind.Interface;
- }
- return vscode.CompletionItemKind.Struct;
- case 'func':
- return vscode.CompletionItemKind.Function;
- case 'var':
- return vscode.CompletionItemKind.Variable;
- case 'import':
- return vscode.CompletionItemKind.Module;
- }
- return vscode.CompletionItemKind.Property; // TODO@EG additional mappings needed?
-}
-
-interface GoCodeSuggestion {
- class: string;
- package?: string;
- name: string;
- type: string;
- receiver?: string;
-}
-
-class ExtendedCompletionItem extends vscode.CompletionItem {
- public package?: string;
- public receiver?: string;
- public fileName!: string;
-}
-
-const lineCommentFirstWordRegex = /^\s*\/\/\s+[\S]*$/;
-const exportedMemberRegex = /(const|func|type|var)(\s+\(.*\))?\s+([A-Z]\w*)/;
-const gocodeNoSupportForgbMsgKey = 'dontshowNoSupportForgb';
-
-export class GoCompletionItemProvider implements vscode.CompletionItemProvider, vscode.Disposable {
- private pkgsList = new Map<string, PackageInfo>();
- private killMsgShown = false;
- private setGocodeOptions = true;
- private isGoMod = false;
- private globalState: vscode.Memento | undefined;
- private previousFile?: string;
- private previousFileDir?: string;
- private gocodeFlags?: string[];
- private excludeDocs = false;
-
- constructor(globalState?: vscode.Memento) {
- this.globalState = globalState;
- }
-
- public provideCompletionItems(
- document: vscode.TextDocument,
- position: vscode.Position,
- token: vscode.CancellationToken
- ): Thenable<vscode.CompletionList> {
- return this.provideCompletionItemsInternal(document, position, token, getGoConfig(document.uri)).then(
- (result) => {
- if (!result) {
- return new vscode.CompletionList([], false);
- }
- if (Array.isArray(result)) {
- return new vscode.CompletionList(result, false);
- }
- return result;
- }
- );
- }
-
- public resolveCompletionItem(
- item: vscode.CompletionItem,
- token: vscode.CancellationToken
- ): vscode.ProviderResult<vscode.CompletionItem> {
- if (
- !(item instanceof ExtendedCompletionItem) ||
- item.kind === vscode.CompletionItemKind.Module ||
- this.excludeDocs
- ) {
- return;
- }
-
- if (typeof item.package === 'undefined') {
- promptForUpdatingTool('gocode');
- return;
- }
-
- let { label } = item;
- if (typeof label !== 'string') label = label.label;
-
- return runGodoc(
- path.dirname(item.fileName),
- item.package || path.dirname(item.fileName),
- item.receiver,
- label,
- token
- )
- .then((doc) => {
- item.documentation = new vscode.MarkdownString(doc);
- return item;
- })
- .catch((err) => {
- console.log(err);
- return item;
- });
- }
-
- public async provideCompletionItemsInternal(
- document: vscode.TextDocument,
- position: vscode.Position,
- token: vscode.CancellationToken,
- config: vscode.WorkspaceConfiguration
- ): Promise<vscode.CompletionItem[] | vscode.CompletionList> {
- // Completions for the package statement based on the file name
- const pkgStatementCompletions = await getPackageStatementCompletions(document);
- if (pkgStatementCompletions && pkgStatementCompletions.length) {
- return pkgStatementCompletions;
- }
-
- this.excludeDocs = false;
- this.gocodeFlags = ['-f=json'];
- if (Array.isArray(config['gocodeFlags'])) {
- this.gocodeFlags.push(...config['gocodeFlags']);
- }
-
- return this.ensureGoCodeConfigured(document.uri, config).then(() => {
- return new Promise<vscode.CompletionItem[] | vscode.CompletionList>((resolve, reject) => {
- const filename = document.fileName;
- const lineText = document.lineAt(position.line).text;
- const lineTillCurrentPosition = lineText.substr(0, position.character);
- const autocompleteUnimportedPackages =
- config['autocompleteUnimportedPackages'] === true && !lineText.match(/^(\s)*(import|package)(\s)+/);
-
- // triggering completions in comments on exported members
- const commentCompletion = getCommentCompletion(document, position);
- if (commentCompletion) {
- return resolve([commentCompletion]);
- }
- // prevent completion when typing in a line comment that doesnt start from the beginning of the line
- if (isPositionInComment(document, position)) {
- return resolve([]);
- }
-
- const inString = isPositionInString(document, position);
- if (!inString && lineTillCurrentPosition.endsWith('"')) {
- return resolve([]);
- }
-
- const currentWord = getCurrentWord(document, position);
- if (currentWord.match(/^\d+$/)) {
- return resolve([]);
- }
-
- let offset = byteOffsetAt(document, position);
- let inputText = document.getText();
- const includeUnimportedPkgs = autocompleteUnimportedPackages && !inString && currentWord.length > 0;
-
- return this.runGoCode(
- document,
- filename,
- inputText,
- offset,
- inString,
- position,
- lineText,
- currentWord,
- includeUnimportedPkgs,
- config
- ).then((suggestions) => {
- // gocode does not suggest keywords, so we have to do it
- suggestions.push(...getKeywordCompletions(currentWord));
-
- // If no suggestions and cursor is at a dot, then check if preceeding word is a package name
- // If yes, then import the package in the inputText and run gocode again to get suggestions
- if ((!suggestions || suggestions.length === 0) && lineTillCurrentPosition.endsWith('.')) {
- 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 pkg = v.pkg;
- if (!pkg) return;
- const posToAddImport = document.offsetAt(new vscode.Position(pkg.start + 1, 0));
- const textToAdd = `import "${pkgPath[0]}"\n`;
- inputText =
- inputText.substr(0, posToAddImport) + textToAdd + inputText.substr(posToAddImport);
- offset += textToAdd.length;
-
- // Now that we have the package imported in the inputText, run gocode again
- return this.runGoCode(
- document,
- filename,
- inputText,
- offset,
- inString,
- position,
- lineText,
- currentWord,
- false,
- config
- ).then((newsuggestions) => {
- // Since the new suggestions are due to the package that we imported,
- // add additionalTextEdits to do the same in the actual document in the editor
- // We use additionalTextEdits instead of command so that 'useCodeSnippetsOnFunctionSuggest'
- // feature continues to work
- newsuggestions.forEach((item) => {
- item.additionalTextEdits = getTextEditForAddImport(pkgPath[0]);
- });
- resolve(newsuggestions);
- }, reject);
- }
- if (pkgPath.length > 1) {
- pkgPath.forEach((pkg) => {
- const item = new vscode.CompletionItem(
- `${lineTillCurrentPosition.replace('.', '').trim()} (${pkg})`,
- vscode.CompletionItemKind.Module
- );
- item.additionalTextEdits = getTextEditForAddImport(pkg);
- item.insertText = '';
- item.detail = pkg;
- item.command = {
- title: 'Trigger Suggest',
- command: 'editor.action.triggerSuggest'
- };
- suggestions.push(item);
- });
- resolve(new vscode.CompletionList(suggestions, true));
- }
- }
- resolve(suggestions);
- }, reject);
- });
- });
- }
-
- public dispose() {
- const gocodeName = this.isGoMod ? 'gocode-gomod' : 'gocode';
- const gocode = getBinPath(gocodeName);
- if (path.isAbsolute(gocode)) {
- cp.spawn(gocode, ['close'], { env: toolExecutionEnvironment() });
- }
- }
-
- private runGoCode(
- document: vscode.TextDocument,
- filename: string,
- inputText: string,
- offset: number,
- inString: boolean,
- position: vscode.Position,
- lineText: string,
- currentWord: string,
- includeUnimportedPkgs: boolean,
- config: vscode.WorkspaceConfiguration
- ): Thenable<vscode.CompletionItem[]> {
- return new Promise<vscode.CompletionItem[]>((resolve, reject) => {
- const gocodeName = this.isGoMod ? 'gocode-gomod' : 'gocode';
- const gocode = getBinPath(gocodeName);
- if (!path.isAbsolute(gocode)) {
- promptForMissingTool(gocodeName);
- return reject();
- }
-
- const env = toolExecutionEnvironment();
- let stdout = '';
- let stderr = '';
-
- // stamblerre/gocode does not support -unimported-packages flags.
- if (this.isGoMod && this.gocodeFlags) {
- const unimportedPkgIndex = this.gocodeFlags.indexOf('-unimported-packages');
- if (unimportedPkgIndex >= 0) {
- this.gocodeFlags.splice(unimportedPkgIndex, 1);
- }
- }
-
- // -exclude-docs is something we use internally and is not related to gocode
- 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 });
- p.stdout.on('data', (data) => (stdout += data));
- p.stderr.on('data', (data) => (stderr += data));
- p.on('error', (err) => {
- if (err && (<any>err).code === 'ENOENT') {
- promptForMissingTool(gocodeName);
- return reject();
- }
- return reject(err);
- });
- p.on('close', (code) => {
- try {
- if (code !== 0) {
- if (stderr.indexOf("rpc: can't find service Server.AutoComplete") > -1 && !this.killMsgShown) {
- vscode.window.showErrorMessage(
- 'Auto-completion feature failed as an older gocode process is still running. Please kill the running process for gocode and try again.'
- );
- this.killMsgShown = true;
- }
- if (stderr.startsWith('flag provided but not defined:')) {
- promptForUpdatingTool(gocodeName);
- }
- return reject();
- }
- const results = <[number, GoCodeSuggestion[]]>JSON.parse(stdout.toString());
- let suggestions: vscode.CompletionItem[] = [];
- const packageSuggestions: string[] = [];
-
- const wordAtPosition = document.getWordRangeAtPosition(position);
- let areCompletionsForPackageSymbols = false;
- if (results && results[1]) {
- for (const suggest of results[1]) {
- if (inString && suggest.class !== 'import') {
- continue;
- }
- const item = new ExtendedCompletionItem(suggest.name);
- item.kind = vscodeKindFromGoCodeClass(suggest.class, suggest.type);
- item.package = suggest.package;
- item.receiver = suggest.receiver;
- item.fileName = document.fileName;
- item.detail = suggest.type;
- if (!areCompletionsForPackageSymbols && item.package && item.package !== 'builtin') {
- areCompletionsForPackageSymbols = true;
- }
- if (suggest.class === 'package') {
- let { label } = item;
- if (typeof label !== 'string') label = label.label;
- const possiblePackageImportPaths = this.getPackageImportPath(label);
- if (possiblePackageImportPaths.length === 1) {
- item.detail = possiblePackageImportPaths[0];
- }
- packageSuggestions.push(suggest.name);
- }
- if (inString && suggest.class === 'import') {
- item.textEdit = new vscode.TextEdit(
- new vscode.Range(
- position.line,
- lineText.substring(0, position.character).lastIndexOf('"') + 1,
- position.line,
- position.character
- ),
- suggest.name
- );
- }
- if (
- (config['useCodeSnippetsOnFunctionSuggest'] ||
- config['useCodeSnippetsOnFunctionSuggestWithoutType']) &&
- ((suggest.class === 'func' && lineText.substr(position.character, 2) !== '()') || // Avoids met() -> method()()
- (suggest.class === 'var' &&
- suggest.type.startsWith('func(') &&
- lineText.substr(position.character, 1) !== ')' && // Avoids snippets when typing params in a func call
- lineText.substr(position.character, 1) !== ',')) // Avoids snippets when typing params in a func call
- ) {
- const got = getParametersAndReturnType(suggest.type.substring(4));
- const params = got.params;
- const paramSnippets = [];
- for (let i = 0; i < params.length; i++) {
- let param = params[i].trim();
- if (param) {
- param = param.replace('${', '\\${').replace('}', '\\}');
- if (config['useCodeSnippetsOnFunctionSuggestWithoutType']) {
- if (param.includes(' ')) {
- // Separate the variable name from the type
- param = param.substr(0, param.indexOf(' '));
- }
- }
- paramSnippets.push('${' + (i + 1) + ':' + param + '}');
- }
- }
- item.insertText = new vscode.SnippetString(
- suggest.name + '(' + paramSnippets.join(', ') + ')'
- );
- }
- if (
- config['useCodeSnippetsOnFunctionSuggest'] &&
- suggest.class === 'type' &&
- suggest.type.startsWith('func(')
- ) {
- const { params, returnType } = getParametersAndReturnType(suggest.type.substring(4));
- const paramSnippets = [];
- for (let i = 0; i < params.length; i++) {
- let param = params[i].trim();
- if (param) {
- param = param.replace('${', '\\${').replace('}', '\\}');
- if (!param.includes(' ')) {
- // If we don't have an argument name, we need to create one
- param = 'arg' + (i + 1) + ' ' + param;
- }
- const arg = param.substr(0, param.indexOf(' '));
- paramSnippets.push(
- '${' +
- (i + 1) +
- ':' +
- arg +
- '}' +
- param.substr(param.indexOf(' '), param.length)
- );
- }
- }
- item.insertText = new vscode.SnippetString(
- suggest.name +
- '(func(' +
- paramSnippets.join(', ') +
- ') {\n $' +
- (params.length + 1) +
- '\n})' +
- returnType
- );
- }
-
- if (
- wordAtPosition &&
- wordAtPosition.start.character === 0 &&
- suggest.class === 'type' &&
- !goBuiltinTypes.has(suggest.name)
- ) {
- const auxItem = new vscode.CompletionItem(
- suggest.name + ' method',
- vscode.CompletionItemKind.Snippet
- );
- auxItem.label = 'func (*' + suggest.name + ')';
- auxItem.filterText = suggest.name;
- auxItem.detail = 'Method snippet';
- auxItem.sortText = 'b';
- const prefix = 'func (' + suggest.name[0].toLowerCase() + ' *' + suggest.name + ')';
- const snippet = prefix + ' ${1:methodName}(${2}) ${3} {\n\t$0\n}';
- auxItem.insertText = new vscode.SnippetString(snippet);
- suggestions.push(auxItem);
- }
-
- // Add same sortText to all suggestions from gocode so that they appear before the unimported packages
- item.sortText = 'a';
- suggestions.push(item);
- }
- }
-
- // Add importable packages matching currentword to suggestions
- if (includeUnimportedPkgs && !this.isGoMod && !areCompletionsForPackageSymbols) {
- suggestions = suggestions.concat(
- getPackageCompletions(document, currentWord, this.pkgsList, packageSuggestions)
- );
- }
-
- resolve(suggestions);
- } catch (e) {
- reject(e);
- }
- });
- if (p.pid) {
- p.stdin.end(inputText);
- }
- });
- }
- // TODO: Shouldn't lib-path also be set?
- private ensureGoCodeConfigured(fileuri: vscode.Uri, goConfig: vscode.WorkspaceConfiguration): Thenable<void> {
- const currentFile = fileuri.fsPath;
- let checkModSupport = Promise.resolve(this.isGoMod);
- if (this.previousFile !== currentFile && this.previousFileDir !== path.dirname(currentFile)) {
- this.previousFile = currentFile;
- this.previousFileDir = path.dirname(currentFile);
- checkModSupport = isModSupported(fileuri).then((result) => (this.isGoMod = result));
- }
- const setPkgsList = getImportablePackages(currentFile, true).then((pkgMap) => {
- this.pkgsList = pkgMap;
- });
-
- if (!this.setGocodeOptions) {
- return Promise.all([checkModSupport, setPkgsList]).then(() => {
- return;
- });
- }
-
- const setGocodeProps = new Promise<void>((resolve) => {
- const gocode = getBinPath('gocode');
- const env = toolExecutionEnvironment();
-
- cp.execFile(gocode, ['set'], { env }, (err, stdout) => {
- if (err && stdout.startsWith('gocode: unknown subcommand:')) {
- if (
- goConfig['gocodePackageLookupMode'] === 'gb' &&
- this.globalState &&
- !this.globalState.get(gocodeNoSupportForgbMsgKey)
- ) {
- vscode.window
- .showInformationMessage(
- 'The go.gocodePackageLookupMode setting for gb will not be honored as github.com/mdempskey/gocode doesnt support it yet.',
- "Don't show again"
- )
- .then((selected) => {
- if (selected === "Don't show again") {
- this.globalState?.update(gocodeNoSupportForgbMsgKey, true);
- }
- });
- }
- this.setGocodeOptions = false;
- return resolve();
- }
-
- const existingOptions = stdout.split(/\r\n|\n/);
- const optionsToSet: string[][] = [];
- const setOption = () => {
- const [name, value] = optionsToSet.pop() ?? [];
- cp.execFile(gocode, ['set', name, value], { env }, () => {
- if (optionsToSet.length) {
- setOption();
- } else {
- resolve();
- }
- });
- };
-
- if (existingOptions.indexOf('propose-builtins true') === -1) {
- optionsToSet.push(['propose-builtins', 'true']);
- }
- if (existingOptions.indexOf(`autobuild ${goConfig['gocodeAutoBuild']}`) === -1) {
- optionsToSet.push(['autobuild', goConfig['gocodeAutoBuild']]);
- }
- if (existingOptions.indexOf(`package-lookup-mode ${goConfig['gocodePackageLookupMode']}`) === -1) {
- optionsToSet.push(['package-lookup-mode', goConfig['gocodePackageLookupMode']]);
- }
- if (!optionsToSet.length) {
- return resolve();
- }
-
- setOption();
- });
- });
-
- return Promise.all([setPkgsList, setGocodeProps, checkModSupport]).then(() => {
- return;
- });
- }
-
- // Given a line ending with dot, return the import paths of packages that match with the word preceeding the dot
- private getPackagePathFromLine(line: string): string[] {
- const pattern = /(\w+)\.$/g;
- const wordmatches = pattern.exec(line);
- if (!wordmatches) {
- return [];
- }
-
- const [, pkgNameFromWord] = wordmatches;
- // Word is isolated. Now check pkgsList for a match
- return this.getPackageImportPath(pkgNameFromWord);
- }
-
- /**
- * Returns import path for given package. Since there can be multiple matches,
- * this returns an array of matches
- * @param input Package name
- */
- private getPackageImportPath(input: string): string[] {
- const matchingPackages: any[] = [];
- this.pkgsList.forEach((info: PackageInfo, pkgPath: string) => {
- if (input === info.name) {
- matchingPackages.push(pkgPath);
- }
- });
- return matchingPackages;
- }
-}
-
-/**
- * Provides completion item for the exported member in the next line if current line is a comment
- * @param document The current document
- * @param position The cursor position
- */
-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 | undefined;
- if (memberType && memberType.length === 4) {
- suggestionItem = new vscode.CompletionItem(memberType[3], vscodeKindFromGoCodeClass(memberType[1], ''));
- }
- return suggestionItem;
- }
-}
-
-function getCurrentWord(document: vscode.TextDocument, position: vscode.Position): string {
- // get current word
- const wordAtPosition = document.getWordRangeAtPosition(position);
- let currentWord = '';
- if (wordAtPosition && wordAtPosition.start.character < position.character) {
- const word = document.getText(wordAtPosition);
- currentWord = word.substr(0, position.character - wordAtPosition.start.character);
- }
-
- return currentWord;
-}
-
-function getKeywordCompletions(currentWord: string): vscode.CompletionItem[] {
- if (!currentWord.length) {
- return [];
- }
- const completionItems: vscode.CompletionItem[] = [];
- goKeywords.forEach((keyword) => {
- if (keyword.startsWith(currentWord)) {
- completionItems.push(new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword));
- }
- });
- return completionItems;
-}
-
-/**
- * Return importable packages that match given word as Completion Items
- * @param document Current document
- * @param currentWord The word at the cursor
- * @param allPkgMap Map of all available packages and their import paths
- * @param importedPackages List of imported packages. Used to prune imported packages out of available packages
- */
-function getPackageCompletions(
- document: vscode.TextDocument,
- currentWord: string,
- allPkgMap: Map<string, PackageInfo>,
- importedPackages: string[] = []
-): vscode.CompletionItem[] {
- const cwd = path.dirname(document.fileName);
- const goWorkSpace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), cwd);
- const workSpaceFolder = vscode.workspace.getWorkspaceFolder(document.uri);
- const currentPkgRootPath = (workSpaceFolder ? workSpaceFolder.uri.path : cwd).slice(goWorkSpace.length + 1);
-
- const completionItems: any[] = [];
-
- allPkgMap.forEach((info: PackageInfo, pkgPath: string) => {
- const pkgName = info.name;
- if (pkgName.startsWith(currentWord) && importedPackages.indexOf(pkgName) === -1) {
- const item = new vscode.CompletionItem(pkgName, vscode.CompletionItemKind.Keyword);
- item.detail = pkgPath;
- item.documentation = 'Imports the package';
- item.insertText = pkgName;
- item.command = {
- title: 'Import Package',
- command: 'go.import.add',
- arguments: [{ importPath: pkgPath, from: 'completion' }]
- };
- item.kind = vscode.CompletionItemKind.Module;
-
- // Unimported packages should appear after the suggestions from gocode
- const isStandardPackage = !item.detail.includes('.');
- item.sortText = isStandardPackage ? 'za' : pkgPath.startsWith(currentPkgRootPath) ? 'zb' : 'zc';
- completionItems.push(item);
- }
- });
- return completionItems;
-}
-
-async function getPackageStatementCompletions(document: vscode.TextDocument): Promise<vscode.CompletionItem[]> {
- // 'Smart Snippet' for package clause
- const inputText = document.getText();
- if (inputText.match(/package\s+(\w+)/)) {
- return [];
- }
-
- const pkgNames = await guessPackageNameFromFile(document.fileName);
- const suggestions = pkgNames.map((pkgName) => {
- const packageItem = new vscode.CompletionItem('package ' + pkgName);
- packageItem.kind = vscode.CompletionItemKind.Snippet;
- packageItem.insertText = 'package ' + pkgName + '\r\n\r\n';
- return packageItem;
- });
- return suggestions;
-}
diff --git a/src/language/legacy/goSymbol.ts b/src/language/legacy/goSymbol.ts
deleted file mode 100644
index 0aab278..0000000
--- a/src/language/legacy/goSymbol.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool, promptForUpdatingTool } from '../../goInstallTools';
-import { getBinPath, getWorkspaceFolderPath } from '../../util';
-import { getCurrentGoRoot } from '../../utils/pathUtils';
-import { killProcessTree } from '../../utils/processUtils';
-
-// Keep in sync with github.com/acroca/go-symbols'
-interface GoSymbolDeclaration {
- name: string;
- kind: string;
- package: string;
- path: string;
- line: number;
- character: number;
-}
-
-export class GoWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
- private goKindToCodeKind: { [key: string]: vscode.SymbolKind } = {
- package: vscode.SymbolKind.Package,
- import: vscode.SymbolKind.Namespace,
- var: vscode.SymbolKind.Variable,
- type: vscode.SymbolKind.Interface,
- func: vscode.SymbolKind.Function,
- const: vscode.SymbolKind.Constant
- };
-
- public provideWorkspaceSymbols(
- query: string,
- token: vscode.CancellationToken
- ): Thenable<vscode.SymbolInformation[]> {
- const convertToCodeSymbols = (decls: GoSymbolDeclaration[], symbols: vscode.SymbolInformation[]): void => {
- if (!decls) {
- return;
- }
- for (const decl of decls) {
- let kind: vscode.SymbolKind;
- if (decl.kind !== '') {
- kind = this.goKindToCodeKind[decl.kind];
- }
- const pos = new vscode.Position(decl.line, decl.character);
- const symbolInfo = new vscode.SymbolInformation(
- decl.name,
- kind!,
- new vscode.Range(pos, pos),
- vscode.Uri.file(decl.path),
- ''
- );
- symbols.push(symbolInfo);
- }
- };
- 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 Promise.resolve([]);
- }
-
- return getWorkspaceSymbols(root, query, token, goConfig).then((results) => {
- const symbols: vscode.SymbolInformation[] = [];
- convertToCodeSymbols(results, symbols);
- return symbols;
- });
- }
-}
-
-export function getWorkspaceSymbols(
- workspacePath: string,
- query: string,
- token: vscode.CancellationToken,
- goConfig?: vscode.WorkspaceConfiguration,
- ignoreFolderFeatureOn = true
-): Thenable<GoSymbolDeclaration[]> {
- if (!goConfig) {
- goConfig = getGoConfig();
- }
- const gotoSymbolConfig = goConfig['gotoSymbol'];
- const calls: Promise<GoSymbolDeclaration[]>[] = [];
-
- const ignoreFolders: string[] = gotoSymbolConfig ? gotoSymbolConfig['ignoreFolders'] : [];
- const baseArgs =
- ignoreFolderFeatureOn && ignoreFolders && ignoreFolders.length > 0 ? ['-ignore', ignoreFolders.join(',')] : [];
-
- calls.push(callGoSymbols([...baseArgs, workspacePath, query], token));
-
- if (gotoSymbolConfig.includeGoroot) {
- const goRoot = getCurrentGoRoot();
- const gorootCall = callGoSymbols([...baseArgs, goRoot, query], token);
- calls.push(gorootCall);
- }
-
- return Promise.all(calls)
- .then(([...results]) => <GoSymbolDeclaration[]>[].concat(...(results as any)))
- .catch((err: Error) => {
- if (err && (<any>err).code === 'ENOENT') {
- promptForMissingTool('go-symbols');
- }
- if (err.message.startsWith('flag provided but not defined: -ignore')) {
- promptForUpdatingTool('go-symbols');
- return getWorkspaceSymbols(workspacePath, query, token, goConfig, false);
- }
- return [];
- });
-}
-
-function callGoSymbols(args: string[], token: vscode.CancellationToken): Promise<GoSymbolDeclaration[]> {
- const gosyms = getBinPath('go-symbols');
- const env = toolExecutionEnvironment();
- let p: cp.ChildProcess;
-
- if (token) {
- token.onCancellationRequested(() => killProcessTree(p));
- }
-
- return new Promise((resolve, reject) => {
- p = cp.execFile(gosyms, args, { maxBuffer: 1024 * 1024, env }, (err, stdout, stderr) => {
- if (err && stderr && stderr.startsWith('flag provided but not defined: -ignore')) {
- return reject(new Error(stderr));
- } else if (err) {
- return reject(err);
- }
- const result = stdout.toString();
- const decls = <GoSymbolDeclaration[]>JSON.parse(result);
- return resolve(decls);
- });
- });
-}
diff --git a/src/language/legacy/goTypeDefinition.ts b/src/language/legacy/goTypeDefinition.ts
deleted file mode 100644
index b4249b7..0000000
--- a/src/language/legacy/goTypeDefinition.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/*---------------------------------------------------------
- * Copyright (C) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See LICENSE in the project root for license information.
- *--------------------------------------------------------*/
-
-'use strict';
-
-import cp = require('child_process');
-import path = require('path');
-import vscode = require('vscode');
-import { getGoConfig } from '../../config';
-import { adjustWordPosition, definitionLocation, parseMissingError } from './goDeclaration';
-import { toolExecutionEnvironment } from '../../goEnv';
-import { promptForMissingTool } from '../../goInstallTools';
-import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath, getFileArchive, goBuiltinTypes } from '../../util';
-import { killProcessTree } from '../../utils/processUtils';
-
-interface GuruDescribeOutput {
- desc: string;
- pos: string;
- detail: string;
- value: GuruDescribeValueOutput;
-}
-
-interface GuruDescribeValueOutput {
- type: string;
- value: string;
- objpos: string;
- typespos: GuruDefinitionOutput[];
-}
-
-interface GuruDefinitionOutput {
- objpos: string;
- desc: string;
-}
-
-export class GoTypeDefinitionProvider implements vscode.TypeDefinitionProvider {
- public provideTypeDefinition(
- document: vscode.TextDocument,
- position: vscode.Position,
- token: vscode.CancellationToken
- ): vscode.ProviderResult<vscode.Definition> {
- const adjustedPos = adjustWordPosition(document, position);
- if (!adjustedPos[0]) {
- return Promise.resolve(null);
- }
- position = adjustedPos[2];
-
- return new Promise<vscode.Definition | null>((resolve, reject) => {
- const goGuru = getBinPath('guru');
- if (!path.isAbsolute(goGuru)) {
- promptForMissingTool('guru');
- return reject('Cannot find tool "guru" to find type definitions.');
- }
-
- const filename = canonicalizeGOPATHPrefix(document.fileName);
- const offset = byteOffsetAt(document, position);
- const env = toolExecutionEnvironment();
- const buildTags = getGoConfig(document.uri)['buildTags'];
- const args = buildTags ? ['-tags', buildTags] : [];
- args.push('-json', '-modified', 'describe', `${filename}:#${offset.toString()}`);
-
- const process = cp.execFile(goGuru, args, { env }, (guruErr, stdout) => {
- try {
- if (guruErr && (<any>guruErr).code === 'ENOENT') {
- promptForMissingTool('guru');
- return resolve(null);
- }
-
- if (guruErr) {
- return reject(guruErr);
- }
-
- const guruOutput = <GuruDescribeOutput>JSON.parse(stdout.toString());
- if (!guruOutput.value || !guruOutput.value.typespos) {
- if (
- guruOutput.value &&
- guruOutput.value.type &&
- !goBuiltinTypes.has(guruOutput.value.type) &&
- guruOutput.value.type !== 'invalid type'
- ) {
- console.log("no typespos from guru's output - try to update guru tool");
- }
-
- // Fall back to position of declaration
- return definitionLocation(document, position, undefined, false, token).then(
- (definitionInfo) => {
- if (!definitionInfo || !definitionInfo.file) {
- return null;
- }
- const definitionResource = vscode.Uri.file(definitionInfo.file);
- const pos = new vscode.Position(definitionInfo.line, definitionInfo.column);
- resolve(new vscode.Location(definitionResource, pos));
- },
- (err) => {
- const miss = parseMissingError(err);
- if (miss[0] && miss[1]) {
- promptForMissingTool(miss[1]);
- } else if (err) {
- return Promise.reject(err);
- }
- return Promise.resolve(null);
- }
- );
- }
-
- const results: vscode.Location[] = [];
- guruOutput.value.typespos.forEach((ref) => {
- const match = /^(.*):(\d+):(\d+)/.exec(ref.objpos);
- if (!match) {
- return;
- }
- const [, file, line, col] = match;
- const referenceResource = vscode.Uri.file(file);
- const pos = new vscode.Position(parseInt(line, 10) - 1, parseInt(col, 10) - 1);
- results.push(new vscode.Location(referenceResource, pos));
- });
-
- resolve(results);
- } catch (e) {
- reject(e);
- }
- });
- if (process.pid) {
- process.stdin?.end(getFileArchive(document));
- }
- token.onCancellationRequested(() => killProcessTree(process));
- });
- }
-}
diff --git a/src/language/registerDefaultProviders.ts b/src/language/registerDefaultProviders.ts
index 6bea2a9..f02fea6 100644
--- a/src/language/registerDefaultProviders.ts
+++ b/src/language/registerDefaultProviders.ts
@@ -6,53 +6,16 @@
*--------------------------------------------------------*/
'use strict';
import vscode = require('vscode');
-import { GoCodeActionProvider } from './legacy/goCodeAction';
-import { GoDefinitionProvider } from './legacy/goDeclaration';
-import { GoHoverProvider } from './legacy/goExtraInfo';
import { GoDocumentFormattingEditProvider } from './legacy/goFormat';
-import { GoImplementationProvider } from './legacy/goImplementations';
-import { parseLiveFile } from './legacy/goLiveErrors';
import { GO_MODE } from '../goMode';
-import { GoLegacyDocumentSymbolProvider } from './legacy/goOutline';
-import { GoReferenceProvider } from './legacy/goReferences';
-import { GoRenameProvider } from './legacy/goRename';
-import { GoSignatureHelpProvider } from './legacy/goSignature';
-import { GoCompletionItemProvider } from './legacy/goSuggest';
-import { GoWorkspaceSymbolProvider } from './legacy/goSymbol';
-import { GoTypeDefinitionProvider } from './legacy/goTypeDefinition';
-import { GoExtensionContext } from '../context';

export class LegacyLanguageService implements vscode.Disposable {
private _disposables: vscode.Disposable[] = [];

- constructor(ctx: vscode.ExtensionContext, goCtx: GoExtensionContext) {
- const completionProvider = new GoCompletionItemProvider(ctx.globalState);
- this._disposables.push(completionProvider);
- this._disposables.push(vscode.languages.registerCompletionItemProvider(GO_MODE, completionProvider, '.', '"'));
- this._disposables.push(vscode.languages.registerHoverProvider(GO_MODE, new GoHoverProvider()));
- this._disposables.push(vscode.languages.registerDefinitionProvider(GO_MODE, new GoDefinitionProvider()));
- this._disposables.push(vscode.languages.registerReferenceProvider(GO_MODE, new GoReferenceProvider()));
- this._disposables.push(
- vscode.languages.registerDocumentSymbolProvider(GO_MODE, new GoLegacyDocumentSymbolProvider())
- );
- this._disposables.push(vscode.languages.registerWorkspaceSymbolProvider(new GoWorkspaceSymbolProvider()));
- this._disposables.push(
- vscode.languages.registerSignatureHelpProvider(GO_MODE, new GoSignatureHelpProvider(), '(', ',')
- );
- this._disposables.push(
- vscode.languages.registerImplementationProvider(GO_MODE, new GoImplementationProvider())
- );
+ constructor() {
this._disposables.push(
vscode.languages.registerDocumentFormattingEditProvider(GO_MODE, new GoDocumentFormattingEditProvider())
);
- this._disposables.push(
- vscode.languages.registerTypeDefinitionProvider(GO_MODE, new GoTypeDefinitionProvider())
- );
- this._disposables.push(vscode.languages.registerRenameProvider(GO_MODE, new GoRenameProvider()));
- this._disposables.push(
- vscode.workspace.onDidChangeTextDocument((e) => parseLiveFile(goCtx, e), null, ctx.subscriptions)
- );
- this._disposables.push(vscode.languages.registerCodeActionsProvider(GO_MODE, new GoCodeActionProvider()));
}

dispose() {
diff --git a/test/integration/extension.test.ts b/test/integration/extension.test.ts
index 9f6b2c3..17d13a1 100644
--- a/test/integration/extension.test.ts
+++ b/test/integration/extension.test.ts
@@ -15,24 +15,16 @@
import { getGoConfig, getGoplsConfig } from '../../src/config';
import { FilePatch, getEdits, getEditsFromUnifiedDiffStr } from '../../src/diffUtils';
import { check } from '../../src/goCheck';
-import { GoDefinitionProvider } from '../../src/language/legacy/goDeclaration';
-import { GoHoverProvider } from '../../src/language/legacy/goExtraInfo';
import { runFillStruct } from '../../src/goFillStruct';
import {
generateTestCurrentFile,
generateTestCurrentFunction,
generateTestCurrentPackage
} from '../../src/goGenerateTests';
-import { getTextEditForAddImport, listPackages } from '../../src/goImport';
import { updateGoVarsFromConfig } from '../../src/goInstallTools';
import { buildLanguageServerConfig } from '../../src/language/goLanguageServer';
import { goLint } from '../../src/goLint';
-import { documentSymbols, GoOutlineImportsOptions } from '../../src/language/legacy/goOutline';
-import { GoDocumentSymbolProvider } from '../../src/goDocumentSymbols';
import { goPlay } from '../../src/goPlayground';
-import { GoSignatureHelpProvider } from '../../src/language/legacy/goSignature';
-import { GoCompletionItemProvider } from '../../src/language/legacy/goSuggest';
-import { getWorkspaceSymbols } from '../../src/language/legacy/goSymbol';
import { testCurrentFile } from '../../src/commands';
import {
getBinPath,
@@ -128,276 +120,6 @@
sinon.restore();
});

- async function testDefinitionProvider(goConfig: vscode.WorkspaceConfiguration): Promise<any> {
- const provider = new GoDefinitionProvider(goConfig);
- const uri = vscode.Uri.file(path.join(fixturePath, 'baseTest', 'test.go'));
- const position = new vscode.Position(10, 3);
- const textDocument = await vscode.workspace.openTextDocument(uri);
- const definitionInfo = await provider.provideDefinition(textDocument, position, dummyCancellationSource.token);
-
- assert.equal(
- definitionInfo?.uri.path.toLowerCase(),
- uri.path.toLowerCase(),
- `${definitionInfo?.uri.path} is not the same as ${uri.path}`
- );
- assert.equal(definitionInfo?.range.start.line, 6);
- assert.equal(definitionInfo?.range.start.character, 5);
- }
-
- async function testSignatureHelpProvider(
- goConfig: vscode.WorkspaceConfiguration,
- testCases: [vscode.Position, string, string, string[]][]
- ): Promise<any> {
- const provider = new GoSignatureHelpProvider(goConfig);
- const uri = vscode.Uri.file(path.join(fixturePath, 'gogetdocTestData', 'test.go'));
- const textDocument = await vscode.workspace.openTextDocument(uri);
-
- const promises = testCases.map(([position, expected, expectedDocPrefix, expectedParams]) =>
- provider.provideSignatureHelp(textDocument, position, dummyCancellationSource.token).then((sigHelp) => {
- assert.ok(
- sigHelp,
- `No signature for gogetdocTestData/test.go:${position.line + 1}:${position.character + 1}`
- );
- assert.equal(sigHelp.signatures.length, 1, 'unexpected number of overloads');
- assert.equal(sigHelp.signatures[0].label, expected);
- assert(
- sigHelp.signatures[0].documentation?.toString().startsWith(expectedDocPrefix),
- `expected doc starting with ${expectedDocPrefix}, got ${JSON.stringify(sigHelp.signatures[0])}`
- );
- assert.equal(sigHelp.signatures[0].parameters.length, expectedParams.length);
- for (let i = 0; i < expectedParams.length; i++) {
- assert.equal(sigHelp.signatures[0].parameters[i].label, expectedParams[i]);
- }
- })
- );
- return Promise.all(promises);
- }
-
- async function testHoverProvider(
- goConfig: vscode.WorkspaceConfiguration,
- testCases: [vscode.Position, string | null, string | null][]
- ): Promise<any> {
- const provider = new GoHoverProvider(goConfig);
- const uri = vscode.Uri.file(path.join(fixturePath, 'gogetdocTestData', 'test.go'));
- const textDocument = await vscode.workspace.openTextDocument(uri);
-
- const promises = testCases.map(([position, expectedSignature, expectedDocumentation]) =>
- provider.provideHover(textDocument, position, dummyCancellationSource.token).then((res) => {
- if (expectedSignature === null && expectedDocumentation === null) {
- assert.equal(res, null);
- return;
- }
- let expectedHover = '\n```go\n' + expectedSignature + '\n```\n';
- if (expectedDocumentation != null) {
- expectedHover += expectedDocumentation;
- }
- assert(res);
- assert.equal(res.contents.length, 1);
- assert(
- (<vscode.MarkdownString>res.contents[0]).value.startsWith(expectedHover),
- `expected hover starting with ${expectedHover}, got ${JSON.stringify(res.contents[0])}`
- );
- })
- );
- return Promise.all(promises);
- }
-
- test('Test Definition Provider using godoc', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode.
-
- const config = Object.create(getGoConfig(), {
- docsTool: { value: 'godoc' }
- });
- await testDefinitionProvider(config);
- });
-
- test('Test Definition Provider using gogetdoc', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode.
- const gogetdocPath = getBinPath('gogetdoc');
- if (gogetdocPath === 'gogetdoc') {
- // gogetdoc is not installed, so skip the test
- return;
- }
- const config = Object.create(getGoConfig(), {
- docsTool: { value: 'gogetdoc' }
- });
- await testDefinitionProvider(config);
- });
-
- test('Test SignatureHelp Provider using godoc', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode
-
- const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
- const printlnSig = goVersion.lt('1.18')
- ? 'Println(a ...interface{}) (n int, err error)'
- : 'Println(a ...any) (n int, err error)';
-
- const testCases: [vscode.Position, string, string, string[]][] = [
- [
- new vscode.Position(19, 13),
- printlnSig,
- printlnDocPrefix,
- [goVersion.lt('1.18') ? 'a ...interface{}' : 'a ...any']
- ],
- [
- new vscode.Position(23, 7),
- 'print(txt string)',
- "This is an unexported function so couldn't get this comment on hover :( Not\nanymore!!\n",
- ['txt string']
- ],
- [
- new vscode.Position(41, 19),
- 'Hello(s string, exclaim bool) string',
- 'Hello is a method on the struct ABC. Will signature help understand this\ncorrectly\n',
- ['s string', 'exclaim bool']
- ],
- [
- new vscode.Position(41, 47),
- 'EmptyLine(s string) string',
- 'EmptyLine has docs\n\nwith a blank line in the middle\n',
- ['s string']
- ]
- ];
- const config = Object.create(getGoConfig(), {
- docsTool: { value: 'godoc' }
- });
- await testSignatureHelpProvider(config, testCases);
- });
-
- test('Test SignatureHelp Provider using gogetdoc', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode.
- const gogetdocPath = getBinPath('gogetdoc');
- if (gogetdocPath === 'gogetdoc') {
- // gogetdoc is not installed, so skip the test
- return;
- }
-
- const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
- const printlnSig = goVersion.lt('1.18')
- ? 'Println(a ...interface{}) (n int, err error)'
- : 'Println(a ...any) (n int, err error)';
-
- const testCases: [vscode.Position, string, string, string[]][] = [
- [
- new vscode.Position(19, 13),
- printlnSig,
- printlnDocPrefix,
- [goVersion.lt('1.18') ? 'a ...interface{}' : 'a ...any']
- ],
- [
- new vscode.Position(23, 7),
- 'print(txt string)',
- "This is an unexported function so couldn't get this comment on hover :(\nNot anymore!!\n",
- ['txt string']
- ],
- [
- new vscode.Position(41, 19),
- 'Hello(s string, exclaim bool) string',
- 'Hello is a method on the struct ABC. Will signature help understand this correctly\n',
- ['s string', 'exclaim bool']
- ],
- [
- new vscode.Position(41, 47),
- 'EmptyLine(s string) string',
- 'EmptyLine has docs\n\nwith a blank line in the middle\n',
- ['s string']
- ]
- ];
- const config = Object.create(getGoConfig(), {
- docsTool: { value: 'gogetdoc' }
- });
- await testSignatureHelpProvider(config, testCases);
- });
-
- test('Test Hover Provider using godoc', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode
-
- const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
- const printlnSig = goVersion.lt('1.18')
- ? 'Println func(a ...interface{}) (n int, err error)'
- : 'Println func(a ...any) (n int, err error)';
-
- const testCases: [vscode.Position, string | null, string | null][] = [
- // [new vscode.Position(3,3), '/usr/local/go/src/fmt'],
- [new vscode.Position(0, 3), null, null], // keyword
- [new vscode.Position(23, 14), null, null], // inside a string
- [new vscode.Position(20, 0), null, null], // just a }
- [new vscode.Position(28, 16), null, null], // inside a number
- [new vscode.Position(22, 5), 'main func()', '\n'],
- [new vscode.Position(40, 23), 'import (math "math")', null],
- [new vscode.Position(19, 6), printlnSig, printlnDocPrefix],
- [
- new vscode.Position(23, 4),
- 'print func(txt string)',
- "This is an unexported function so couldn't get this comment on hover :( Not\nanymore!!\n"
- ]
- ];
- const config = Object.create(getGoConfig(), {
- docsTool: { value: 'godoc' }
- });
- await testHoverProvider(config, testCases);
- });
-
- test('Test Hover Provider using gogetdoc', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode.
-
- const gogetdocPath = getBinPath('gogetdoc');
- if (gogetdocPath === 'gogetdoc') {
- // gogetdoc is not installed, so skip the test
- return;
- }
-
- const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
- const printlnSig = goVersion.lt('1.18')
- ? 'func Println(a ...interface{}) (n int, err error)'
- : 'func Println(a ...any) (n int, err error)';
-
- const testCases: [vscode.Position, string | null, string | null][] = [
- [new vscode.Position(0, 3), null, null], // keyword
- [new vscode.Position(23, 11), null, null], // inside a string
- [new vscode.Position(20, 0), null, null], // just a }
- [new vscode.Position(28, 16), null, null], // inside a number
- [new vscode.Position(22, 5), 'func main()', ''],
- [
- new vscode.Position(23, 4),
- 'func print(txt string)',
- "This is an unexported function so couldn't get this comment on hover :(\nNot anymore!!\n"
- ],
- [
- new vscode.Position(40, 23),
- 'package math',
- 'Package math provides basic constants and mathematical functions.\n\nThis package does not guarantee bit-identical results across architectures.\n'
- ],
- [new vscode.Position(19, 6), printlnSig, printlnDocPrefix],
- [
- new vscode.Position(27, 14),
- 'type ABC struct {\n a int\n b int\n c int\n}',
- "ABC is a struct, you coudn't use Goto Definition or Hover info on this before\nNow you can due to gogetdoc and go doc\n"
- ],
- [
- new vscode.Position(28, 6),
- 'func IPv4Mask(a, b, c, d byte) IPMask',
- 'IPv4Mask returns the IP mask (in 4-byte form) of the\nIPv4 mask a.b.c.d.\n'
- ]
- ];
- const config = Object.create(getGoConfig(), {
- docsTool: { value: 'gogetdoc' }
- });
- await testHoverProvider(config, testCases);
- });
-
test('Linting - concurrent process cancelation', async () => {
const util = require('../../src/util');
const processutil = require('../../src/utils/processUtils');
@@ -674,648 +396,6 @@
assert.equal(result, true);
});

- test('Test Outline', async () => {
- const uri = vscode.Uri.file(path.join(fixturePath, 'outlineTest', 'test.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- const options = {
- document,
- fileName: document.fileName,
- importsOption: GoOutlineImportsOptions.Include
- };
-
- const outlines = await documentSymbols(options, dummyCancellationSource.token);
- const packageSymbols = outlines.filter((x: any) => x.kind === vscode.SymbolKind.Package);
- const imports = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Namespace);
- const functions = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Function);
-
- assert.equal(packageSymbols.length, 1);
- assert.equal(packageSymbols[0].name, 'main');
- assert.equal(imports.length, 1);
- assert.equal(imports[0].name, '"fmt"');
- assert.equal(functions.length, 2);
- assert.equal(functions[0].name, 'print');
- assert.equal(functions[1].name, 'main');
- });
-
- test('Test Outline imports only', async () => {
- const uri = vscode.Uri.file(path.join(fixturePath, 'outlineTest', 'test.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- const options = {
- document,
- fileName: document.fileName,
- importsOption: GoOutlineImportsOptions.Only
- };
-
- const outlines = await documentSymbols(options, dummyCancellationSource.token);
- const packageSymbols = outlines.filter((x) => x.kind === vscode.SymbolKind.Package);
- const imports = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Namespace);
- const functions = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Function);
-
- assert.equal(packageSymbols.length, 1);
- assert.equal(packageSymbols[0].name, 'main');
- assert.equal(imports.length, 1);
- assert.equal(imports[0].name, '"fmt"');
- assert.equal(functions.length, 0);
- });
-
- test('Test Outline document symbols', async () => {
- const uri = vscode.Uri.file(path.join(fixturePath, 'outlineTest', 'test.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- const symbolProvider = GoDocumentSymbolProvider({});
-
- const outlines = await symbolProvider.provideDocumentSymbols(document, dummyCancellationSource.token);
- const packages = outlines.filter((x) => x.kind === vscode.SymbolKind.Package);
- const variables = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Variable);
- const functions = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Function);
- const structs = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Struct);
- const interfaces = outlines[0].children.filter((x: any) => x.kind === vscode.SymbolKind.Interface);
-
- assert.equal(packages[0].name, 'main');
- assert.equal(variables.length, 0);
- assert.equal(functions[0].name, 'print');
- assert.equal(functions[1].name, 'main');
- assert.equal(structs.length, 1);
- assert.equal(structs[0].name, 'foo');
- assert.equal(interfaces.length, 1);
- assert.equal(interfaces[0].name, 'circle');
- });
-
- test('Test listPackages', async function () {
- if (affectedByIssue832()) {
- this.skip(); // timeout on windows
- }
- const uri = vscode.Uri.file(path.join(fixturePath, 'baseTest', 'test.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- await vscode.window.showTextDocument(document);
-
- const includeImportedPkgs = await listPackages(false);
- const excludeImportedPkgs = await listPackages(true);
- assert.equal(includeImportedPkgs.indexOf('fmt') > -1, true, 'want to include imported package');
- assert.equal(excludeImportedPkgs.indexOf('fmt') > -1, false, 'want to exclude imported package');
- });
-
- test('Replace vendor packages with relative path', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode.
- const filePath = path.join(fixturePath, 'vendoring', 'main.go');
- const vendorPkgsFullPath = ['test/testfixture/vendoring/vendor/example/vendorpls'];
- const vendorPkgsRelativePath = ['example/vendorpls'];
-
- vscode.workspace.openTextDocument(vscode.Uri.file(filePath)).then(async (document) => {
- await vscode.window.showTextDocument(document);
- const pkgs = await listPackages();
- vendorPkgsRelativePath.forEach((pkg) => {
- assert.equal(pkgs.indexOf(pkg) > -1, true, `Relative path for vendor package ${pkg} not found`);
- });
- vendorPkgsFullPath.forEach((pkg) => {
- assert.equal(
- pkgs.indexOf(pkg),
- -1,
- `Full path for vendor package ${pkg} should be shown by listPackages method`
- );
- });
- return pkgs;
- });
- });
-
- test('Vendor pkgs from other projects should not be allowed to import', async function () {
- if (isModuleMode) {
- this.skip();
- } // not working in module mode.
- const filePath = path.join(fixturePath, 'baseTest', 'test.go');
- const vendorPkgs = ['test/testfixture/vendoring/vendor/example/vendorpls'];
-
- vscode.workspace.openTextDocument(vscode.Uri.file(filePath)).then(async (document) => {
- await vscode.window.showTextDocument(document);
- const pkgs = await listPackages();
- vendorPkgs.forEach((pkg) => {
- assert.equal(pkgs.indexOf(pkg), -1, `Vendor package ${pkg} should not be shown by listPackages method`);
- });
- });
- });
-
- test('Workspace Symbols', function () {
- if (affectedByIssue832()) {
- this.skip(); // frequent timeout on windows
- }
- const workspacePath = path.join(fixturePath, 'vendoring');
- const configWithoutIgnoringFolders = Object.create(getGoConfig(), {
- gotoSymbol: {
- value: {
- ignoreFolders: []
- }
- }
- });
- const configWithIgnoringFolders = Object.create(getGoConfig(), {
- gotoSymbol: {
- value: {
- ignoreFolders: ['vendor']
- }
- }
- });
- const configWithIncludeGoroot = Object.create(getGoConfig(), {
- gotoSymbol: {
- value: {
- includeGoroot: true
- }
- }
- });
- const configWithoutIncludeGoroot = Object.create(getGoConfig(), {
- gotoSymbol: {
- value: {
- includeGoroot: false
- }
- }
- });
-
- const withoutIgnoringFolders = getWorkspaceSymbols(
- workspacePath,
- 'SomethingStr',
- dummyCancellationSource.token,
- configWithoutIgnoringFolders
- ).then((results) => {
- assert.equal(results[0].name, 'SomethingStrange');
- assert.equal(results[0].path, path.join(workspacePath, 'vendor/example/vendorpls/lib.go'));
- });
- const withIgnoringFolders = getWorkspaceSymbols(
- workspacePath,
- 'SomethingStr',
- dummyCancellationSource.token,
- configWithIgnoringFolders
- ).then((results) => {
- assert.equal(results.length, 0);
- });
- const withoutIncludingGoroot = getWorkspaceSymbols(
- workspacePath,
- 'Mutex',
- dummyCancellationSource.token,
- configWithoutIncludeGoroot
- ).then((results) => {
- assert.equal(results.length, 0);
- });
- const withIncludingGoroot = getWorkspaceSymbols(
- workspacePath,
- 'Mutex',
- dummyCancellationSource.token,
- configWithIncludeGoroot
- ).then((results) => {
- assert(results.some((result) => result.name === 'Mutex'));
- });
-
- return Promise.all([withIgnoringFolders, withoutIgnoringFolders, withIncludingGoroot, withoutIncludingGoroot]);
- });
-
- test('Test Completion', async function () {
- if (affectedByIssue832()) {
- this.skip(); // timeout on windows
- }
-
- const printlnDocPrefix = 'Println formats using the default formats for its operands';
- const printlnSig = goVersion.lt('1.18')
- ? 'func(a ...interface{}) (n int, err error)'
- : 'func(a ...any) (n int, err error)';
-
- const provider = new GoCompletionItemProvider();
- const testCases: [vscode.Position, string, string | null, string | null][] = [
- [new vscode.Position(7, 4), 'fmt', 'fmt', null],
- [new vscode.Position(7, 6), 'Println', printlnSig, printlnDocPrefix]
- ];
- const uri = vscode.Uri.file(path.join(fixturePath, 'baseTest', 'test.go'));
- const textDocument = await vscode.workspace.openTextDocument(uri);
- const editor = await vscode.window.showTextDocument(textDocument);
-
- const promises = testCases.map(([position, expectedLabel, expectedDetail, expectedDoc]) =>
- provider
- .provideCompletionItems(editor.document, position, dummyCancellationSource.token)
- .then(async (items) => {
- const item = items.items.find((x) => x.label === expectedLabel);
- if (!item) {
- assert.fail('missing expected item in completion list');
- }
- assert.equal(item.detail, expectedDetail);
- const resolvedItemResult: vscode.ProviderResult<vscode.CompletionItem> = provider.resolveCompletionItem(
- item,
- dummyCancellationSource.token
- );
- if (!resolvedItemResult) {
- return;
- }
- const resolvedItem =
- resolvedItemResult instanceof vscode.CompletionItem
- ? resolvedItemResult
- : await resolvedItemResult;
- if (resolvedItem?.documentation) {
- const got = (<vscode.MarkdownString>resolvedItem.documentation).value;
- if (expectedDoc) {
- assert(
- got.startsWith(expectedDoc),
- `expected doc starting with ${expectedDoc}, got ${got}`
- );
- } else {
- assert.equal(got, expectedDoc);
- }
- }
- })
- );
- await Promise.all(promises);
- });
-
- test('Test Completion Snippets For Functions', async function () {
- if (affectedByIssue832()) {
- this.skip(); // timeout on windows
- }
- const provider = new GoCompletionItemProvider();
- const uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'snippets.go'));
- const baseConfig = getGoConfig();
- const textDocument = await vscode.workspace.openTextDocument(uri);
- const editor = await vscode.window.showTextDocument(textDocument);
-
- const noFunctionSnippet = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(9, 6),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: false }
- })
- )
- .then((items) => {
- items = items instanceof vscode.CompletionList ? items.items : items;
- const item = items.find((x) => x.label === 'Print');
- if (!item) {
- assert.fail('Suggestion with label "Print" not found in test case noFunctionSnippet.');
- }
- assert.equal(!item.insertText, true);
- });
- const withFunctionSnippet = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(9, 6),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: true }
- })
- )
- .then((items1) => {
- items1 = items1 instanceof vscode.CompletionList ? items1.items : items1;
- const item1 = items1.find((x) => x.label === 'Print');
- if (!item1) {
- assert.fail('Suggestion with label "Print" not found in test case withFunctionSnippet.');
- }
- assert.equal(
- (<vscode.SnippetString>item1.insertText).value,
- goVersion.lt('1.18') ? 'Print(${1:a ...interface{\\}})' : 'Print(${1:a ...any})'
- );
- });
- const withFunctionSnippetNotype = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(9, 6),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggestWithoutType: { value: true }
- })
- )
- .then((items2) => {
- items2 = items2 instanceof vscode.CompletionList ? items2.items : items2;
- const item2 = items2.find((x) => x.label === 'Print');
- if (!item2) {
- assert.fail('Suggestion with label "Print" not found in test case withFunctionSnippetNotype.');
- }
- assert.equal((<vscode.SnippetString>item2.insertText).value, 'Print(${1:a})');
- });
- const noFunctionAsVarSnippet = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(11, 3),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: false }
- })
- )
- .then((items3) => {
- items3 = items3 instanceof vscode.CompletionList ? items3.items : items3;
- const item3 = items3.find((x) => x.label === 'funcAsVariable');
- if (!item3) {
- assert.fail('Suggestion with label "Print" not found in test case noFunctionAsVarSnippet.');
- }
- assert.equal(!item3.insertText, true);
- });
- const withFunctionAsVarSnippet = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(11, 3),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: true }
- })
- )
- .then((items4) => {
- items4 = items4 instanceof vscode.CompletionList ? items4.items : items4;
- const item4 = items4.find((x) => x.label === 'funcAsVariable');
- if (!item4) {
- assert.fail('Suggestion with label "Print" not found in test case withFunctionAsVarSnippet.');
- }
- assert.equal((<vscode.SnippetString>item4.insertText).value, 'funcAsVariable(${1:k string})');
- });
- const withFunctionAsVarSnippetNoType = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(11, 3),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggestWithoutType: { value: true }
- })
- )
- .then((items5) => {
- items5 = items5 instanceof vscode.CompletionList ? items5.items : items5;
- const item5 = items5.find((x) => x.label === 'funcAsVariable');
- if (!item5) {
- assert.fail('Suggestion with label "Print" not found in test case withFunctionAsVarSnippetNoType.');
- }
- assert.equal((<vscode.SnippetString>item5.insertText).value, 'funcAsVariable(${1:k})');
- });
- const noFunctionAsTypeSnippet = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(14, 0),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: false }
- })
- )
- .then((items6) => {
- items6 = items6 instanceof vscode.CompletionList ? items6.items : items6;
- const item1 = items6.find((x) => x.label === 'HandlerFunc');
- const item2 = items6.find((x) => x.label === 'HandlerFuncWithArgNames');
- const item3 = items6.find((x) => x.label === 'HandlerFuncNoReturnType');
- if (!item1) {
- assert.fail('Suggestion with label "HandlerFunc" not found in test case noFunctionAsTypeSnippet.');
- }
- assert.equal(!item1.insertText, true);
- if (!item2) {
- assert.fail(
- 'Suggestion with label "HandlerFuncWithArgNames" not found in test case noFunctionAsTypeSnippet.'
- );
- }
- assert.equal(!item2.insertText, true);
- if (!item3) {
- assert.fail(
- 'Suggestion with label "HandlerFuncNoReturnType" not found in test case noFunctionAsTypeSnippet.'
- );
- }
- assert.equal(!item3.insertText, true);
- });
- const withFunctionAsTypeSnippet = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(14, 0),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: true }
- })
- )
- .then((items7) => {
- items7 = items7 instanceof vscode.CompletionList ? items7.items : items7;
- const item11 = items7.find((x) => x.label === 'HandlerFunc');
- const item21 = items7.find((x) => x.label === 'HandlerFuncWithArgNames');
- const item31 = items7.find((x) => x.label === 'HandlerFuncNoReturnType');
- if (!item11) {
- assert.fail(
- 'Suggestion with label "HandlerFunc" not found in test case withFunctionAsTypeSnippet.'
- );
- }
- assert.equal(
- (<vscode.SnippetString>item11.insertText).value,
- 'HandlerFunc(func(${1:arg1} string, ${2:arg2} string) {\n\t$3\n}) (string, string)'
- );
- if (!item21) {
- assert.fail(
- 'Suggestion with label "HandlerFuncWithArgNames" not found in test case withFunctionAsTypeSnippet.'
- );
- }
- assert.equal(
- (<vscode.SnippetString>item21.insertText).value,
- 'HandlerFuncWithArgNames(func(${1:w} string, ${2:r} string) {\n\t$3\n}) int'
- );
- if (!item31) {
- assert.fail(
- 'Suggestion with label "HandlerFuncNoReturnType" not found in test case withFunctionAsTypeSnippet.'
- );
- }
- assert.equal(
- (<vscode.SnippetString>item31.insertText).value,
- 'HandlerFuncNoReturnType(func(${1:arg1} string, ${2:arg2} string) {\n\t$3\n})'
- );
- });
- await Promise.all([
- noFunctionSnippet,
- withFunctionSnippet,
- withFunctionSnippetNotype,
- noFunctionAsVarSnippet,
- withFunctionAsVarSnippet,
- withFunctionAsVarSnippetNoType,
- noFunctionAsTypeSnippet,
- withFunctionAsTypeSnippet
- ]);
- });
-
- test('Test No Completion Snippets For Functions', async () => {
- if (affectedByIssue832()) {
- return;
- }
- const provider = new GoCompletionItemProvider();
- const uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'nosnippets.go'));
- const baseConfig = getGoConfig();
- const textDocument = await vscode.workspace.openTextDocument(uri);
- const editor = await vscode.window.showTextDocument(textDocument);
-
- const symbolFollowedByBrackets = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(5, 10),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: true }
- })
- )
- .then((items) => {
- items = items instanceof vscode.CompletionList ? items.items : items;
- const item = items.find((x) => x.label === 'Print');
- if (!item) {
- assert.fail('Suggestion with label "Print" not found in test case symbolFollowedByBrackets.');
- }
- assert.equal(!item.insertText, true, 'Unexpected snippet when symbol is followed by ().');
- });
- const symbolAsLastParameter = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(7, 13),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: true }
- })
- )
- .then((items1) => {
- items1 = items1 instanceof vscode.CompletionList ? items1.items : items1;
- const item1 = items1.find((x) => x.label === 'funcAsVariable');
- if (!item1) {
- assert.fail('Suggestion with label "funcAsVariable" not found in test case symbolAsLastParameter.');
- }
- assert.equal(!item1.insertText, true, 'Unexpected snippet when symbol is a parameter inside func call');
- });
- const symbolsAsNonLastParameter = provider
- .provideCompletionItemsInternal(
- editor.document,
- new vscode.Position(8, 11),
- dummyCancellationSource.token,
- Object.create(baseConfig, {
- useCodeSnippetsOnFunctionSuggest: { value: true }
- })
- )
- .then((items2) => {
- items2 = items2 instanceof vscode.CompletionList ? items2.items : items2;
- const item2 = items2.find((x) => x.label === 'funcAsVariable');
- if (!item2) {
- assert.fail(
- 'Suggestion with label "funcAsVariable" not found in test case symbolsAsNonLastParameter.'
- );
- }
- assert.equal(
- !item2.insertText,
- true,
- 'Unexpected snippet when symbol is one of the parameters inside func call.'
- );
- });
- await Promise.all([symbolFollowedByBrackets, symbolAsLastParameter, symbolsAsNonLastParameter]);
- });
-
- test('Test Completion on unimported packages', async function () {
- if (isModuleMode || affectedByIssue832()) {
- this.skip();
- }
- // gocode-gomod does not handle unimported package completion.
- // Skip if we run in module mode.
-
- const config = Object.create(getGoConfig(), {
- autocompleteUnimportedPackages: { value: true }
- });
- const provider = new GoCompletionItemProvider();
- const testCases: [vscode.Position, string[]][] = [
- [new vscode.Position(10, 3), ['bytes']],
- [new vscode.Position(11, 6), ['Abs', 'Acos', 'Asin']]
- ];
- const uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'unimportedPkgs.go'));
- const textDocument = await vscode.workspace.openTextDocument(uri);
- const editor = await vscode.window.showTextDocument(textDocument);
-
- const promises = testCases.map(([position, expected]) =>
- provider
- .provideCompletionItemsInternal(editor.document, position, dummyCancellationSource.token, config)
- .then((items) => {
- items = items instanceof vscode.CompletionList ? items.items : items;
- const labels = items.map((x) => x.label);
- for (const entry of expected) {
- assert.equal(
- labels.indexOf(entry) > -1,
- true,
- `missing expected item in completion list: ${entry} Actual: ${labels}`
- );
- }
- })
- );
- await Promise.all(promises);
- });
-
- test('Test Completion on unimported packages (multiple)', async function () {
- if (affectedByIssue832()) {
- this.skip();
- }
- const config = Object.create(getGoConfig(), {
- gocodeFlags: { value: ['-builtin'] }
- });
- const provider = new GoCompletionItemProvider();
- const position = new vscode.Position(3, 14);
- const expectedItems = [
- {
- label: 'template (html/template)',
- import: '\nimport (\n\t"html/template"\n)\n'
- },
- {
- label: 'template (text/template)',
- import: '\nimport (\n\t"text/template"\n)\n'
- }
- ];
- const uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'unimportedMultiplePkgs.go'));
- const textDocument = await vscode.workspace.openTextDocument(uri);
- const editor = await vscode.window.showTextDocument(textDocument);
-
- const completionResult = await provider.provideCompletionItemsInternal(
- editor.document,
- position,
- dummyCancellationSource.token,
- config
- );
- const items = completionResult instanceof vscode.CompletionList ? completionResult.items : completionResult;
- const labels = items.map((x) => x.label);
- expectedItems.forEach((expectedItem) => {
- const actualItem: vscode.CompletionItem = items.filter((item) => item.label === expectedItem.label)[0];
- if (!actualItem) {
- assert.fail(
- actualItem,
- expectedItem,
- `Missing expected item in completion list: ${expectedItem.label} Actual: ${labels}`
- );
- }
- if (!actualItem.additionalTextEdits) {
- assert.fail(`Missing additionalTextEdits on suggestion for ${actualItem}`);
- }
- assert.equal(actualItem.additionalTextEdits.length, 1);
- assert.equal(actualItem.additionalTextEdits[0].newText, expectedItem.import);
- });
- });
-
- test('Test Completion on Comments for Exported Members', async () => {
- const provider = new GoCompletionItemProvider();
- const testCases: [vscode.Position, string[]][] = [
- [new vscode.Position(6, 4), ['Language']],
- [new vscode.Position(9, 4), ['GreetingText']],
- // checking for comment completions with begining of comment without space
- [new vscode.Position(12, 2), []],
- // cursor between /$/ this should not trigger any completion
- [new vscode.Position(12, 1), []],
- [new vscode.Position(12, 4), ['SayHello']],
- [new vscode.Position(17, 5), ['HelloParams']],
- [new vscode.Position(26, 5), ['Abs']]
- ];
- const uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'exportedMemberDocs.go'));
-
- const textDocument = await vscode.workspace.openTextDocument(uri);
- const editor = await vscode.window.showTextDocument(textDocument);
-
- const promises = testCases.map(([position, expected]) =>
- provider.provideCompletionItems(editor.document, position, dummyCancellationSource.token).then((items) => {
- const labels = items.items.map((x) => x.label);
- assert.equal(
- expected.length,
- labels.length,
- `expected number of completions: ${expected.length} Actual: ${labels.length} at position(${
- position.line + 1
- },${position.character + 1}) ${labels}`
- );
- expected.forEach((entry, index) => {
- assert.equal(
- entry,
- labels[index],
- `mismatch in comment completion list Expected: ${entry} Actual: ${labels[index]}`
- );
- });
- })
- );
- await Promise.all(promises);
- });
-
test('getImportPath()', () => {
const testCases: [string, string][] = [
['import "github.com/sirupsen/logrus"', 'github.com/sirupsen/logrus'],
@@ -1539,79 +619,6 @@
return strWithLF.split('\n').join('\r\n'); // replaceAll.
}

- test('Add imports when no imports', async () => {
- const uri = vscode.Uri.file(path.join(fixturePath, 'importTest', 'noimports.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- await vscode.window.showTextDocument(document);
-
- const expectedText = document.getText() + fixEOL(document.eol, '\n' + 'import (\n\t"bytes"\n)\n');
- const edits = getTextEditForAddImport('bytes');
- const edit = new vscode.WorkspaceEdit();
- assert(edits);
- edit.set(document.uri, edits);
- return vscode.workspace.applyEdit(edit).then(() => {
- assert.equal(
- vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.getText(),
- expectedText
- );
- return Promise.resolve();
- });
- });
-
- test('Add imports to an import block', async () => {
- const uri = vscode.Uri.file(path.join(fixturePath, 'importTest', 'groupImports.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- await vscode.window.showTextDocument(document);
- const eol = document.eol;
-
- const expectedText = document
- .getText()
- .replace(fixEOL(eol, '\t"fmt"\n\t"math"'), fixEOL(eol, '\t"bytes"\n\t"fmt"\n\t"math"'));
- const edits = getTextEditForAddImport('bytes');
- const edit = new vscode.WorkspaceEdit();
- assert(edits);
- edit.set(document.uri, edits);
- await vscode.workspace.applyEdit(edit);
- assert.equal(vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.getText(), expectedText);
- });
-
- test('Add imports and collapse single imports to an import block', async () => {
- const uri = vscode.Uri.file(path.join(fixturePath, 'importTest', 'singleImports.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- await vscode.window.showTextDocument(document);
- const eol = document.eol;
-
- const expectedText = document
- .getText()
- .replace(
- fixEOL(eol, 'import "fmt"\nimport . "math" // comment'),
- fixEOL(eol, 'import (\n\t"bytes"\n\t"fmt"\n\t. "math" // comment\n)')
- );
- const edits = getTextEditForAddImport('bytes');
- const edit = new vscode.WorkspaceEdit();
- assert(edits);
- edit.set(document.uri, edits);
- await vscode.workspace.applyEdit(edit);
- assert.equal(vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.getText(), expectedText);
- });
-
- test('Add imports and avoid pseudo package imports for cgo', async () => {
- const uri = vscode.Uri.file(path.join(fixturePath, 'importTest', 'cgoImports.go'));
- const document = await vscode.workspace.openTextDocument(uri);
- await vscode.window.showTextDocument(document);
- const eol = document.eol;
-
- const expectedText = document
- .getText()
- .replace(fixEOL(eol, 'import "math"'), fixEOL(eol, 'import (\n\t"bytes"\n\t"math"\n)'));
- const edits = getTextEditForAddImport('bytes');
- const edit = new vscode.WorkspaceEdit();
- assert(edits);
- edit.set(document.uri, edits);
- await vscode.workspace.applyEdit(edit);
- assert.equal(vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.getText(), expectedText);
- });
-
test('Fill struct', async () => {
const uri = vscode.Uri.file(path.join(fixturePath, 'fillStruct', 'input_1.go'));
const golden = fs.readFileSync(path.join(fixturePath, 'fillStruct', 'golden_1.go'), 'utf-8');

To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: vscode-go
Gerrit-Branch: master
Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
Gerrit-Change-Number: 535096
Gerrit-PatchSet: 1
Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>

kokoro (Gerrit)

unread,
Oct 12, 2023, 11:57:46 PM10/12/23
to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Attention is currently required from: Hyang-Ah Hana Kim.

Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/c7547f94-12e5-4557-accc-ee3c69dc6a06

Patch set 1:TryBot-Result -1

View Change

    To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-MessageType: comment
    Gerrit-Project: vscode-go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
    Gerrit-Change-Number: 535096
    Gerrit-PatchSet: 1
    Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
    Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
    Gerrit-Reviewer: kokoro <noreply...@google.com>
    Gerrit-CC: kokoro <noreply...@google.com>
    Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
    Gerrit-Comment-Date: Fri, 13 Oct 2023 03:57:42 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes

    Hyang-Ah Hana Kim (Gerrit)

    unread,
    Oct 13, 2023, 8:38:26 AM10/13/23
    to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Hyang-Ah Hana Kim.

    Hyang-Ah Hana Kim uploaded patch set #2 to this change.

    View Change

    The following approvals got outdated and were removed: Commit-Queue+1 by Hyang-Ah Hana Kim, TryBot-Result-1 by kokoro

    src/language/legacy: delete legacy language feature providers

    Except the legacy goFormat provider. It is still used for custom
    formatter feature implementation.

    Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
    ---
    M src/commands/startLanguageServer.ts
    M src/goDocumentSymbols.ts
    M src/goGenerateTests.ts
    M src/goImport.ts
    M src/goRunTestCodelens.ts

    M src/goTools.ts
    D src/language/legacy/goCodeAction.ts
    D src/language/legacy/goDeclaration.ts
    D src/language/legacy/goExtraInfo.ts
    D src/language/legacy/goImplementations.ts
    D src/language/legacy/goLiveErrors.ts
    D src/language/legacy/goOutline.ts
    D src/language/legacy/goRefactor.ts
    D src/language/legacy/goReferences.ts
    D src/language/legacy/goRename.ts
    D src/language/legacy/goSignature.ts
    D src/language/legacy/goSuggest.ts
    D src/language/legacy/goSymbol.ts
    D src/language/legacy/goTypeDefinition.ts
    M src/language/registerDefaultProviders.ts
    M test/integration/extension.test.ts
    21 files changed, 12 insertions(+), 3,504 deletions(-)

    To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-MessageType: newpatchset
    Gerrit-Project: vscode-go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
    Gerrit-Change-Number: 535096
    Gerrit-PatchSet: 2

    kokoro (Gerrit)

    unread,
    Oct 13, 2023, 8:48:20 AM10/13/23
    to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Hyang-Ah Hana Kim.

    Kokoro presubmit build finished with status: FAILURE
    Logs at: https://source.cloud.google.com/results/invocations/f64809c1-4357-4bd0-8b3e-588b372ef39d

    Patch set 2:TryBot-Result -1

    View Change

      To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: vscode-go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
      Gerrit-Change-Number: 535096
      Gerrit-PatchSet: 2
      Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: kokoro <noreply...@google.com>
      Gerrit-CC: kokoro <noreply...@google.com>
      Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Comment-Date: Fri, 13 Oct 2023 12:48:14 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: Yes

      kokoro (Gerrit)

      unread,
      Oct 14, 2023, 4:55:44 PM10/14/23
      to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

      Attention is currently required from: Hyang-Ah Hana Kim.

      Kokoro presubmit build finished with status: FAILURE

      View Change

        To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: comment
        Gerrit-Project: vscode-go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
        Gerrit-Change-Number: 535096
        Gerrit-PatchSet: 3
        Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: kokoro <noreply...@google.com>
        Gerrit-CC: kokoro <noreply...@google.com>
        Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Comment-Date: Sat, 14 Oct 2023 20:55:40 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes

        Hyang-Ah Hana Kim (Gerrit)

        unread,
        Oct 15, 2023, 6:12:41 PM10/15/23
        to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

        Attention is currently required from: Hyang-Ah Hana Kim.

        Hyang-Ah Hana Kim uploaded patch set #4 to this change.

        View Change

        The following approvals got outdated and were removed: Commit-Queue+1 by Hyang-Ah Hana Kim, TryBot-Result-1 by kokoro

        src/language/legacy: delete legacy language feature providers

        Except the legacy goFormat provider. It is still used for custom
        formatter feature implementation.

        Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
        ---
        M src/commands/startLanguageServer.ts
        M src/goDocumentSymbols.ts
        M src/goGenerateTests.ts
        M src/goImport.ts
        M src/goRunTestCodelens.ts
        M src/goTest/explore.ts

        M src/goTools.ts
        D src/language/legacy/goCodeAction.ts
        D src/language/legacy/goDeclaration.ts
        D src/language/legacy/goExtraInfo.ts
        D src/language/legacy/goImplementations.ts
        D src/language/legacy/goLiveErrors.ts
        D src/language/legacy/goOutline.ts
        D src/language/legacy/goRefactor.ts
        D src/language/legacy/goReferences.ts
        D src/language/legacy/goRename.ts
        D src/language/legacy/goSignature.ts
        D src/language/legacy/goSuggest.ts
        D src/language/legacy/goSymbol.ts
        D src/language/legacy/goTypeDefinition.ts
        M src/language/registerDefaultProviders.ts
        M src/testUtils.ts
        M test/integration/extension.test.ts
        23 files changed, 15 insertions(+), 3,507 deletions(-)

        To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: newpatchset
        Gerrit-Project: vscode-go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
        Gerrit-Change-Number: 535096
        Gerrit-PatchSet: 4

        kokoro (Gerrit)

        unread,
        Oct 15, 2023, 6:27:31 PM10/15/23
        to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

        Attention is currently required from: Hyang-Ah Hana Kim.

        Kokoro presubmit build finished with status: FAILURE
        Logs at: https://source.cloud.google.com/results/invocations/a9ceff2c-84f3-4535-b42d-4c7b68266b0c

        Patch set 4:TryBot-Result -1

        View Change

          To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-MessageType: comment
          Gerrit-Project: vscode-go
          Gerrit-Branch: master
          Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
          Gerrit-Change-Number: 535096
          Gerrit-PatchSet: 4
          Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
          Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
          Gerrit-Reviewer: kokoro <noreply...@google.com>
          Gerrit-CC: kokoro <noreply...@google.com>
          Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
          Gerrit-Comment-Date: Sun, 15 Oct 2023 22:27:28 +0000
          Gerrit-HasComments: No
          Gerrit-Has-Labels: Yes

          kokoro (Gerrit)

          unread,
          Oct 16, 2023, 11:23:23 AM10/16/23
          to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

          Attention is currently required from: Hyang-Ah Hana Kim.

          Kokoro presubmit build finished with status: SUCCESS
          Logs at: https://source.cloud.google.com/results/invocations/8084279d-178a-479c-abf6-fb3d6ffae790

          Patch set 5:TryBot-Result +1

          View Change

            To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-MessageType: comment
            Gerrit-Project: vscode-go
            Gerrit-Branch: master
            Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
            Gerrit-Change-Number: 535096
            Gerrit-PatchSet: 5
            Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
            Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
            Gerrit-Reviewer: kokoro <noreply...@google.com>
            Gerrit-CC: kokoro <noreply...@google.com>
            Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
            Gerrit-Comment-Date: Mon, 16 Oct 2023 15:23:19 +0000
            Gerrit-HasComments: No
            Gerrit-Has-Labels: Yes

            Hyang-Ah Hana Kim (Gerrit)

            unread,
            Oct 16, 2023, 11:08:44 PM10/16/23
            to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

            Attention is currently required from: Hyang-Ah Hana Kim.

            Hyang-Ah Hana Kim uploaded patch set #6 to this change.

            View Change

            src/language/legacy: delete legacy language feature providers


            Except the legacy goFormat provider. It is still used for custom
            formatter feature implementation.

            For golang/vscode-go#2799

            To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-MessageType: newpatchset
            Gerrit-Project: vscode-go
            Gerrit-Branch: master
            Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
            Gerrit-Change-Number: 535096
            Gerrit-PatchSet: 6

            kokoro (Gerrit)

            unread,
            Oct 16, 2023, 11:20:35 PM10/16/23
            to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

            Attention is currently required from: Hyang-Ah Hana Kim.

            Kokoro presubmit build finished with status: SUCCESS
            Logs at: https://source.cloud.google.com/results/invocations/79421091-a58b-4209-a42f-1f62bf46f067

            Patch set 6:TryBot-Result +1

            View Change

              To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-MessageType: comment
              Gerrit-Project: vscode-go
              Gerrit-Branch: master
              Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
              Gerrit-Change-Number: 535096
              Gerrit-PatchSet: 6
              Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
              Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
              Gerrit-Reviewer: kokoro <noreply...@google.com>
              Gerrit-CC: kokoro <noreply...@google.com>
              Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
              Gerrit-Comment-Date: Tue, 17 Oct 2023 03:20:31 +0000
              Gerrit-HasComments: No
              Gerrit-Has-Labels: Yes

              kokoro (Gerrit)

              unread,
              Oct 23, 2023, 4:42:37 PM10/23/23
              to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

              Attention is currently required from: Hyang-Ah Hana Kim.

              Kokoro presubmit build finished with status: SUCCESS

              View Change

                To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-MessageType: comment
                Gerrit-Project: vscode-go
                Gerrit-Branch: master
                Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
                Gerrit-Change-Number: 535096
                Gerrit-PatchSet: 7
                Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
                Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
                Gerrit-Reviewer: kokoro <noreply...@google.com>
                Gerrit-CC: kokoro <noreply...@google.com>
                Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
                Gerrit-Comment-Date: Mon, 23 Oct 2023 20:42:33 +0000
                Gerrit-HasComments: No
                Gerrit-Has-Labels: Yes

                Suzy Mueller (Gerrit)

                unread,
                Oct 24, 2023, 1:53:46 PM10/24/23
                to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, Robert Findley, kokoro, golang-co...@googlegroups.com

                Attention is currently required from: Hyang-Ah Hana Kim, Robert Findley.

                Patch set 7:Code-Review +2

                View Change

                  To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-MessageType: comment
                  Gerrit-Project: vscode-go
                  Gerrit-Branch: master
                  Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
                  Gerrit-Change-Number: 535096
                  Gerrit-PatchSet: 7
                  Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
                  Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
                  Gerrit-Reviewer: Robert Findley <rfin...@google.com>
                  Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
                  Gerrit-Reviewer: kokoro <noreply...@google.com>
                  Gerrit-CC: kokoro <noreply...@google.com>
                  Gerrit-Attention: Robert Findley <rfin...@google.com>
                  Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
                  Gerrit-Comment-Date: Tue, 24 Oct 2023 17:53:40 +0000
                  Gerrit-HasComments: No
                  Gerrit-Has-Labels: Yes

                  Hyang-Ah Hana Kim (Gerrit)

                  unread,
                  Oct 25, 2023, 11:45:44 AM10/25/23
                  to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Suzy Mueller, Robert Findley, kokoro, golang-co...@googlegroups.com

                  Hyang-Ah Hana Kim submitted this change.

                  View Change

                  Approvals: Suzy Mueller: Looks good to me, approved Hyang-Ah Hana Kim: Run LUCI TryBots kokoro: TryBots succeeded
                  src/language/legacy: delete legacy language feature providers

                  Except the legacy goFormat provider. It is still used for custom
                  formatter feature implementation.

                  For golang/vscode-go#2799

                  Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
                  Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/535096
                  Reviewed-by: Suzy Mueller <suz...@golang.org>
                  TryBot-Result: kokoro <noreply...@google.com>
                  Commit-Queue: Hyang-Ah Hana Kim <hya...@gmail.com>
                  diff --git a/src/commands/startLanguageServer.ts b/src/commands/startLanguageServer.ts
                  index 42ccefa..7f56f3e 100644
                  --- a/src/commands/startLanguageServer.ts
                  +++ b/src/commands/startLanguageServer.ts
                  @@ -86,7 +86,7 @@
                  }

                  if (!cfg.enabled) {
                  - const legacyService = new LegacyLanguageService(ctx, goCtx);
                  + const legacyService = new LegacyLanguageService();
                  goCtx.legacyLanguageService = legacyService;
                  ctx.subscriptions.push(legacyService);
                  updateStatus(goCtx, goConfig, false);
                  diff --git a/src/goDocumentSymbols.ts b/src/goDocumentSymbols.ts
                  index ea5c4d4..bc5e881 100644
                  --- a/src/goDocumentSymbols.ts
                  +++ b/src/goDocumentSymbols.ts
                  @@ -7,16 +7,11 @@
                  import { DocumentSymbolRequest, ExecuteCommandParams, ExecuteCommandRequest } from 'vscode-languageserver-protocol';

                  import { getGoConfig } from './config';
                  import { GoExtensionContext } from './context';
                  -import { GoLegacyDocumentSymbolProvider } from './language/legacy/goOutline';

                   export function GoDocumentSymbolProvider(
                  goCtx: GoExtensionContext,

                  includeImports?: boolean
                  -): GoplsDocumentSymbolProvider | GoLegacyDocumentSymbolProvider {
                  - const { latestConfig } = goCtx;
                  - if (!latestConfig?.enabled) {
                  - return new GoLegacyDocumentSymbolProvider(includeImports);
                  - }
                  +): GoplsDocumentSymbolProvider {
                  return new GoplsDocumentSymbolProvider(goCtx, includeImports);
                  }

                  @@ -25,6 +20,9 @@

                  constructor(private readonly goCtx: GoExtensionContext, private includeImports?: boolean) {}

                  public async provideDocumentSymbols(document: vscode.TextDocument): Promise<vscode.DocumentSymbol[]> {
                  + if (!this.goCtx.languageServerIsRunning) {
                  + return [];
                  + }
                  // TODO(suzmue): consider providing an interface for providing document symbols that only requires
                  // the URI. Getting a TextDocument from a filename requires opening the file, which can lead to
                  // files being opened that were not requested by the user in order to get information that we just
                  diff --git a/src/goGenerateTests.ts b/src/goGenerateTests.ts
                  index 12e0e42..d2ee0ad 100644
                  --- a/src/goGenerateTests.ts
                  +++ b/src/goGenerateTests.ts
                  @@ -244,6 +244,9 @@

                  async function getFunctions(goCtx: GoExtensionContext, doc: vscode.TextDocument): Promise<vscode.DocumentSymbol[]> {
                   	const documentSymbolProvider = GoDocumentSymbolProvider(goCtx);
                  diff --git a/src/goRunTestCodelens.ts b/src/goRunTestCodelens.ts
                  index 0baa8ee..1a66241 100644
                  --- a/src/goRunTestCodelens.ts
                  +++ b/src/goRunTestCodelens.ts
                  @@ -59,7 +59,7 @@

                  private async getCodeLensForPackage(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
                  const documentSymbolProvider = GoDocumentSymbolProvider(this.goCtx);
                  - const symbols = await documentSymbolProvider.provideDocumentSymbols(document, token);
                  + const symbols = await documentSymbolProvider.provideDocumentSymbols(document);
                  if (!symbols || symbols.length === 0) {
                  return [];
                  }
                  diff --git a/src/goTest/explore.ts b/src/goTest/explore.ts
                  index a9a75fe..bb5e009 100644
                  --- a/src/goTest/explore.ts
                  +++ b/src/goTest/explore.ts
                  @@ -37,8 +37,8 @@

                  const ctrl = vscode.tests.createTestController('go', 'Go');
                  const symProvider = GoDocumentSymbolProvider(goCtx, true);
                  - const inst = new this(goCtx, workspace, ctrl, context.workspaceState, (doc, token) =>
                  - symProvider.provideDocumentSymbols(doc, token)
                  + const inst = new this(goCtx, workspace, ctrl, context.workspaceState, (doc) =>
                  + symProvider.provideDocumentSymbols(doc)
                  );

                  // Process already open editors
                  diff --git a/src/goTools.ts b/src/goTools.ts
                  index 771e61c..628e065 100644

                  --- a/src/goTools.ts
                  +++ b/src/goTools.ts
                  @@ -12,7 +12,6 @@
                  import semver = require('semver');
                  import util = require('util');
                  import { getFormatTool, usingCustomFormatTool } from './language/legacy/goFormat';
                  -import { goLiveErrorsEnabled } from './language/legacy/goLiveErrors';
                  import { allToolsInformation } from './goToolsInformation';
                  import { getBinPath, GoVersion } from './util';

                  @@ -209,11 +208,6 @@
                  diff --git a/src/testUtils.ts b/src/testUtils.ts
                  index 1155a07..0b72d9f 100644
                  --- a/src/testUtils.ts
                  +++ b/src/testUtils.ts
                  @@ -154,7 +154,7 @@
                  token?: vscode.CancellationToken
                  ): Promise<vscode.DocumentSymbol[] | undefined> {
                  const documentSymbolProvider = GoDocumentSymbolProvider(goCtx, true);
                  - const symbols = await documentSymbolProvider.provideDocumentSymbols(doc, token);
                  + const symbols = await documentSymbolProvider.provideDocumentSymbols(doc);
                  if (!symbols || symbols.length === 0) {
                  return;
                  }
                  @@ -242,7 +242,7 @@
                  token?: vscode.CancellationToken
                  ): Promise<vscode.DocumentSymbol[] | undefined> {
                  const documentSymbolProvider = GoDocumentSymbolProvider(goCtx);
                  - const symbols = await documentSymbolProvider.provideDocumentSymbols(doc, token);
                  + const symbols = await documentSymbolProvider.provideDocumentSymbols(doc);
                  if (!symbols || symbols.length === 0) {
                  return;

                  To view, visit change 535096. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-MessageType: merged
                  Gerrit-Project: vscode-go
                  Gerrit-Branch: master
                  Gerrit-Change-Id: Ia4c04bc584110d88b728b7ee144a255645e458b6
                  Gerrit-Change-Number: 535096
                  Gerrit-PatchSet: 8
                  Reply all
                  Reply to author
                  Forward
                  0 new messages