Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Sun, 30 Nov 2014 01:03:00 UTC Commit: 94aa892c8177e93d0dff3edf853854e872f19d20 https://github.com/geany/geany/commit/94aa892c8177e93d0dff3edf853854e872f19d...
Log Message: ----------- Merge pull request #373 from techee/go_ctags
Add a Go ctags parser.
Modified Paths: -------------- data/Makefile.am data/filetype_extensions.conf data/filetypes.go src/filetypes.c src/filetypes.h src/highlighting.c src/highlightingmappings.h src/symbols.c tagmanager/ctags/Makefile.am tagmanager/ctags/go.c tagmanager/ctags/makefile.win32 tagmanager/ctags/parsers.h tagmanager/src/tm_parser.h tests/ctags/Makefile.am tests/ctags/test.go tests/ctags/test.go.tags wscript
Modified: data/Makefile.am 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -34,7 +34,7 @@ filetypes = \ filetypes.freebasic \ filetypes.Genie.conf \ filetypes.glsl \ - filetypes.Go.conf \ + filetypes.go \ filetypes.Graphviz.conf \ filetypes.haskell \ filetypes.haxe \
Modified: data/filetype_extensions.conf 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -70,7 +70,7 @@ None=*;
# Note: restarting is required after editing groups [Groups] -Programming=Clojure;CUDA;Cython;Genie;Go;Rust;Scala; +Programming=Clojure;CUDA;Cython;Genie;Scala; Script=Graphviz; Markup= Misc=
Modified: data/filetypes.go 1 lines changed, 0 insertions(+), 1 deletions(-) =================================================================== @@ -13,7 +13,6 @@ docComment=a addindex addtogroup anchor arg attention author authors b brief bug [lexer_properties=C]
[settings] -lexer_filetype=C
# default extension used when saving files extension=go
Modified: src/filetypes.c 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -191,6 +191,7 @@ static void init_builtin_filetypes(void) FT_INIT( POWERSHELL, NONE, "PowerShell", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( RUST, RUST, "Rust", NULL, SOURCE_FILE, COMPILED ); FT_INIT( COFFEESCRIPT, NONE, "CoffeeScript", NULL, SOURCE_FILE, SCRIPT ); + FT_INIT( GO, GO, "Go", NULL, SOURCE_FILE, COMPILED ); }
Modified: src/filetypes.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -101,6 +101,7 @@ typedef enum GEANY_FILETYPES_POWERSHELL, GEANY_FILETYPES_RUST, GEANY_FILETYPES_COFFEESCRIPT, + GEANY_FILETYPES_GO, /* ^ append items here */ GEANY_MAX_BUILT_IN_FILETYPES /* Don't use this, use filetypes_array->len instead */ }
Modified: src/highlighting.c 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -1013,6 +1013,7 @@ void highlighting_init_styles(guint filetype_idx, GKeyFile *config, GKeyFile *co init_styleset_case(F77); init_styleset_case(FORTH); init_styleset_case(FORTRAN); + init_styleset_case(GO); init_styleset_case(HASKELL); init_styleset_case(HAXE); init_styleset_case(AS); @@ -1097,6 +1098,7 @@ void highlighting_set_styles(ScintillaObject *sci, GeanyFiletype *ft) styleset_case(F77); styleset_case(FORTH); styleset_case(FORTRAN); + styleset_case(GO); styleset_case(HASKELL); styleset_case(HAXE); styleset_case(AS);
Modified: src/highlightingmappings.h 7 lines changed, 7 insertions(+), 0 deletions(-) =================================================================== @@ -652,6 +652,13 @@ static const HLKeyword highlighting_keywords_FORTH[] = #define highlighting_properties_FORTRAN highlighting_properties_F77
+/* Go */ +#define highlighting_lexer_GO SCLEX_CPP +#define highlighting_styles_GO highlighting_styles_C +#define highlighting_keywords_GO highlighting_keywords_C +#define highlighting_properties_GO highlighting_properties_C + + /* Haskell */ #define highlighting_lexer_HASKELL SCLEX_HASKELL static const HLStyle highlighting_styles_HASKELL[] =
Modified: src/symbols.c 12 lines changed, 12 insertions(+), 0 deletions(-) =================================================================== @@ -754,6 +754,18 @@ static void add_top_level_items(GeanyDocument *doc) NULL); break; } + case GEANY_FILETYPES_GO: + { + 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_type), _("Types"), "classviewer-struct", + &(tv_iters.tag_variable), _("Variables"), "classviewer-var", + &(tv_iters.tag_other), _("Other"), "classviewer-other", NULL, + NULL); + break; + } case GEANY_FILETYPES_PERL: { tag_list_add_groups(tag_store,
Modified: tagmanager/ctags/Makefile.am 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -24,6 +24,7 @@ parsers = \ diff.c \ docbook.c \ fortran.c \ + go.c \ haskell.c \ haxe.c \ html.c \
Modified: tagmanager/ctags/go.c 687 lines changed, 687 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,687 @@ +/* +* INCLUDE FILES +*/ +#include "general.h" /* must always come first */ + +#include "entry.h" +#include "keyword.h" +#include "read.h" +#include "main.h" +#include "vstring.h" +#include "options.h" + +/* + * MACROS + */ +#define isType(token,t) (boolean) ((token)->type == (t)) +#define isKeyword(token,k) (boolean) ((token)->keyword == (k)) + +/* + * DATA DECLARATIONS + */ + +typedef enum eKeywordId { + KEYWORD_NONE = -1, + KEYWORD_package, + KEYWORD_import, + KEYWORD_const, + KEYWORD_type, + KEYWORD_var, + KEYWORD_func, + KEYWORD_struct, + KEYWORD_interface, + KEYWORD_map, + KEYWORD_chan +} keywordId; + +/* Used to determine whether keyword is valid for the current language and + * what its ID is. + */ +typedef struct sKeywordDesc { + const char *name; + keywordId id; +} keywordDesc; + +typedef enum eTokenType { + TOKEN_NONE = -1, + // Token not important for top-level Go parsing + TOKEN_OTHER, + TOKEN_KEYWORD, + TOKEN_IDENTIFIER, + TOKEN_STRING, + TOKEN_OPEN_PAREN, + TOKEN_CLOSE_PAREN, + TOKEN_OPEN_CURLY, + TOKEN_CLOSE_CURLY, + TOKEN_OPEN_SQUARE, + TOKEN_CLOSE_SQUARE, + TOKEN_SEMICOLON, + TOKEN_STAR, + TOKEN_LEFT_ARROW, + TOKEN_DOT, + TOKEN_COMMA, + TOKEN_EOF +} tokenType; + +typedef struct sTokenInfo { + tokenType type; + keywordId keyword; + vString *string; /* the name of the token */ + unsigned long lineNumber; /* line number of tag */ + MIOPos filePosition; /* file position of line containing name */ +} tokenInfo; + +/* +* DATA DEFINITIONS +*/ + +static int Lang_go; +static vString *scope; + +typedef enum { + GOTAG_UNDEFINED = -1, + GOTAG_PACKAGE, + GOTAG_FUNCTION, + GOTAG_CONST, + GOTAG_TYPE, + GOTAG_VAR, +} goKind; + +static kindOption GoKinds[] = { + {TRUE, 'p', "namespace", "packages"}, + {TRUE, 'f', "function", "functions"}, + {TRUE, 'c', "macro", "constants"}, + {TRUE, 't', "typedef", "types"}, + {TRUE, 'v', "variable", "variables"} +}; + +static keywordDesc GoKeywordTable[] = { + {"package", KEYWORD_package}, + {"import", KEYWORD_import}, + {"const", KEYWORD_const}, + {"type", KEYWORD_type}, + {"var", KEYWORD_var}, + {"func", KEYWORD_func}, + {"struct", KEYWORD_struct}, + {"interface", KEYWORD_interface}, + {"map", KEYWORD_map}, + {"chan", KEYWORD_chan} +}; + +/* +* FUNCTION DEFINITIONS +*/ + +// XXX UTF-8 +static boolean isStartIdentChar (const int c) +{ + return (boolean) + (isalpha (c) || c == '_' || c > 128); +} + +static boolean isIdentChar (const int c) +{ + return (boolean) + (isStartIdentChar (c) || isdigit (c)); +} + +static void initialize (const langType language) +{ + size_t i; + const size_t count = + sizeof (GoKeywordTable) / sizeof (GoKeywordTable[0]); + Lang_go = language; + for (i = 0; i < count; ++i) + { + const keywordDesc *const p = &GoKeywordTable[i]; + addKeyword (p->name, language, (int) p->id); + } +} + +static tokenInfo *newToken (void) +{ + tokenInfo *const token = xMalloc (1, tokenInfo); + token->type = TOKEN_NONE; + token->keyword = KEYWORD_NONE; + token->string = vStringNew (); + token->lineNumber = getSourceLineNumber (); + token->filePosition = getInputFilePosition (); + return token; +} + +static void deleteToken (tokenInfo * const token) +{ + if (token != NULL) + { + vStringDelete (token->string); + eFree (token); + } +} + +/* + * Parsing functions + */ + +static void parseString (vString *const string, const int delimiter) +{ + boolean end = FALSE; + while (!end) + { + int c = fileGetc (); + if (c == EOF) + end = TRUE; + else if (c == '\' && delimiter != '`') + { + c = fileGetc (); + if (c != ''' && c != '"') + vStringPut (string, '\'); + vStringPut (string, c); + } + else if (c == delimiter) + end = TRUE; + else + vStringPut (string, c); + } + vStringTerminate (string); +} + +static void parseIdentifier (vString *const string, const int firstChar) +{ + int c = firstChar; + do + { + vStringPut (string, c); + c = fileGetc (); + } while (isIdentChar (c)); + vStringTerminate (string); + fileUngetc (c); /* always unget, LF might add a semicolon */ +} + +static void readToken (tokenInfo *const token) +{ + int c; + static tokenType lastTokenType = TOKEN_NONE; + + token->type = TOKEN_NONE; + token->keyword = KEYWORD_NONE; + vStringClear (token->string); + +getNextChar: + do + { + c = fileGetc (); + token->lineNumber = getSourceLineNumber (); + token->filePosition = getInputFilePosition (); + if (c == '\n' && (lastTokenType == TOKEN_IDENTIFIER || + lastTokenType == TOKEN_STRING || + lastTokenType == TOKEN_OTHER || + lastTokenType == TOKEN_CLOSE_PAREN || + lastTokenType == TOKEN_CLOSE_CURLY || + lastTokenType == TOKEN_CLOSE_SQUARE)) + { + token->type = TOKEN_SEMICOLON; + goto done; + } + } + while (c == '\t' || c == ' ' || c == '\r' || c == '\n'); + + switch (c) + { + case EOF: + token->type = TOKEN_EOF; + break; + + case ';': + token->type = TOKEN_SEMICOLON; + break; + + case '/': + { + boolean hasNewline = FALSE; + int d = fileGetc (); + switch (d) + { + case '/': + fileSkipToCharacter ('\n'); + /* Line comments start with the + * character sequence // and + * continue through the next + * newline. A line comment acts + * like a newline. */ + fileUngetc ('\n'); + goto getNextChar; + case '*': + do + { + do + { + d = fileGetc (); + if (d == '\n') + { + hasNewline = TRUE; + } + } while (d != EOF && d != '*'); + + c = fileGetc (); + if (c == '/') + break; + else + fileUngetc (c); + } while (c != EOF && c != '\0'); + + fileUngetc (hasNewline ? '\n' : ' '); + goto getNextChar; + default: + token->type = TOKEN_OTHER; + fileUngetc (d); + break; + } + } + break; + + case '"': + case ''': + case '`': + token->type = TOKEN_STRING; + parseString (token->string, c); + token->lineNumber = getSourceLineNumber (); + token->filePosition = getInputFilePosition (); + break; + + case '<': + { + int d = fileGetc (); + if (d == '-') + token->type = TOKEN_LEFT_ARROW; + else + { + fileUngetc (d); + token->type = TOKEN_OTHER; + } + } + break; + + case '(': + token->type = TOKEN_OPEN_PAREN; + break; + + case ')': + token->type = TOKEN_CLOSE_PAREN; + break; + + case '{': + token->type = TOKEN_OPEN_CURLY; + break; + + case '}': + token->type = TOKEN_CLOSE_CURLY; + break; + + case '[': + token->type = TOKEN_OPEN_SQUARE; + break; + + case ']': + token->type = TOKEN_CLOSE_SQUARE; + break; + + case '*': + token->type = TOKEN_STAR; + break; + + case '.': + token->type = TOKEN_DOT; + break; + + case ',': + token->type = TOKEN_COMMA; + break; + + default: + if (isStartIdentChar (c)) + { + parseIdentifier (token->string, c); + token->lineNumber = getSourceLineNumber (); + token->filePosition = getInputFilePosition (); + token->keyword = lookupKeyword (vStringValue (token->string), Lang_go); + if (isKeyword (token, KEYWORD_NONE)) + token->type = TOKEN_IDENTIFIER; + else + token->type = TOKEN_KEYWORD; + } + else + token->type = TOKEN_OTHER; + break; + } + +done: + lastTokenType = token->type; +} + +static void skipToMatched (tokenInfo *const token) +{ + int nest_level = 0; + tokenType open_token; + tokenType close_token; + + switch (token->type) + { + 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; + } + + /* + * This routine will skip to a matching closing token. + * It will also handle nested tokens like the (, ) below. + * ( name varchar(30), text binary(10) ) + */ + if (isType (token, open_token)) + { + 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); + } +} + +static void 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; + } + + // TypeName = QualifiedIdent. + // QualifiedIdent = [ PackageName "." ] identifier . + // PackageName = identifier . + if (isType (token, TOKEN_IDENTIFIER)) + { + readToken (token); + if (isType (token, TOKEN_DOT)) + { + readToken (token); + if (isType (token, TOKEN_IDENTIFIER)) + readToken (token); + } + return; + } + + // StructType = "struct" "{" { FieldDecl ";" } "}" + // InterfaceType = "interface" "{" { MethodSpec ";" } "}" . + if (isKeyword (token, KEYWORD_struct) || isKeyword (token, KEYWORD_interface)) + { + readToken (token); + // skip over "{}" + skipToMatched (token); + return; + } + + // ArrayType = "[" ArrayLength "]" ElementType . + // SliceType = "[" "]" ElementType . + // ElementType = Type . + if (isType (token, TOKEN_OPEN_SQUARE)) + { + skipToMatched (token); + goto again; + } + + // PointerType = "*" BaseType . + // BaseType = Type . + // ChannelType = ( "chan" [ "<-" ] | "<-" "chan" ) ElementType . + if (isType (token, TOKEN_STAR) || isKeyword (token, KEYWORD_chan) || isType (token, TOKEN_LEFT_ARROW)) + { + readToken (token); + goto again; + } + + // MapType = "map" "[" KeyType "]" ElementType . + // KeyType = Type . + if (isKeyword (token, KEYWORD_map)) + { + readToken (token); + // skip over "[]" + skipToMatched (token); + goto again; + } + + // FunctionType = "func" Signature . + // Signature = Parameters [ Result ] . + // Result = Parameters | Type . + // Parameters = "(" [ ParameterList [ "," ] ] ")" . + if (isKeyword (token, KEYWORD_func)) + { + readToken (token); + // Parameters, skip over "()" + skipToMatched (token); + // 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; + } +} + +static void makeTag (tokenInfo *const token, const goKind kind) +{ + const char *const name = vStringValue (token->string); + + tagEntryInfo e; + initTagEntry (&e, name); + + if (!GoKinds [kind].enabled) + return; + + e.lineNumber = token->lineNumber; + e.filePosition = token->filePosition; + e.kindName = GoKinds [kind].name; + e.kind = GoKinds [kind].letter; + + makeTagEntry (&e); + + if (scope && Option.include.qualifiedTags) + { + vString *qualifiedName = vStringNew (); + vStringCopy (qualifiedName, scope); + vStringCatS (qualifiedName, "."); + vStringCat (qualifiedName, token->string); + e.name = vStringValue (qualifiedName); + makeTagEntry (&e); + vStringDelete (qualifiedName); + } +} + +static void parsePackage (tokenInfo *const token) +{ + tokenInfo *const name = newToken (); + + readToken (name); + if (isType (name, TOKEN_IDENTIFIER)) + { + makeTag (name, GOTAG_PACKAGE); + if (!scope && Option.include.qualifiedTags) + { + scope = vStringNew (); + vStringCopy (scope, name->string); + } + } + + deleteToken (name); +} + +static void parseFunctionOrMethod (tokenInfo *const token) +{ + // FunctionDecl = "func" identifier Signature [ Body ] . + // Body = Block. + // + // MethodDecl = "func" Receiver MethodName Signature [ Body ] . + // Receiver = "(" [ identifier ] [ "*" ] BaseTypeName ")" . + // BaseTypeName = identifier . + tokenInfo *const name = newToken (); + + // Skip over receiver. + readToken (name); + if (isType (name, TOKEN_OPEN_PAREN)) + skipToMatched (name); + + if (isType (name, TOKEN_IDENTIFIER)) + { + // Skip over parameters. + readToken (token); + skipToMatched (token); + + // Skip over result. + skipType (token); + + // Skip over function body. + if (isType (token, TOKEN_OPEN_CURLY)) + skipToMatched (token); + + makeTag (name, GOTAG_FUNCTION); + } + + deleteToken (name); +} + +static void parseConstTypeVar (tokenInfo *const token, goKind kind) +{ + // ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) . + // ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] . + // IdentifierList = identifier { "," identifier } . + // ExpressionList = Expression { "," Expression } . + // TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) . + // TypeSpec = identifier Type . + // VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) . + // VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) . + tokenInfo *const name = newToken (); + boolean usesParens = FALSE; + + readToken (name); + + if (isType (name, TOKEN_OPEN_PAREN)) + { + usesParens = TRUE; + readToken (name); + } + +again: + while (1) + { + if (isType (name, TOKEN_IDENTIFIER)) + { + makeTag (name, kind); + readToken (token); + } + if (!isType (token, TOKEN_COMMA)) + break; + readToken (name); + } + + skipType (token); + while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_PAREN) + && !isType (token, TOKEN_EOF)) + { + readToken (token); + skipToMatched (token); + } + + if (usesParens) + { + if (!isType (token, TOKEN_CLOSE_PAREN)) // we are at TOKEN_SEMICOLON + { + readToken (name); + if (!isType (name, TOKEN_CLOSE_PAREN) && !isType (name, TOKEN_EOF)) + goto again; + } + } + + deleteToken (name); +} + +static void parseGoFile (tokenInfo *const token) +{ + do + { + readToken (token); + + if (isType (token, TOKEN_KEYWORD)) + { + switch (token->keyword) + { + case KEYWORD_package: + parsePackage (token); + break; + case KEYWORD_func: + parseFunctionOrMethod (token); + break; + case KEYWORD_const: + parseConstTypeVar (token, GOTAG_CONST); + break; + case KEYWORD_type: + parseConstTypeVar (token, GOTAG_TYPE); + break; + case KEYWORD_var: + parseConstTypeVar (token, GOTAG_VAR); + break; + default: + break; + } + } + else if (isType (token, TOKEN_OPEN_PAREN) || isType (token, TOKEN_OPEN_CURLY) || + isType (token, TOKEN_OPEN_SQUARE)) + { + skipToMatched (token); + } + } while (token->type != TOKEN_EOF); +} + +static void findGoTags (void) +{ + tokenInfo *const token = newToken (); + + parseGoFile (token); + + deleteToken (token); + vStringDelete (scope); + scope = NULL; +} + +extern parserDefinition *GoParser (void) +{ + static const char *const extensions[] = { "go", NULL }; + parserDefinition *def = parserNew ("Go"); + def->kinds = GoKinds; + def->kindCount = KIND_COUNT (GoKinds); + def->extensions = extensions; + def->parser = findGoTags; + def->initialize = initialize; + return def; +}
Modified: tagmanager/ctags/makefile.win32 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -49,7 +49,7 @@ actionscript.o nsis.o objc.o \ haskell.o haxe.o html.o python.o lregex.o asciidoc.o rest.o sh.o ctags.o entry.o get.o keyword.o nestlevel.o \ options.o \ parse.o basic.o read.o sort.o strlist.o latex.o markdown.o matlab.o docbook.o tcl.o ruby.o rust.o asm.o sql.o txt2tags.o css.o \ -vstring.o r.o +vstring.o r.o go.o $(AR) rc $@ $^ $(RANLIB) $@
Modified: tagmanager/ctags/parsers.h 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -61,7 +61,8 @@ ObjcParser, \ AsciidocParser, \ AbaqusParser, \ - RustParser + RustParser, \ + GoParser
#endif /* _PARSERS_H */
Modified: tagmanager/src/tm_parser.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -68,6 +68,7 @@ typedef enum TM_PARSER_ASCIIDOC, TM_PARSER_ABAQUS, TM_PARSER_RUST, + TM_PARSER_GO, TM_PARSER_COUNT } TMParserType;
Modified: tests/ctags/Makefile.am 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -262,6 +262,7 @@ test_sources = \ strings.rb \ structure.f \ tabindent.py \ + test.go \ test.py \ test.vhd \ test_input.rs \
Modified: tests/ctags/test.go 47 lines changed, 47 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,47 @@ +package main + +import "fmt" + +type ( + T1 map[string]int + T2 <-chan float32 + T3 chan []string + T4 chan<- *[12]string + T5 interface { + Reader() + Writer() + foo() + } +) + +type T6 struct { + a, b, c, d int + e float32 + //ignored int +} + +const (A = iota;B;C; + D = iota << (1 + iota*2) + E + F=3.14*(1+2*3)/34e7;I=1) + +type (T7 func (a struct{_ int; _ float32}, b int) (int, map[string]int);T8 float32) + +var (a, b, c int +d T5 +e T4 +f interface{}) + +func f1() {};func f2() {};type/*no newline here*/T9 int/*var ignored int +const ignored int*/const (G=6); var g int + +func (t *T1) f3() (a, b int){ + return 1, 2 +}; var h int + +func (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f5(){};const H=1 + +func main() { + go func (){}() + fmt.Println("Hello, 世界") +}
Modified: tests/ctags/test.go.tags 34 lines changed, 34 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,34 @@ +# format=tagmanager +A�65536�0 +B�65536�0 +C�65536�0 +D�65536�0 +E�65536�0 +F�65536�0 +G�65536�0 +H�65536�0 +I�65536�0 +T1�4096�0 +T2�4096�0 +T3�4096�0 +T4�4096�0 +T5�4096�0 +T6�4096�0 +T7�4096�0 +T8�4096�0 +T9�4096�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 +g�16384�0 +h�16384�0 +main�16�0 +main�256�0
Modified: wscript 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -82,6 +82,7 @@ ctags_sources = set([ 'tagmanager/ctags/entry.c', 'tagmanager/ctags/fortran.c', 'tagmanager/ctags/get.c', + 'tagmanager/ctags/go.c', 'tagmanager/ctags/haskell.c', 'tagmanager/ctags/haxe.c', 'tagmanager/ctags/html.c',
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).