diff --git a/src/editor.c b/src/editor.c index e8ef888a3d..1762d2175a 100644 --- a/src/editor.c +++ b/src/editor.c @@ -711,6 +711,7 @@ static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize GPtrArray *tags; gboolean function = FALSE; gboolean member; + gboolean scope_sep_typed = FALSE; gboolean ret = FALSE; const gchar *current_scope; const gchar *context_sep = tm_tag_context_separator(ft->lang); @@ -729,10 +730,13 @@ static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize } /* make sure to keep in sync with similar checks below */ - if (typed == '.') - pos -= 1; - else if (match_last_chars(sci, pos, context_sep)) + if (match_last_chars(sci, pos, context_sep)) + { pos -= strlen(context_sep); + scope_sep_typed = TRUE; + } + else if (typed == '.') + pos -= 1; else if ((ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP) && match_last_chars(sci, pos, "->")) pos -= 2; @@ -777,7 +781,7 @@ static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize if (symbols_get_current_scope(editor->document, ¤t_scope) == -1) current_scope = ""; tags = tm_workspace_find_scope_members(editor->document->tm_file, name, function, - member, current_scope); + member, current_scope, scope_sep_typed); if (tags) { GPtrArray *filtered = g_ptr_array_new(); diff --git a/src/filetypes.c b/src/filetypes.c index 218d24383b..a9a74595b3 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -103,7 +103,7 @@ static gchar *filetype_make_title(const char *name, enum TitleType type) /* name argument (ie filetype name) must not be translated as it is used for * filetype lookup. Use filetypes_get_display_name() instead.*/ -static void ft_init(filetype_id ft_id, int lang, const char *name, +static void ft_init(filetype_id ft_id, TMParserType lang, const char *name, const char *title_name, enum TitleType title_type, GeanyFiletypeGroupID group_id) { @@ -202,7 +202,7 @@ static GeanyFiletype *filetype_new(void) GeanyFiletype *ft = g_new0(GeanyFiletype, 1); ft->group = GEANY_FILETYPE_GROUP_NONE; - ft->lang = -2; /* assume no tagmanager parser */ + ft->lang = TM_PARSER_NONE; /* assume no tagmanager parser */ /* pattern must not be null */ ft->pattern = g_new0(gchar*, 1); ft->indent_width = -1; @@ -950,7 +950,7 @@ static void load_settings(guint ft_id, GKeyFile *config, GKeyFile *configh) if (result != NULL) { ft->lang = tm_source_file_get_named_lang(result); - if (ft->lang < 0) + if (ft->lang == TM_PARSER_NONE) geany_debug("Cannot find tags parser '%s' for custom filetype '%s'.", result, ft->name); g_free(result); } @@ -1240,7 +1240,7 @@ gboolean filetype_has_tags(GeanyFiletype *ft) { g_return_val_if_fail(ft != NULL, FALSE); - return ft->lang >= 0; + return ft->lang != TM_PARSER_NONE; } diff --git a/src/filetypes.h b/src/filetypes.h index 9f5998333b..19c7e9adb9 100644 --- a/src/filetypes.h +++ b/src/filetypes.h @@ -24,7 +24,7 @@ #define GEANY_FILETYPES_H 1 #include "geany.h" /* for GEANY() macro */ -#include "tm_source_file.h" /* for langType */ +#include "tm_parser.h" /* for TMParserType */ #include "gtkcompat.h" /* Needed by ScintillaWidget.h */ #include "Scintilla.h" /* Needed by ScintillaWidget.h */ @@ -134,9 +134,9 @@ GeanyFiletypeGroupID; typedef struct GeanyFiletype { GeanyFiletypeID id; /**< Index in @ref filetypes. */ - /** Represents the langType of tagmanager (see the table - * in tagmanager/parsers.h), -1 represents all, -2 none. */ - langType lang; + /* Represents the TMParserType of tagmanager (see the table + * in tagmanager/src/tm_parser.h). */ + TMParserType lang; /** Untranslated short name, such as "C", "None". * Must not be translated as it's used for hash table lookups - use * filetypes_get_display_name() instead. */ diff --git a/src/plugindata.h b/src/plugindata.h index 63dd373c89..8e84d6a3cf 100644 --- a/src/plugindata.h +++ b/src/plugindata.h @@ -58,7 +58,7 @@ G_BEGIN_DECLS * @warning You should not test for values below 200 as previously * @c GEANY_API_VERSION was defined as an enum value, not a macro. */ -#define GEANY_API_VERSION 227 +#define GEANY_API_VERSION 228 /* hack to have a different ABI when built with GTK3 because loading GTK2-linked plugins * with GTK3-linked Geany leads to crash */ diff --git a/src/symbols.c b/src/symbols.c index db37514515..c3aeffbf8e 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -272,13 +272,13 @@ static void html_tags_loaded(void) } -GString *symbols_find_typenames_as_string(gint lang, gboolean global) +GString *symbols_find_typenames_as_string(TMParserType lang, gboolean global) { guint j; TMTag *tag; GString *s = NULL; GPtrArray *typedefs; - gint tag_lang; + TMParserType tag_lang; if (global) typedefs = app->tm_workspace->global_typename_array; @@ -287,21 +287,21 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global) if ((typedefs) && (typedefs->len > 0)) { + const gchar *last_name = ""; + s = g_string_sized_new(typedefs->len * 10); for (j = 0; j < typedefs->len; ++j) { tag = TM_TAG(typedefs->pdata[j]); tag_lang = tag->lang; - /* the check for tag_lang == lang is necessary to avoid wrong type colouring of - * e.g. PHP classes in C++ files - * lang = -2 disables the check */ - if (tag->name && (tag_lang == lang || lang == -2 || - (lang == TM_PARSER_CPP && tag_lang == TM_PARSER_C))) + if (tag->name && tm_tag_langs_compatible(lang, tag_lang) && + strcmp(tag->name, last_name) != 0) { if (j != 0) g_string_append_c(s, ' '); g_string_append(s, tag->name); + last_name = tag->name; } } } diff --git a/src/symbols.h b/src/symbols.h index 1afbd29e95..8a325aaa0a 100644 --- a/src/symbols.h +++ b/src/symbols.h @@ -50,9 +50,7 @@ void symbols_reload_config_files(void); void symbols_global_tags_loaded(guint file_type_idx); -GString *symbols_find_typenames_as_string(gint lang, gboolean global); - -const GList *symbols_get_tag_list(GeanyDocument *doc, guint tag_types); +GString *symbols_find_typenames_as_string(TMParserType lang, gboolean global); const gchar **symbols_get_html_entities(void); diff --git a/tagmanager/src/Makefile.am b/tagmanager/src/Makefile.am index 65ee42c5ab..ba05ca0097 100644 --- a/tagmanager/src/Makefile.am +++ b/tagmanager/src/Makefile.am @@ -18,7 +18,8 @@ tagmanager_include_HEADERS = \ tm_source_file.h \ tm_tag.h \ tm_tagmanager.h \ - tm_workspace.h + tm_workspace.h \ + tm_parser.h libtagmanager_la_SOURCES =\ diff --git a/tagmanager/src/tm_parser.h b/tagmanager/src/tm_parser.h index 2e0edaceb8..9b3c237420 100644 --- a/tagmanager/src/tm_parser.h +++ b/tagmanager/src/tm_parser.h @@ -10,18 +10,15 @@ #ifndef TM_PARSER_H #define TM_PARSER_H -#ifndef LIBCTAGS_DEFINED -/* from ctags/parse.h */ -# define LANG_AUTO (-1) -# define LANG_IGNORE (-2) -#endif +typedef gint TMParserType; +#ifdef GEANY_PRIVATE + /* keep in sync with ctags/parsers.h */ -typedef enum +enum { - TM_PARSER_NONE = LANG_IGNORE, - TM_PARSER_AUTO = LANG_AUTO, + TM_PARSER_NONE = -2, /* keep in sync with ctags LANG_IGNORE */ TM_PARSER_C = 0, TM_PARSER_CPP, TM_PARSER_JAVA, @@ -74,7 +71,8 @@ typedef enum TM_PARSER_ZEPHIR, TM_PARSER_POWERSHELL, TM_PARSER_COUNT -} TMParserType; +}; +#endif /* GEANY_PRIVATE */ #endif /* TM_PARSER_H */ diff --git a/tagmanager/src/tm_source_file.c b/tagmanager/src/tm_source_file.c index af3d6499c5..dcb2bee674 100644 --- a/tagmanager/src/tm_source_file.c +++ b/tagmanager/src/tm_source_file.c @@ -34,6 +34,7 @@ #define LIBCTAGS_DEFINED #include "tm_source_file.h" #include "tm_tag.h" +#include "tm_parser.h" typedef struct { @@ -193,7 +194,7 @@ static gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_ } if (name == NULL) - source_file->lang = LANG_AUTO; + source_file->lang = TM_PARSER_NONE; else source_file->lang = getNamedLanguage(name); @@ -203,7 +204,7 @@ static gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_ /** Initializes a TMSourceFile structure and returns a pointer to it. The * TMSourceFile has to be added to TMWorkspace to start its parsing. * @param file_name The file name. - * @param name Name of the used programming language, NULL for autodetection. + * @param name Name of the used programming language, NULL to disable parsing. * @return The created unparsed TMSourceFile object. * */ GEANY_API_SYMBOL @@ -297,7 +298,7 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize return FALSE; } - if (source_file->lang == LANG_IGNORE) + if (source_file->lang == TM_PARSER_NONE) { tm_tags_array_free(source_file->tags_array, FALSE); return FALSE; @@ -342,15 +343,7 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize TagEntrySetArglistFunction = tm_source_file_set_tag_arglist; } current_source_file = source_file; - if (LANG_AUTO == source_file->lang) - source_file->lang = getFileLanguage (file_name); - if (source_file->lang == LANG_IGNORE) - { -#ifdef TM_DEBUG - g_warning("ignoring %s (unknown language)\n", file_name); -#endif - } - else if (! LanguageTable [source_file->lang]->enabled) + if (! LanguageTable [source_file->lang]->enabled) { #ifdef TM_DEBUG g_warning("ignoring %s (language disabled)\n", file_name); @@ -406,7 +399,7 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize @param lang The language index. @return The language name, or NULL. */ -const gchar *tm_source_file_get_lang_name(gint lang) +const gchar *tm_source_file_get_lang_name(TMParserType lang) { if (NULL == LanguageTable) { @@ -422,9 +415,9 @@ const gchar *tm_source_file_get_lang_name(gint lang) /* Gets the language index for \a name. @param name The language name. - @return The language index, or -2. + @return The language index, or TM_PARSER_NONE. */ -gint tm_source_file_get_named_lang(const gchar *name) +TMParserType tm_source_file_get_named_lang(const gchar *name) { if (NULL == LanguageTable) { diff --git a/tagmanager/src/tm_source_file.h b/tagmanager/src/tm_source_file.h index f2bdf4b1c9..2ecd9d7bc2 100644 --- a/tagmanager/src/tm_source_file.h +++ b/tagmanager/src/tm_source_file.h @@ -14,14 +14,12 @@ #include #include +#include "tm_parser.h" + #ifndef LIBCTAGS_DEFINED -typedef int langType; typedef void tagEntryInfo; #endif -#if !defined(tagEntryInfo) -#endif - #ifdef __cplusplus extern "C" { @@ -39,7 +37,7 @@ extern "C" */ typedef struct { - langType lang; /**< Programming language used */ + TMParserType lang; /* Programming language used */ char *file_name; /**< Full file name (inc. path) */ char *short_name; /**< Just the name of the file (without the path) */ GPtrArray *tags_array; /**< Sorted tag array obtained by parsing the object */ @@ -56,9 +54,9 @@ gchar *tm_get_real_path(const gchar *file_name); #ifdef GEANY_PRIVATE -const gchar *tm_source_file_get_lang_name(gint lang); +const gchar *tm_source_file_get_lang_name(TMParserType lang); -gint tm_source_file_get_named_lang(const gchar *name); +TMParserType tm_source_file_get_named_lang(const gchar *name); gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize buf_size, gboolean use_buffer); diff --git a/tagmanager/src/tm_tag.c b/tagmanager/src/tm_tag.c index ff559ee1e5..dbab8d5a74 100644 --- a/tagmanager/src/tm_tag.c +++ b/tagmanager/src/tm_tag.c @@ -562,9 +562,9 @@ static gboolean tm_tag_init_from_file_ctags(TMTag *tag, TMSourceFile *file, FILE /* Same as tm_tag_new() except that the tag attributes are read from file. - @param mode langType to use for the tag. + @param mode TMParserType to use for the tag. */ -TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, gint mode, TMFileFormat format) +TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, TMParserType mode, TMFileFormat format) { TMTag *tag; gboolean result = FALSE; @@ -1182,7 +1182,7 @@ tm_get_current_tag (GPtrArray * file_tags, const gulong line, const TMTagType ta return matching_tag; } -const gchar *tm_tag_context_separator(langType lang) +const gchar *tm_tag_context_separator(TMParserType lang) { switch (lang) { @@ -1226,6 +1226,22 @@ gboolean tm_tag_is_anon(const TMTag *tag) } +gboolean tm_tag_langs_compatible(TMParserType lang, TMParserType other) +{ + if (lang == TM_PARSER_NONE || other == TM_PARSER_NONE) + return FALSE; + if (lang == other) + return TRUE; + /* Accept CPP tags for C lang and vice versa */ + else if (lang == TM_PARSER_C && other == TM_PARSER_CPP) + return TRUE; + else if (lang == TM_PARSER_CPP && other == TM_PARSER_C) + return TRUE; + + return FALSE; +} + + #ifdef TM_DEBUG /* various debugging functions */ /* diff --git a/tagmanager/src/tm_tag.h b/tagmanager/src/tm_tag.h index 9441392d3d..ac7886ec49 100644 --- a/tagmanager/src/tm_tag.h +++ b/tagmanager/src/tm_tag.h @@ -137,7 +137,7 @@ typedef struct _TMTag char *var_type; /**< Variable type (maps to struct for typedefs) */ char access; /**< Access type (public/protected/private/etc.) */ char impl; /**< Implementation (e.g. virtual) */ - langType lang; /**< Programming language of the file */ + TMParserType lang; /* Programming language of the file */ } TMTag; @@ -160,7 +160,7 @@ GType tm_tag_get_type(void) G_GNUC_CONST; TMTag *tm_tag_new(TMSourceFile *file, const tagEntryInfo *tag_entry); -TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, gint mode, TMFileFormat format); +TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, TMParserType mode, TMFileFormat format); gboolean tm_tag_write(TMTag *tag, FILE *file, guint attrs); @@ -191,10 +191,12 @@ TMTag *tm_tag_ref(TMTag *tag); gboolean tm_tags_equal(const TMTag *a, const TMTag *b); -const gchar *tm_tag_context_separator(langType lang); +const gchar *tm_tag_context_separator(TMParserType lang); gboolean tm_tag_is_anon(const TMTag *tag); +gboolean tm_tag_langs_compatible(TMParserType lang, TMParserType other); + #ifdef TM_DEBUG /* various debugging functions */ const char *tm_tag_type_name(const TMTag *tag); diff --git a/tagmanager/src/tm_workspace.c b/tagmanager/src/tm_workspace.c index ef582a84a0..8e51f84677 100644 --- a/tagmanager/src/tm_workspace.c +++ b/tagmanager/src/tm_workspace.c @@ -193,8 +193,7 @@ void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file) you're editing. It's useful for a "real-time" updating of the tags. The tags array and the tags themselves are destroyed and re-created, hence any other tag arrays pointing to these tags should be rebuilt as well. All sorting - information is also lost. The language parameter is automatically detected - the first time the file is parsed if it is set to LANG_AUTO. + information is also lost. @param source_file The source file to update with a buffer. @param text_buf A text buffer. The user should take care of allocate and free it after the use here. @@ -338,7 +337,7 @@ void tm_workspace_remove_source_files(GPtrArray *source_files) @return TRUE on success, FALSE on failure. @see tm_workspace_create_global_tags() */ -gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode) +gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode) { guchar buf[BUFSIZ]; FILE *fp; @@ -503,7 +502,7 @@ static gchar *create_temp_file(const gchar *tpl) @return TRUE on success, FALSE on failure. */ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, - int includes_count, const char *tags_file, int lang) + int includes_count, const char *tags_file, TMParserType lang) { #ifdef HAVE_GLOB_H glob_t globbuf; @@ -686,22 +685,8 @@ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **i } -static gboolean langs_compatible(langType lang, langType other) -{ - if (lang == other || lang == -1 || other == -1) - return TRUE; - /* Accept CPP tags for C lang and vice versa */ - else if (lang == TM_PARSER_C && other == TM_PARSER_CPP) - return TRUE; - else if (lang == TM_PARSER_CPP && other == TM_PARSER_C) - return TRUE; - - return FALSE; -} - - static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, - const char *name, const char *scope, TMTagType type, langType lang) + const char *name, const char *scope, TMTagType type, TMParserType lang) { TMTag **tag; guint i, num; @@ -713,7 +698,7 @@ static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, for (i = 0; i < num; ++i) { if ((type & (*tag)->type) && - langs_compatible(lang, (*tag)->lang) && + tm_tag_langs_compatible(lang, (*tag)->lang) && (!scope || g_strcmp0((*tag)->scope, scope) == 0)) { g_ptr_array_add(dst, *tag); @@ -733,7 +718,7 @@ static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, @return Array of matching tags. */ GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type, - TMTagAttrType *attrs, langType lang) + TMTagAttrType *attrs, TMParserType lang) { GPtrArray *tags = g_ptr_array_new(); @@ -748,7 +733,7 @@ GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src, - const char *name, langType lang, guint max_num) + const char *name, TMParserType lang, guint max_num) { TMTag **tag, *last = NULL; guint i, count, num; @@ -760,7 +745,7 @@ static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src, tag = tm_tags_find(src, name, TRUE, &count); for (i = 0; i < count && num < max_num; ++i) { - if (langs_compatible(lang, (*tag)->lang) && + if (tm_tag_langs_compatible(lang, (*tag)->lang) && !tm_tag_is_anon(*tag) && (!last || g_strcmp0(last->name, (*tag)->name) != 0)) { @@ -781,7 +766,7 @@ static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src, @param max_num The maximum number of tags to return. @return Array of matching tags sorted by their name. */ -GPtrArray *tm_workspace_find_prefix(const char *prefix, langType lang, guint max_num) +GPtrArray *tm_workspace_find_prefix(const char *prefix, TMParserType lang, guint max_num) { TMTagAttrType attrs[] = { tm_tag_attr_name_t, 0 }; GPtrArray *tags = g_ptr_array_new(); @@ -826,7 +811,7 @@ find_scope_members_tags (const GPtrArray *all, TMTag *type_tag, gboolean namespa if (tag && (tag->type & member_types) && tag->scope && tag->scope[0] != '\0' && - langs_compatible(tag->lang, type_tag->lang) && + tm_tag_langs_compatible(tag->lang, type_tag->lang) && strcmp(scope, tag->scope) == 0 && (!namespace || !tm_tag_is_anon(tag))) { @@ -846,7 +831,7 @@ find_scope_members_tags (const GPtrArray *all, TMTag *type_tag, gboolean namespa } -static gchar *strip_type(const gchar *scoped_name, langType lang) +static gchar *strip_type(const gchar *scoped_name, TMParserType lang) { if (scoped_name != NULL) { @@ -868,7 +853,7 @@ static gchar *strip_type(const gchar *scoped_name, langType lang) /* Gets all members of the type with the given name; search them inside tags_array */ static GPtrArray * find_scope_members (const GPtrArray *tags_array, const gchar *name, TMSourceFile *file, - langType lang, gboolean namespace) + TMParserType lang, gboolean namespace) { GPtrArray *res = NULL; gchar *type_name; @@ -945,7 +930,7 @@ find_scope_members (const GPtrArray *tags_array, const gchar *name, TMSourceFile /* Checks whether a member tag is directly accessible from method with method_scope */ static gboolean member_at_method_scope(const GPtrArray *tags, const gchar *method_scope, TMTag *member_tag, - langType lang) + TMParserType lang) { const gchar *sep = tm_tag_context_separator(lang); gboolean ret = FALSE; @@ -995,7 +980,7 @@ static gboolean member_at_method_scope(const GPtrArray *tags, const gchar *metho /* For an array of variable/type tags, find members inside the types */ static GPtrArray * -find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, langType lang, +find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, TMParserType lang, gboolean member, const gchar *current_scope) { GPtrArray *member_tags = NULL; @@ -1039,19 +1024,36 @@ find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, l } +static GPtrArray *find_namespace_members_all(const GPtrArray *tags, const GPtrArray *searched_array, TMParserType lang) +{ + GPtrArray *member_tags = NULL; + guint i; + + for (i = 0; i < tags->len && !member_tags; i++) + { + TMTag *tag = TM_TAG(tags->pdata[i]); + + member_tags = find_scope_members_tags(searched_array, tag, TRUE); + } + + return member_tags; +} + + /* Returns all member tags of a struct/union/class if the provided name is a variable of such a type or the name of the type. - @param source_file TMSourceFile of the edited source file or NULL if not available + @param source_file TMSourceFile of the edited source file @param name Name of the variable/type whose members are searched @param function TRUE if the name is a name of a function @param member TRUE if invoked on class/struct member (e.g. after the last dot in foo.bar.) @param current_scope The current scope in the editor + @param search_namespace Whether to search the contents of namespace (e.g. after MyNamespace::) @return A GPtrArray of TMTag pointers to struct/union/class members or NULL when not found */ GPtrArray * tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, - gboolean function, gboolean member, const gchar *current_scope) + gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace) { - langType lang = source_file ? source_file->lang : -1; + TMParserType lang = source_file->lang; GPtrArray *tags, *member_tags = NULL; TMTagType function_types = tm_tag_function_t | tm_tag_method_t | tm_tag_macro_with_arg_t | tm_tag_prototype_t; @@ -1059,26 +1061,40 @@ tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, ~(function_types | tm_tag_enumerator_t | tm_tag_namespace_t | tm_tag_package_t); TMTagAttrType sort_attr[] = {tm_tag_attr_name_t, 0}; - if (function) - tag_type = function_types; + if (search_namespace) + { + tags = tm_workspace_find(name, NULL, tm_tag_namespace_t, NULL, lang); - /* tags corresponding to the variable/type name */ - tags = tm_workspace_find(name, NULL, tag_type, NULL, lang); + member_tags = find_namespace_members_all(tags, theWorkspace->tags_array, lang); + if (!member_tags) + member_tags = find_namespace_members_all(tags, theWorkspace->global_tags, lang); + + g_ptr_array_free(tags, TRUE); + } - /* Start searching inside the source file, continue with workspace tags and - * end with global tags. This way we find the "closest" tag to the current - * file in case there are more of them. */ - if (source_file) - member_tags = find_scope_members_all(tags, source_file->tags_array, - lang, member, current_scope); - if (!member_tags) - member_tags = find_scope_members_all(tags, theWorkspace->tags_array, lang, - member, current_scope); if (!member_tags) - member_tags = find_scope_members_all(tags, theWorkspace->global_tags, lang, - member, current_scope); + { + if (function) + tag_type = function_types; + + /* tags corresponding to the variable/type name */ + tags = tm_workspace_find(name, NULL, tag_type, NULL, lang); + + /* Start searching inside the source file, continue with workspace tags and + * end with global tags. This way we find the "closest" tag to the current + * file in case there are more of them. */ + if (source_file) + member_tags = find_scope_members_all(tags, source_file->tags_array, + lang, member, current_scope); + if (!member_tags) + member_tags = find_scope_members_all(tags, theWorkspace->tags_array, lang, + member, current_scope); + if (!member_tags) + member_tags = find_scope_members_all(tags, theWorkspace->global_tags, lang, + member, current_scope); - g_ptr_array_free(tags, TRUE); + g_ptr_array_free(tags, TRUE); + } tm_tags_dedup(member_tags, sort_attr, FALSE); diff --git a/tagmanager/src/tm_workspace.h b/tagmanager/src/tm_workspace.h index 50821224b9..173766b97a 100644 --- a/tagmanager/src/tm_workspace.h +++ b/tagmanager/src/tm_workspace.h @@ -50,18 +50,18 @@ void tm_workspace_remove_source_files(GPtrArray *source_files); const TMWorkspace *tm_get_workspace(void); -gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode); +gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode); gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, - int includes_count, const char *tags_file, int lang); + int includes_count, const char *tags_file, TMParserType lang); GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type, - TMTagAttrType *attrs, langType lang); + TMTagAttrType *attrs, TMParserType lang); -GPtrArray *tm_workspace_find_prefix(const char *prefix, langType lang, guint max_num); +GPtrArray *tm_workspace_find_prefix(const char *prefix, TMParserType lang, guint max_num); GPtrArray *tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, - gboolean function, gboolean member, const gchar *current_scope); + gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace); void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file); diff --git a/wscript b/wscript index d7cabeb721..ac6e49dd23 100644 --- a/wscript +++ b/wscript @@ -671,7 +671,8 @@ def build(bld): tagmanager/src/tm_source_file.h tagmanager/src/tm_tag.h tagmanager/src/tm_tagmanager.h - tagmanager/src/tm_workspace.h ''') + tagmanager/src/tm_workspace.h + tagmanager/src/tm_parser.h ''') # Docs base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}' ext = '.txt' if is_win32 else ''