diff --git a/tagmanager/ctags/go.c b/tagmanager/ctags/go.c index 61706437..41755d45 100644 --- a/tagmanager/ctags/go.c +++ b/tagmanager/ctags/go.c @@ -528,7 +528,7 @@ static boolean skipType (tokenInfo *const token) static void makeTag (tokenInfo *const token, const goKind kind, tokenInfo *const parent_token, const goKind parent_kind, - const char *argList) + const char *argList, const char *varType) { const char *const name = vStringValue (token->string); @@ -544,6 +544,8 @@ static void makeTag (tokenInfo *const token, const goKind kind, e.kind = GoKinds [kind].letter; if (argList) e.extensionFields.arglist = argList; + if (varType) + e.extensionFields.varType = varType; if (parent_kind != GOTAG_UNDEFINED && parent_token != NULL) { @@ -569,7 +571,7 @@ static void parsePackage (tokenInfo *const token) readToken (token); if (isType (token, TOKEN_IDENTIFIER)) { - makeTag (token, GOTAG_PACKAGE, NULL, GOTAG_UNDEFINED, NULL); + makeTag (token, GOTAG_PACKAGE, NULL, GOTAG_UNDEFINED, NULL, NULL); if (!scope && Option.include.qualifiedTags) { scope = vStringNew (); @@ -594,6 +596,7 @@ static void parseFunctionOrMethod (tokenInfo *const token) if (isType (token, TOKEN_IDENTIFIER)) { + vString *argList; tokenInfo *functionToken = copyToken (token); // Start recording signature @@ -605,18 +608,28 @@ static void parseFunctionOrMethod (tokenInfo *const token) vStringStripLeading (signature); vStringStripTrailing (signature); - makeTag (functionToken, GOTAG_FUNCTION, NULL, GOTAG_UNDEFINED, signature->buffer); - deleteToken (functionToken); - vStringDelete(signature); - - // Stop recording signature - signature = NULL; + argList = signature; + signature = vStringNew (); readToken (token); // Skip over result. skipType (token); + // Remove the extra { we have just read + vStringStripTrailing (signature); + vStringChop (signature); + + vStringStripLeading (signature); + vStringStripTrailing (signature); + makeTag (functionToken, GOTAG_FUNCTION, NULL, GOTAG_UNDEFINED, argList->buffer, signature->buffer); + deleteToken (functionToken); + vStringDelete(signature); + vStringDelete(argList); + + // Stop recording signature + signature = NULL; + // Skip over function body. if (isType (token, TOKEN_OPEN_CURLY)) skipToMatched (token); @@ -655,11 +668,11 @@ static void parseStructMembers (tokenInfo *const token, tokenInfo *const parent_ if (memberCandidate) { // if we are here, there was a comma and memberCandidate isn't an anonymous field - makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL); + makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL, NULL); deleteToken (memberCandidate); memberCandidate = NULL; } - makeTag (token, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL); + makeTag (token, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL, NULL); } readToken (token); } @@ -672,7 +685,7 @@ static void parseStructMembers (tokenInfo *const token, tokenInfo *const parent_ // type into memberCandidate and skipType() should return FALSE so no tag should // be generated in this case. if (skipType (token) && memberCandidate) - makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL); + makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL, NULL); if (memberCandidate) deleteToken (memberCandidate); @@ -725,15 +738,15 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind) typeToken = copyToken (token); readToken (token); if (isKeyword (token, KEYWORD_struct)) - makeTag (typeToken, GOTAG_STRUCT, NULL, GOTAG_UNDEFINED, NULL); + makeTag (typeToken, GOTAG_STRUCT, NULL, GOTAG_UNDEFINED, NULL, NULL); else if (isKeyword (token, KEYWORD_interface)) - makeTag (typeToken, GOTAG_INTERFACE, NULL, GOTAG_UNDEFINED, NULL); + makeTag (typeToken, GOTAG_INTERFACE, NULL, GOTAG_UNDEFINED, NULL, NULL); else - makeTag (typeToken, kind, NULL, GOTAG_UNDEFINED, NULL); + makeTag (typeToken, kind, NULL, GOTAG_UNDEFINED, NULL, NULL); break; } else - makeTag (token, kind, NULL, GOTAG_UNDEFINED, NULL); + makeTag (token, kind, NULL, GOTAG_UNDEFINED, NULL, NULL); readToken (token); } if (!isType (token, TOKEN_COMMA)) diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index 475fd33e..f7f5970a 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -243,6 +243,7 @@ test_sources = \ refcurs.sql \ regexp.js \ return-hint.zep \ + return-types.go \ rules.t2t \ sample.t2t \ secondary_fcn_name.js \ diff --git a/tests/ctags/return-types.go b/tests/ctags/return-types.go new file mode 100644 index 00000000..0b0bbd5d --- /dev/null +++ b/tests/ctags/return-types.go @@ -0,0 +1,16 @@ +package main + +func foo() *struct {a int; b func()} { + return nil +} + +func bar() (a int, b func(a int), c interface{}, d string) { + return 0, nil, nil, "" +} + +func baz() *[20*3+1]map[chan<- /* map[int]int */<-chan int]map[interface{}]*string { + return nil +} + +func main() { +} \ No newline at end of file diff --git a/tests/ctags/return-types.go.tags b/tests/ctags/return-types.go.tags new file mode 100644 index 00000000..16fe4a4b --- /dev/null +++ b/tests/ctags/return-types.go.tags @@ -0,0 +1,6 @@ +# format=tagmanager +barÌ16Í()Ö0Ï(a int, b func(a int), c interface{}, d string) +bazÌ16Í()Ö0Ï*[20*3+1]map[chan<- <-chan int]map[interface{}]*string +fooÌ16Í()Ö0Ï*struct {a int; b func()} +mainÌ16Í()Ö0Ï +mainÌ256Ö0 diff --git a/tests/ctags/test.go.tags b/tests/ctags/test.go.tags index 3f16c9fa..d5fb79fb 100644 --- a/tests/ctags/test.go.tags +++ b/tests/ctags/test.go.tags @@ -28,12 +28,12 @@ c dÌ16384Ö0 eÌ16384Ö0 fÌ16384Ö0 -f1Ì16Í()Ö0 -f2Ì16Í()Ö0 -f3Ì16Í()Ö0 -f4Ì16Í(a func () func ())Ö0 -f5Ì16Í()Ö0 +f1Ì16Í()Ö0Ï +f2Ì16Í()Ö0Ï +f3Ì16Í()Ö0Ï(a, b int) +f4Ì16Í(a func () func ())Ö0Ï(func (), int) +f5Ì16Í()Ö0Ï gÌ16384Ö0 hÌ16384Ö0 -mainÌ16Í()Ö0 +mainÌ16Í()Ö0Ï mainÌ256Ö0