diff --git a/src/goSignature.ts b/src/goSignature.ts index afaa418af..bcb96b57e 100755 --- a/src/goSignature.ts +++ b/src/goSignature.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import { SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, TextDocument, Position, CancellationToken, WorkspaceConfiguration } from 'vscode'; import { definitionLocation } from './goDeclaration'; -import { parameters } from './util'; +import { getParametersAndReturnType } from './util'; export class GoSignatureHelpProvider implements SignatureHelpProvider { private goConfig = null; @@ -66,7 +66,7 @@ export class GoSignatureHelpProvider implements SignatureHelpProvider { sig = declarationText.substring(res.name.length); } - si.parameters = parameters(sig).map(paramText => + si.parameters = getParametersAndReturnType(sig).params.map(paramText => new ParameterInformation(paramText) ); result.signatures = [si]; diff --git a/src/goSuggest.ts b/src/goSuggest.ts index e1b3ae8f6..bcc7eb330 100644 --- a/src/goSuggest.ts +++ b/src/goSuggest.ts @@ -7,7 +7,7 @@ import vscode = require('vscode'); import cp = require('child_process'); -import { getBinPath, parameters, parseFilePrelude, isPositionInString, goKeywords, getToolsEnvVars, guessPackageNameFromFile, goBuiltinTypes, byteOffsetAt } from './util'; +import { getBinPath, getParametersAndReturnType, parseFilePrelude, isPositionInString, goKeywords, getToolsEnvVars, guessPackageNameFromFile, goBuiltinTypes, byteOffsetAt } from './util'; import { promptForMissingTool } from './goInstallTools'; import { getTextEditForAddImport } from './goImport'; import { getImportablePackages } from './goPackages'; @@ -170,8 +170,8 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider { ); } if ((config['useCodeSnippetsOnFunctionSuggest'] || config['useCodeSnippetsOnFunctionSuggestWithoutType']) - && (suggest.class === 'func' || suggest.class === 'var' && suggest.type.startsWith('func('))) { - let params = parameters(suggest.type.substring(4)); + && (suggest.class === 'func' || suggest.class === 'var' && suggest.type.startsWith('func('))) { + let { params, returnType } = getParametersAndReturnType(suggest.type.substring(4)); let paramSnippets = []; for (let i = 0; i < params.length; i++) { let param = params[i].trim(); @@ -189,7 +189,7 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider { item.insertText = new vscode.SnippetString(suggest.name + '(' + paramSnippets.join(', ') + ')'); } if (config['useCodeSnippetsOnFunctionSuggest'] && suggest.class === 'type' && suggest.type.startsWith('func(')) { - let params = parameters(suggest.type.substring(4)); + let { params, returnType } = getParametersAndReturnType(suggest.type.substring(4)); let paramSnippets = []; for (let i = 0; i < params.length; i++) { let param = params[i].trim(); @@ -203,7 +203,7 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider { 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})'); + item.insertText = new vscode.SnippetString(suggest.name + '(func(' + paramSnippets.join(', ') + ') {\n $' + (params.length + 1) + '\n})' + returnType); } if (wordAtPosition && wordAtPosition.start.character === 0 && diff --git a/src/util.ts b/src/util.ts index 25d544aff..414c85441 100644 --- a/src/util.ts +++ b/src/util.ts @@ -122,8 +122,8 @@ export function parseFilePrelude(text: string): Prelude { // ["foo", "bar string", "baz string"] // Takes care of balancing parens so to not get confused by signatures like: // (pattern string, handler func(ResponseWriter, *Request)) { -export function parameters(signature: string): string[] { - let ret: string[] = []; +export function getParametersAndReturnType(signature: string): { params: string[], returnType: string } { + let params: string[] = []; let parenCount = 0; let lastStart = 1; for (let i = 1; i < signature.length; i++) { @@ -135,20 +135,23 @@ export function parameters(signature: string): string[] { parenCount--; if (parenCount < 0) { if (i > lastStart) { - ret.push(signature.substring(lastStart, i)); + params.push(signature.substring(lastStart, i)); } - return ret; + return { + params, + returnType: i < signature.length - 1 ? signature.substr(i + 1) : '' + }; } break; case ',': if (parenCount === 0) { - ret.push(signature.substring(lastStart, i)); + params.push(signature.substring(lastStart, i)); lastStart = i + 2; } break; } } - return null; + return { params: [], returnType: '' }; } export function canonicalizeGOPATHPrefix(filename: string): string { diff --git a/test/fixtures/completions/snippets.go b/test/fixtures/completions/snippets.go index 4c02750b2..a89ed2a7e 100644 --- a/test/fixtures/completions/snippets.go +++ b/test/fixtures/completions/snippets.go @@ -1,10 +1,10 @@ package main import "fmt" -import "net/http" -type HandlerFunc func(http.ResponseWriter, *http.Request) -type HandlerFuncWithArgNames func(w http.ResponseWriter, r *http.Request) +type HandlerFunc func(string, string) (string, string) +type HandlerFuncWithArgNames func(w string, r string) int +type HandlerFuncNoReturnType func(string, string) func main(){ fmt.Println("hello") diff --git a/test/go.test.ts b/test/go.test.ts index 7af60f923..824d3a8da 100644 --- a/test/go.test.ts +++ b/test/go.test.ts @@ -810,15 +810,19 @@ It returns the number of bytes written and any write error encountered. let noFunctionAsTypeSnippet = provider.provideCompletionItemsInternal(editor.document, new vscode.Position(14, 0), null, Object.create(baseConfig, {'useCodeSnippetsOnFunctionSuggest': { value: false }})).then(items => { let item1 = items.find(x => x.label === 'HandlerFunc'); let item2 = items.find(x => x.label === 'HandlerFuncWithArgNames'); + let item3 = items.find(x => x.label === 'HandlerFuncNoReturnType'); assert.equal(!item1.insertText, true); assert.equal(!item2.insertText, true); + assert.equal(!item3.insertText, true); }); let withFunctionAsTypeSnippet = provider.provideCompletionItemsInternal(editor.document, new vscode.Position(14, 0), null, Object.create(baseConfig, {'useCodeSnippetsOnFunctionSuggest': { value: true }})).then(items => { let item1 = items.find(x => x.label === 'HandlerFunc'); let item2 = items.find(x => x.label === 'HandlerFuncWithArgNames'); - assert.equal((item1.insertText).value, 'HandlerFunc(func(${1:arg1} http.ResponseWriter, ${2:arg2} *http.Request) {\n\t$3\n})'); - assert.equal((item2.insertText).value, 'HandlerFuncWithArgNames(func(${1:w} http.ResponseWriter, ${2:r} *http.Request) {\n\t$3\n})'); + let item3 = items.find(x => x.label === 'HandlerFuncNoReturnType'); + assert.equal((item1.insertText).value, 'HandlerFunc(func(${1:arg1} string, ${2:arg2} string) {\n\t$3\n}) (string, string)'); + assert.equal((item2.insertText).value, 'HandlerFuncWithArgNames(func(${1:w} string, ${2:r} string) {\n\t$3\n}) int'); + assert.equal((item3.insertText).value, 'HandlerFuncNoReturnType(func(${1:arg1} string, ${2:arg2} string) {\n\t$3\n})'); }); return Promise.all([