Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Commit

Permalink
Fix signature for methods extending structs
Browse files Browse the repository at this point in the history
  • Loading branch information
ramya-rao-a committed Nov 18, 2016
1 parent d0c6671 commit 73dbfc4
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 46 deletions.
7 changes: 5 additions & 2 deletions src/goDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface GoDefinitionInformtation {
column: number;
doc: string;
declarationlines: string[];
name: string;
toolUsed: string;
}

Expand Down Expand Up @@ -67,7 +68,8 @@ function definitionLocation_godef(document: vscode.TextDocument, position: vscod
column: + col - 1,
declarationlines: lines.splice(1),
toolUsed: 'godef',
doc: null
doc: null,
name: null
};
if (!includeDocs) {
return resolve(definitionInformation);
Expand Down Expand Up @@ -121,7 +123,8 @@ function definitionLocation_gogetdoc(document: vscode.TextDocument, position: vs
column: 0,
toolUsed: 'gogetdoc',
declarationlines: goGetDocOutput.decl.split('\n'),
doc: goGetDocOutput.doc
doc: goGetDocOutput.doc,
name: goGetDocOutput.name
};
if (!match) {
return resolve(definitionInfo);
Expand Down
21 changes: 12 additions & 9 deletions src/goSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,25 @@ export class GoSignatureHelpProvider implements SignatureHelpProvider {
return null;
}
let result = new SignatureHelp();
let text, sig: string;
let declarationText, sig: string;
let si: SignatureInformation;
if (res.toolUsed === 'godef') {
// declaration is of the form "Add func(a int, b int) int"
text = res.declarationlines[0];
let nameEnd = text.indexOf(' ');
declarationText = res.declarationlines[0];
let nameEnd = declarationText.indexOf(' ');
let sigStart = nameEnd + 5; // ' func'
let funcName = text.substring(0, nameEnd);
sig = text.substring(sigStart);
let funcName = declarationText.substring(0, nameEnd);
sig = declarationText.substring(sigStart);
si = new SignatureInformation(funcName + sig, res.doc);
} else {
// declaration is of the form "func Add(a int, b int) int"
text = res.declarationlines[0].substring(5);
si = new SignatureInformation(text, res.doc);
let braceStart = text.indexOf('(');
sig = text.substring(braceStart);
declarationText = res.declarationlines[0].substring(5);
let 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);
}

si.parameters = parameters(sig).map(paramText =>
Expand Down
43 changes: 43 additions & 0 deletions test/fixtures/gogetdocTestData/test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package abc

import (
"fmt"
"math"
"net"
)

// ABC is a struct, you coudnt use Goto Definition or Hover info on this before
// Now you can due to gogetdoc
type ABC struct {
a int
b int
c int
}

// This is an unexported function so couldnt get this comment on hover :(
// Not anymore!! gogetdoc to the rescue
func print(txt string) {
fmt.Println(txt)
}

func main() {
print("Hello")
}

// Hello is a method on the struct ABC. Will signature help understand this correctly
func (abcd *ABC) Hello(s string, exclaim bool) string {
net.CIDRMask(1, 2)
if exclaim {
s = s + "!"
}
if abcd.a+abcd.b+abcd.c > 3 {
return "Hello " + s
}
return "GoodBye " + s
}

// Greetings is an exported function. So all is good.
func Greetings() string {
xyz := ABC{1, 2, int(math.Abs(-1))}
return xyz.Hello("World", false)
}
11 changes: 0 additions & 11 deletions test/fixtures/vendorTest/vd.go

This file was deleted.

68 changes: 44 additions & 24 deletions test/go.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ suite('Go Extension Tests', () => {
suiteSetup(() => {
assert.ok(gopath !== null, 'GOPATH is not defined');
fs.removeSync(repoPath);
fs.mkdirsSync(path.join(fixturePath, 'vendor', 'abc', 'internal'));
fs.copySync(path.join(fixtureSourcePath, 'test.go'), path.join(fixturePath, 'test.go'));
fs.copySync(path.join(fixtureSourcePath, 'errorsTest', 'errors.go'), path.join(fixturePath, 'errorsTest', 'errors.go'));
fs.copySync(path.join(fixtureSourcePath, 'sample_test.go'), path.join(fixturePath, 'sample_test.go'));
fs.copySync(path.join(fixtureSourcePath, 'gogetdocTestData', 'test.go'), path.join(fixturePath, 'gogetdocTestData', 'test.go'));
});

suiteTeardown(() => {
Expand All @@ -57,18 +57,19 @@ suite('Go Extension Tests', () => {
});
}

function testSignatureHelpProvider(tool: string): Thenable<any> {
function testSignatureHelpProvider(tool: string, testCases: [vscode.Position, string, string, string[]][]): Thenable<any> {
let provider = new GoSignatureHelpProvider(tool);
let testCases: [vscode.Position, string][] = [
[new vscode.Position(7, 13), 'Println(a ...interface{}) (n int, err error)'],
[new vscode.Position(10, 7), 'print(txt string)']
];
let uri = vscode.Uri.file(path.join(fixturePath, 'test.go'));
let uri = vscode.Uri.file(path.join(fixturePath, 'gogetdocTestData', 'test.go'));
return vscode.workspace.openTextDocument(uri).then((textDocument) => {
let promises = testCases.map(([position, expected]) =>
let promises = testCases.map(([position, expected, expectedDoc, expectedParams]) =>
provider.provideSignatureHelp(textDocument, position, null).then(sigHelp => {
assert.equal(sigHelp.signatures.length, 1, 'unexpected number of overloads');
assert.equal(sigHelp.signatures[0].label, expected);
assert.equal(sigHelp.signatures[0].documentation, expectedDoc);
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);
Expand All @@ -80,7 +81,7 @@ suite('Go Extension Tests', () => {

function testHoverProvider(tool: string, testCases: [vscode.Position, string, string][]): Thenable<any> {
let provider = new GoHoverProvider(tool);
let uri = vscode.Uri.file(path.join(fixturePath, 'test.go'));
let uri = vscode.Uri.file(path.join(fixturePath, 'gogetdocTestData', 'test.go'));
return vscode.workspace.openTextDocument(uri).then((textDocument) => {
let promises = testCases.map(([position, expectedSignature, expectedDocumentation]) =>
provider.provideHover(textDocument, position, null).then(res => {
Expand Down Expand Up @@ -115,13 +116,32 @@ suite('Go Extension Tests', () => {
});

test('Test SignatureHelp Provider using godoc', (done) => {
testSignatureHelpProvider('godoc').then(() => done(), done);
let printlnDoc = `Println formats using the default formats for its operands and writes to
standard output. Spaces are always added between operands and a newline
is appended. It returns the number of bytes written and any write error
encountered.
`;
let testCases: [vscode.Position, string, string, string[]][] = [
[new vscode.Position(19, 13), 'Println(a ...interface{}) (n int, err error)', printlnDoc, ['a ...interface{}']],
[new vscode.Position(23, 7), 'print(txt string)', null, ['txt string']],
[new vscode.Position(41, 19), 'Hello(s string, exclaim bool) string', null, ['s string', 'exclaim bool']]
];
testSignatureHelpProvider('godoc', testCases).then(() => done(), done);
});

test('Test SignatureHelp Provider using gogetdoc', (done) => {
let printlnDoc = `Println formats using the default formats for its operands and writes to standard output.
Spaces are always added between operands and a newline is appended.
It returns the number of bytes written and any write error encountered.
`;
let testCases: [vscode.Position, string, string, string[]][] = [
[new vscode.Position(19, 13), 'Println(a ...interface{}) (n int, err error)', printlnDoc, ['a ...interface{}']],
[new vscode.Position(23, 7), 'print(txt string)', 'This is an unexported function so couldnt get this comment on hover :(\nNot anymore!! gogetdoc to the rescue\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']]
];
getGoVersion().then(version => {
if (version.major > 1 || (version.major === 1 && version.minor > 5)) {
return testSignatureHelpProvider('gogetdoc');
return testSignatureHelpProvider('gogetdoc', testCases);
}
return Promise.resolve();
}).then(() => done(), done);
Expand All @@ -135,26 +155,26 @@ encountered.
`;
let testCases: [vscode.Position, string, string][] = [
// [new vscode.Position(3,3), '/usr/local/go/src/fmt'],
[new vscode.Position(9, 6), 'main func()', null],
[new vscode.Position(7, 2), 'import (fmt "fmt")', null],
[new vscode.Position(7, 6), 'Println func(a ...interface{}) (n int, err error)', printlnDoc],
[new vscode.Position(10, 3), 'print func(txt string)', null]
[new vscode.Position(22, 5), 'main func()', null],
[new vscode.Position(40, 23), 'import (math "math")', null],
[new vscode.Position(19, 6), 'Println func(a ...interface{}) (n int, err error)', printlnDoc],
[new vscode.Position(23, 4), 'print func(txt string)', null]
];
testHoverProvider('godoc', testCases).then(() => done(), done);
});

test('Test Hover Provider using gogetdoc', (done) => {
let printlnDoc = `Println formats using the default formats for its operands and writes to
standard output. Spaces are always added between operands and a newline
is appended. It returns the number of bytes written and any write error
encountered.
let printlnDoc = `Println formats using the default formats for its operands and writes to standard output.
Spaces are always added between operands and a newline is appended.
It returns the number of bytes written and any write error encountered.
`;
let testCases: [vscode.Position, string, string][] = [
// [new vscode.Position(3,3), '/usr/local/go/src/fmt'],
[new vscode.Position(9, 6), 'func main()', null],
[new vscode.Position(7, 2), 'package fmt', null],
[new vscode.Position(7, 6), 'func Println(a ...interface{}) (n int, err error)', printlnDoc],
[new vscode.Position(10, 3), 'func print(txt string)', null]
[new vscode.Position(22, 5), 'func main()', ''],
[new vscode.Position(23, 4), 'func print(txt string)', 'This is an unexported function so couldnt get this comment on hover :(\nNot anymore!! gogetdoc to the rescue\n'],
[new vscode.Position(40, 23), 'package math', 'Package math provides basic constants and mathematical functions.\n'],
[new vscode.Position(19, 6), 'func Println(a ...interface{}) (n int, err error)', printlnDoc],
[new vscode.Position(27, 14), 'type ABC struct {\n a int\n b int\n c int\n}', 'ABC is a struct, you coudnt use Goto Definition or Hover info on this before\nNow you can due to gogetdoc\n'],
[new vscode.Position(28, 6), 'func CIDRMask(ones, bits int) IPMask', 'CIDRMask returns an IPMask consisting of `ones\' 1 bits\nfollowed by 0s up to a total length of `bits\' bits.\nFor a mask of this form, CIDRMask is the inverse of IPMask.Size.\n']
];
getGoVersion().then(version => {
if (version.major > 1 || (version.major === 1 && version.minor > 5)) {
Expand Down

0 comments on commit 73dbfc4

Please sign in to comment.