Merge pull request #481 from techee/go
Go ctags parser, Scintilla lexer and Geany support improvements Closes #238.
This commit is contained in:
commit
f1c98e5423
@ -4,13 +4,17 @@
|
||||
|
||||
[keywords]
|
||||
# all items must be in one line
|
||||
primary=break case chan const continue default defer else fallthrough for func go goto if import interface map package range return select struct switch type var
|
||||
secondary=byte bool rune int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float32 float64 complex64 complex128 uintptr string
|
||||
primary=break case chan const continue default defer else fallthrough for func go goto if import interface map package range return select struct switch type var true false iota nil
|
||||
secondary=bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr
|
||||
|
||||
# these are the Doxygen keywords
|
||||
docComment=a addindex addtogroup anchor arg attention author authors b brief bug c callergraph callgraph category cite class code cond copybrief copydetails copydoc copyright date def defgroup deprecated details dir dontinclude dot dotfile e else elseif em endcode endcond enddot endhtmlonly endif endinternal endlatexonly endlink endmanonly endmsc endrtfonly endverbatim endxmlonly enum example exception extends file fn headerfile hideinitializer htmlinclude htmlonly if ifnot image implements include includelineno ingroup interface internal invariant latexonly li line link mainpage manonly memberof msc mscfile n name namespace nosubgrouping note overload p package page par paragraph param post pre private privatesection property protected protectedsection protocol public publicsection ref related relatedalso relates relatesalso remark remarks result return returns retval rtfonly sa section see short showinitializer since skip skipline snippet struct subpage subsection subsubsection tableofcontents test throw throws todo tparam typedef union until var verbatim verbinclude version warning weakgroup xmlonly xrefitem
|
||||
|
||||
[lexer_properties=C]
|
||||
[lexer_properties]
|
||||
lexer.cpp.backquoted.strings=1
|
||||
styling.within.preprocessor=1
|
||||
lexer.cpp.allow.dollars=0
|
||||
fold.preprocessor=0
|
||||
|
||||
[settings]
|
||||
|
||||
|
@ -2649,6 +2649,7 @@ void document_highlight_tags(GeanyDocument *doc)
|
||||
case GEANY_FILETYPES_OBJECTIVEC:
|
||||
case GEANY_FILETYPES_VALA:
|
||||
case GEANY_FILETYPES_RUST:
|
||||
case GEANY_FILETYPES_GO:
|
||||
{
|
||||
|
||||
/* index of the keyword set in the Scintilla lexer, for
|
||||
|
@ -1790,7 +1790,7 @@ static gboolean append_calltip(GString *str, const TMTag *tag, filetype_id ft_id
|
||||
if (! tag->arglist)
|
||||
return FALSE;
|
||||
|
||||
if (ft_id != GEANY_FILETYPES_PASCAL)
|
||||
if (ft_id != GEANY_FILETYPES_PASCAL && ft_id != GEANY_FILETYPES_GO)
|
||||
{ /* usual calltips: "retval tagname (arglist)" */
|
||||
if (tag->var_type)
|
||||
{
|
||||
@ -1815,14 +1815,15 @@ static gboolean append_calltip(GString *str, const TMTag *tag, filetype_id ft_id
|
||||
g_string_append(str, tag->arglist);
|
||||
}
|
||||
else
|
||||
{ /* special case Pascal calltips: "tagname (arglist) : retval" */
|
||||
{ /* special case Pascal/Go calltips: "tagname (arglist) : retval"
|
||||
* (with ':' omitted for Go) */
|
||||
g_string_append(str, tag->name);
|
||||
g_string_append_c(str, ' ');
|
||||
g_string_append(str, tag->arglist);
|
||||
|
||||
if (!EMPTY(tag->var_type))
|
||||
{
|
||||
g_string_append(str, " : ");
|
||||
g_string_append(str, ft_id == GEANY_FILETYPES_PASCAL ? " : " : " ");
|
||||
g_string_append(str, tag->var_type);
|
||||
}
|
||||
}
|
||||
|
@ -698,7 +698,7 @@ static void add_top_level_items(GeanyDocument *doc)
|
||||
&(tv_iters.tag_variable), _("Variables"), "classviewer-var",
|
||||
&(tv_iters.tag_macro), _("Macros"), "classviewer-macro",
|
||||
&(tv_iters.tag_member), _("Methods"), "classviewer-member",
|
||||
&(tv_iters.tag_other), _("Other"), "classviewer-other", NULL,
|
||||
&(tv_iters.tag_other), _("Other"), "classviewer-other",
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
@ -707,10 +707,13 @@ static void add_top_level_items(GeanyDocument *doc)
|
||||
tag_list_add_groups(tag_store,
|
||||
&(tv_iters.tag_namespace), _("Package"), "classviewer-namespace",
|
||||
&(tv_iters.tag_function), _("Functions"), "classviewer-method",
|
||||
&(tv_iters.tag_macro), _("Constants"), "classviewer-macro",
|
||||
&(tv_iters.tag_interface), _("Interfaces"), "classviewer-struct",
|
||||
&(tv_iters.tag_struct), _("Structs"), "classviewer-struct",
|
||||
&(tv_iters.tag_type), _("Types"), "classviewer-struct",
|
||||
&(tv_iters.tag_macro), _("Constants"), "classviewer-macro",
|
||||
&(tv_iters.tag_variable), _("Variables"), "classviewer-var",
|
||||
&(tv_iters.tag_other), _("Other"), "classviewer-other", NULL,
|
||||
&(tv_iters.tag_member), _("Members"), "classviewer-member",
|
||||
&(tv_iters.tag_other), _("Other"), "classviewer-other",
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*
|
||||
* MACROS
|
||||
*/
|
||||
#define MAX_SIGNATURE_LENGTH 512
|
||||
#define isType(token,t) (boolean) ((token)->type == (t))
|
||||
#define isKeyword(token,k) (boolean) ((token)->keyword == (k))
|
||||
|
||||
@ -77,6 +78,7 @@ typedef struct sTokenInfo {
|
||||
|
||||
static int Lang_go;
|
||||
static vString *scope;
|
||||
static vString *signature = NULL;
|
||||
|
||||
typedef enum {
|
||||
GOTAG_UNDEFINED = -1,
|
||||
@ -85,6 +87,9 @@ typedef enum {
|
||||
GOTAG_CONST,
|
||||
GOTAG_TYPE,
|
||||
GOTAG_VAR,
|
||||
GOTAG_STRUCT,
|
||||
GOTAG_INTERFACE,
|
||||
GOTAG_MEMBER
|
||||
} goKind;
|
||||
|
||||
static kindOption GoKinds[] = {
|
||||
@ -92,7 +97,10 @@ static kindOption GoKinds[] = {
|
||||
{TRUE, 'f', "function", "functions"},
|
||||
{TRUE, 'c', "macro", "constants"},
|
||||
{TRUE, 't', "typedef", "types"},
|
||||
{TRUE, 'v', "variable", "variables"}
|
||||
{TRUE, 'v', "variable", "variables"},
|
||||
{TRUE, 's', "struct", "structs"},
|
||||
{TRUE, 'i', "interface", "interfaces"},
|
||||
{TRUE, 'm', "member", "struct members"}
|
||||
};
|
||||
|
||||
static keywordDesc GoKeywordTable[] = {
|
||||
@ -149,6 +157,17 @@ static tokenInfo *newToken (void)
|
||||
return token;
|
||||
}
|
||||
|
||||
static tokenInfo *copyToken (tokenInfo *other)
|
||||
{
|
||||
tokenInfo *const token = xMalloc (1, tokenInfo);
|
||||
token->type = other->type;
|
||||
token->keyword = other->keyword;
|
||||
token->string = vStringNewCopy (other->string);
|
||||
token->lineNumber = other->lineNumber;
|
||||
token->filePosition = other->filePosition;
|
||||
return token;
|
||||
}
|
||||
|
||||
static void deleteToken (tokenInfo * const token)
|
||||
{
|
||||
if (token != NULL)
|
||||
@ -201,6 +220,8 @@ static void readToken (tokenInfo *const token)
|
||||
{
|
||||
int c;
|
||||
static tokenType lastTokenType = TOKEN_NONE;
|
||||
boolean firstWhitespace = TRUE;
|
||||
boolean whitespace;
|
||||
|
||||
token->type = TOKEN_NONE;
|
||||
token->keyword = KEYWORD_NONE;
|
||||
@ -219,11 +240,16 @@ getNextChar:
|
||||
lastTokenType == TOKEN_CLOSE_CURLY ||
|
||||
lastTokenType == TOKEN_CLOSE_SQUARE))
|
||||
{
|
||||
token->type = TOKEN_SEMICOLON;
|
||||
goto done;
|
||||
c = ';'; // semicolon injection
|
||||
}
|
||||
whitespace = c == '\t' || c == ' ' || c == '\r' || c == '\n';
|
||||
if (signature && whitespace && firstWhitespace && vStringLength (signature) < MAX_SIGNATURE_LENGTH)
|
||||
{
|
||||
firstWhitespace = FALSE;
|
||||
vStringPut(signature, ' ');
|
||||
}
|
||||
}
|
||||
while (c == '\t' || c == ' ' || c == '\r' || c == '\n');
|
||||
while (whitespace);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
@ -354,71 +380,79 @@ getNextChar:
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if (signature && vStringLength (signature) < MAX_SIGNATURE_LENGTH)
|
||||
{
|
||||
if (token->type == TOKEN_LEFT_ARROW)
|
||||
vStringCatS(signature, "<-");
|
||||
else if (token->type == TOKEN_STRING)
|
||||
{
|
||||
// only struct member annotations can appear in function prototypes
|
||||
// so only `` type strings are possible
|
||||
vStringPut(signature, '`');
|
||||
vStringCat(signature, token->string);
|
||||
vStringPut(signature, '`');
|
||||
}
|
||||
else if (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_KEYWORD)
|
||||
vStringCat(signature, token->string);
|
||||
else if (c != EOF)
|
||||
vStringPut(signature, c);
|
||||
}
|
||||
|
||||
lastTokenType = token->type;
|
||||
}
|
||||
|
||||
static void skipToMatched (tokenInfo *const token)
|
||||
static boolean skipToMatchedNoRead (tokenInfo *const token)
|
||||
{
|
||||
int nest_level = 0;
|
||||
tokenType open_token;
|
||||
tokenType open_token = token->type;
|
||||
tokenType close_token;
|
||||
|
||||
switch (token->type)
|
||||
switch (open_token)
|
||||
{
|
||||
case TOKEN_OPEN_PAREN:
|
||||
open_token = TOKEN_OPEN_PAREN;
|
||||
close_token = TOKEN_CLOSE_PAREN;
|
||||
break;
|
||||
case TOKEN_OPEN_CURLY:
|
||||
open_token = TOKEN_OPEN_CURLY;
|
||||
close_token = TOKEN_CLOSE_CURLY;
|
||||
break;
|
||||
case TOKEN_OPEN_SQUARE:
|
||||
open_token = TOKEN_OPEN_SQUARE;
|
||||
close_token = TOKEN_CLOSE_SQUARE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will skip to a matching closing token.
|
||||
* It will also handle nested tokens like the (, ) below.
|
||||
* ( name varchar(30), text binary(10) )
|
||||
* It will also handle nested tokens.
|
||||
*/
|
||||
if (isType (token, open_token))
|
||||
nest_level++;
|
||||
while (nest_level > 0 && !isType (token, TOKEN_EOF))
|
||||
{
|
||||
nest_level++;
|
||||
while (!(isType (token, close_token) && (nest_level == 0)) &&
|
||||
!isType (token, TOKEN_EOF))
|
||||
{
|
||||
readToken (token);
|
||||
if (isType (token, open_token))
|
||||
{
|
||||
nest_level++;
|
||||
}
|
||||
if (isType (token, close_token))
|
||||
{
|
||||
if (nest_level > 0)
|
||||
{
|
||||
nest_level--;
|
||||
}
|
||||
}
|
||||
}
|
||||
readToken (token);
|
||||
if (isType (token, open_token))
|
||||
nest_level++;
|
||||
else if (isType (token, close_token))
|
||||
nest_level--;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void skipType (tokenInfo *const token)
|
||||
static void skipToMatched (tokenInfo *const token)
|
||||
{
|
||||
if (skipToMatchedNoRead (token))
|
||||
readToken (token);
|
||||
}
|
||||
|
||||
static boolean skipType (tokenInfo *const token)
|
||||
{
|
||||
again:
|
||||
// Type = TypeName | TypeLit | "(" Type ")" .
|
||||
// Skips also function multiple return values "(" Type {"," Type} ")"
|
||||
if (isType (token, TOKEN_OPEN_PAREN))
|
||||
{
|
||||
skipToMatched (token);
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// TypeName = QualifiedIdent.
|
||||
@ -433,7 +467,7 @@ again:
|
||||
if (isType (token, TOKEN_IDENTIFIER))
|
||||
readToken (token);
|
||||
}
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// StructType = "struct" "{" { FieldDecl ";" } "}"
|
||||
@ -443,7 +477,7 @@ again:
|
||||
readToken (token);
|
||||
// skip over "{}"
|
||||
skipToMatched (token);
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ArrayType = "[" ArrayLength "]" ElementType .
|
||||
@ -452,7 +486,7 @@ again:
|
||||
if (isType (token, TOKEN_OPEN_SQUARE))
|
||||
{
|
||||
skipToMatched (token);
|
||||
goto again;
|
||||
return skipType (token);
|
||||
}
|
||||
|
||||
// PointerType = "*" BaseType .
|
||||
@ -461,7 +495,7 @@ again:
|
||||
if (isType (token, TOKEN_STAR) || isKeyword (token, KEYWORD_chan) || isType (token, TOKEN_LEFT_ARROW))
|
||||
{
|
||||
readToken (token);
|
||||
goto again;
|
||||
return skipType (token);
|
||||
}
|
||||
|
||||
// MapType = "map" "[" KeyType "]" ElementType .
|
||||
@ -471,7 +505,7 @@ again:
|
||||
readToken (token);
|
||||
// skip over "[]"
|
||||
skipToMatched (token);
|
||||
goto again;
|
||||
return skipType (token);
|
||||
}
|
||||
|
||||
// FunctionType = "func" Signature .
|
||||
@ -486,11 +520,15 @@ again:
|
||||
// Result is parameters or type or nothing. skipType treats anything
|
||||
// surrounded by parentheses as a type, and does nothing if what
|
||||
// follows is not a type.
|
||||
goto again;
|
||||
return skipType (token);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void makeTag (tokenInfo *const token, const goKind kind)
|
||||
static void makeTag (tokenInfo *const token, const goKind kind,
|
||||
tokenInfo *const parent_token, const goKind parent_kind,
|
||||
const char *argList, const char *varType)
|
||||
{
|
||||
const char *const name = vStringValue (token->string);
|
||||
|
||||
@ -504,7 +542,16 @@ static void makeTag (tokenInfo *const token, const goKind kind)
|
||||
e.filePosition = token->filePosition;
|
||||
e.kindName = GoKinds [kind].name;
|
||||
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)
|
||||
{
|
||||
e.extensionFields.scope[0] = GoKinds[parent_kind].name;
|
||||
e.extensionFields.scope[1] = vStringValue (parent_token->string);
|
||||
}
|
||||
makeTagEntry (&e);
|
||||
|
||||
if (scope && Option.include.qualifiedTags)
|
||||
@ -524,7 +571,7 @@ static void parsePackage (tokenInfo *const token)
|
||||
readToken (token);
|
||||
if (isType (token, TOKEN_IDENTIFIER))
|
||||
{
|
||||
makeTag (token, GOTAG_PACKAGE);
|
||||
makeTag (token, GOTAG_PACKAGE, NULL, GOTAG_UNDEFINED, NULL, NULL);
|
||||
if (!scope && Option.include.qualifiedTags)
|
||||
{
|
||||
scope = vStringNew ();
|
||||
@ -549,21 +596,115 @@ static void parseFunctionOrMethod (tokenInfo *const token)
|
||||
|
||||
if (isType (token, TOKEN_IDENTIFIER))
|
||||
{
|
||||
makeTag (token, GOTAG_FUNCTION);
|
||||
|
||||
vString *argList;
|
||||
tokenInfo *functionToken = copyToken (token);
|
||||
|
||||
// Start recording signature
|
||||
signature = vStringNew ();
|
||||
|
||||
// Skip over parameters.
|
||||
readToken (token);
|
||||
skipToMatched (token);
|
||||
skipToMatchedNoRead (token);
|
||||
|
||||
vStringStripLeading (signature);
|
||||
vStringStripTrailing (signature);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void parseStructMembers (tokenInfo *const token, tokenInfo *const parent_token)
|
||||
{
|
||||
// StructType = "struct" "{" { FieldDecl ";" } "}" .
|
||||
// FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] .
|
||||
// AnonymousField = [ "*" ] TypeName .
|
||||
// Tag = string_lit .
|
||||
|
||||
readToken (token);
|
||||
if (!isType (token, TOKEN_OPEN_CURLY))
|
||||
return;
|
||||
|
||||
readToken (token);
|
||||
while (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))
|
||||
{
|
||||
tokenInfo *memberCandidate = NULL;
|
||||
boolean first = TRUE;
|
||||
|
||||
while (!isType (token, TOKEN_EOF))
|
||||
{
|
||||
if (isType (token, TOKEN_IDENTIFIER))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
// could be anonymous field like in 'struct {int}' - we don't know yet
|
||||
memberCandidate = copyToken (token);
|
||||
first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
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, NULL);
|
||||
deleteToken (memberCandidate);
|
||||
memberCandidate = NULL;
|
||||
}
|
||||
makeTag (token, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL, NULL);
|
||||
}
|
||||
readToken (token);
|
||||
}
|
||||
if (!isType (token, TOKEN_COMMA))
|
||||
break;
|
||||
readToken (token);
|
||||
}
|
||||
|
||||
// in the case of an anonymous field, we already read part of the
|
||||
// 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, NULL);
|
||||
|
||||
if (memberCandidate)
|
||||
deleteToken (memberCandidate);
|
||||
|
||||
while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_CURLY)
|
||||
&& !isType (token, TOKEN_EOF))
|
||||
{
|
||||
readToken (token);
|
||||
skipToMatched (token);
|
||||
}
|
||||
|
||||
if (!isType (token, TOKEN_CLOSE_CURLY))
|
||||
{
|
||||
// we are at TOKEN_SEMICOLON
|
||||
readToken (token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parseConstTypeVar (tokenInfo *const token, goKind kind)
|
||||
{
|
||||
// ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
|
||||
@ -586,11 +727,26 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind)
|
||||
|
||||
do
|
||||
{
|
||||
tokenInfo *typeToken = NULL;
|
||||
|
||||
while (!isType (token, TOKEN_EOF))
|
||||
{
|
||||
if (isType (token, TOKEN_IDENTIFIER))
|
||||
{
|
||||
makeTag (token, kind);
|
||||
if (kind == GOTAG_TYPE)
|
||||
{
|
||||
typeToken = copyToken (token);
|
||||
readToken (token);
|
||||
if (isKeyword (token, KEYWORD_struct))
|
||||
makeTag (typeToken, GOTAG_STRUCT, NULL, GOTAG_UNDEFINED, NULL, NULL);
|
||||
else if (isKeyword (token, KEYWORD_interface))
|
||||
makeTag (typeToken, GOTAG_INTERFACE, NULL, GOTAG_UNDEFINED, NULL, NULL);
|
||||
else
|
||||
makeTag (typeToken, kind, NULL, GOTAG_UNDEFINED, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
else
|
||||
makeTag (token, kind, NULL, GOTAG_UNDEFINED, NULL, NULL);
|
||||
readToken (token);
|
||||
}
|
||||
if (!isType (token, TOKEN_COMMA))
|
||||
@ -598,7 +754,17 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind)
|
||||
readToken (token);
|
||||
}
|
||||
|
||||
skipType (token);
|
||||
if (typeToken)
|
||||
{
|
||||
if (isKeyword (token, KEYWORD_struct))
|
||||
parseStructMembers (token, typeToken);
|
||||
else
|
||||
skipType (token);
|
||||
deleteToken (typeToken);
|
||||
}
|
||||
else
|
||||
skipType (token);
|
||||
|
||||
while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_PAREN)
|
||||
&& !isType (token, TOKEN_EOF))
|
||||
{
|
||||
|
@ -243,6 +243,7 @@ test_sources = \
|
||||
refcurs.sql \
|
||||
regexp.js \
|
||||
return-hint.zep \
|
||||
return-types.go \
|
||||
rules.t2t \
|
||||
sample.t2t \
|
||||
secondary_fcn_name.js \
|
||||
|
16
tests/ctags/return-types.go
Normal file
16
tests/ctags/return-types.go
Normal file
@ -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() {
|
||||
}
|
6
tests/ctags/return-types.go.tags
Normal file
6
tests/ctags/return-types.go.tags
Normal file
@ -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
|
@ -15,8 +15,11 @@ type (
|
||||
)
|
||||
|
||||
type T6 struct {
|
||||
a, b, c, d int
|
||||
e float32
|
||||
_a, _b, _c, _d int
|
||||
int
|
||||
T1 `annotation`
|
||||
*T2
|
||||
_e float32
|
||||
//ignored int
|
||||
}
|
||||
|
||||
@ -44,4 +47,4 @@ func (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f
|
||||
func main() {
|
||||
go func (){}()
|
||||
fmt.Println("Hello, 世界")
|
||||
}
|
||||
}
|
@ -12,23 +12,28 @@ T1
|
||||
T2フ4096ヨ0
|
||||
T3フ4096ヨ0
|
||||
T4フ4096ヨ0
|
||||
T5フ4096ヨ0
|
||||
T6フ4096ヨ0
|
||||
T5Ì32Ö0
|
||||
T6Ì2048Ö0
|
||||
T7フ4096ヨ0
|
||||
T8フ4096ヨ0
|
||||
T9フ4096ヨ0
|
||||
_aÌ64ÎT6Ö0
|
||||
_bÌ64ÎT6Ö0
|
||||
_cÌ64ÎT6Ö0
|
||||
_dÌ64ÎT6Ö0
|
||||
_eÌ64ÎT6Ö0
|
||||
aフ16384ヨ0
|
||||
bフ16384ヨ0
|
||||
cフ16384ヨ0
|
||||
dフ16384ヨ0
|
||||
eフ16384ヨ0
|
||||
fフ16384ヨ0
|
||||
f1フ16ヨ0
|
||||
f2フ16ヨ0
|
||||
f3フ16ヨ0
|
||||
f4フ16ヨ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
|
||||
|
Loading…
x
Reference in New Issue
Block a user