Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Sun, 10 Jan 2016 11:31:02 UTC Commit: b6b93036f682bbc73399b3372168849d0b31fc4f https://github.com/geany/geany/commit/b6b93036f682bbc73399b3372168849d0b31fc...
Log Message: ----------- Get scope members only from corresponding tag arrays
At the moment it can happen that even though a member is found in the currently edited file, the search at the end of the function finds the type inside another file. This typically happens for anonymous structs so e.g. for anon_struct_0{...} from the current file we get members from anon_struct_0{...} from all open documents plus gloabl tags.
Search in an increasing "circle" - start with current file only (trying all possible types of the variable), continue with workspace array and finally, if not found, search in the global tags.
Modified Paths: -------------- src/editor.c tagmanager/src/tm_workspace.c tagmanager/src/tm_workspace.h
Modified: src/editor.c 31 lines changed, 7 insertions(+), 24 deletions(-) =================================================================== @@ -703,10 +703,8 @@ static void autocomplete_scope(GeanyEditor *editor) gint pos = sci_get_current_position(editor->sci); gchar typed = sci_get_char_at(sci, pos - 1); gchar *name; - GPtrArray *tags; - const TMTag *tag; GeanyFiletype *ft = editor->document->file_type; - guint i; + GPtrArray *tags;
if (ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP) { @@ -727,29 +725,14 @@ static void autocomplete_scope(GeanyEditor *editor) if (!name) return;
- tags = tm_workspace_find(name, NULL, tm_tag_max_t, NULL, FALSE, ft->lang); - g_free(name); - - foreach_ptr_array(tag, i, tags) + tags = tm_workspace_find_scope_members(editor->document->tm_file, name); + if (tags) { - if (tag->var_type) - { - TMSourceFile *sf = editor->document->tm_file; - GPtrArray *member_tags; - gboolean found; - - member_tags = tm_workspace_find_scope_members(sf ? sf->tags_array : NULL, - tag->var_type, - sf ? sf->lang : -1); - found = member_tags && member_tags->len > 0; - if (found) - show_tags_list(editor, member_tags, 0); - g_ptr_array_free(member_tags, TRUE); - if (found) - break; - } + show_tags_list(editor, tags, 0); + g_ptr_array_free(tags, TRUE); } - g_ptr_array_free(tags, TRUE); + + g_free(name); }
Modified: tagmanager/src/tm_workspace.c 105 lines changed, 72 insertions(+), 33 deletions(-) =================================================================== @@ -871,15 +871,12 @@ find_scope_members_tags (const GPtrArray * all, GPtrArray * tags, }
-/* Returns all matching members tags found in given struct/union/class name. - @param file_tags A GPtrArray of edited file TMTag pointers (for search speedup, can be NULL). - @param name Name of the struct/union/class. - @return A GPtrArray of TMTag pointers to struct/union/class members */ -GPtrArray * -tm_workspace_find_scope_members (const GPtrArray * file_tags, const char *name, langType lang) +static GPtrArray * +find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array, + const char *name, langType lang) { gboolean has_members = FALSE; - GPtrArray *tags; + GPtrArray *tags = NULL; gchar *type_name; guint i;
@@ -895,32 +892,17 @@ tm_workspace_find_scope_members (const GPtrArray * file_tags, const char *name, * loop when typedefs create a cycle by adding some limits. */ for (i = 0; i < 5; i++) { - guint j; TMTag *tag = NULL; GPtrArray *type_tags; TMTagType types = (tm_tag_class_t | tm_tag_namespace_t | tm_tag_struct_t | tm_tag_typedef_t | tm_tag_union_t | tm_tag_enum_t);
- /* try to get the type from file_tags first */ type_tags = g_ptr_array_new(); - if (file_tags) - fill_find_tags_array(type_tags, file_tags, type_name, NULL, types, FALSE, lang); - - /* file not specified or type definition not in the file */ - if (type_tags->len == 0) - { - TMTagAttrType attrs[] = { - tm_tag_attr_name_t, tm_tag_attr_type_t, - tm_tag_attr_none_t - }; - - g_ptr_array_free(type_tags, TRUE); - type_tags = tm_workspace_find(type_name, NULL, types, attrs, FALSE, lang); - } - + fill_find_tags_array(type_tags, tags_array, type_name, NULL, types, FALSE, lang); if (type_tags) { + guint j; for (j = 0; j < type_tags->len; j++) { tag = TM_TAG(type_tags->pdata[j]); @@ -959,17 +941,15 @@ tm_workspace_find_scope_members (const GPtrArray * file_tags, const char *name, } }
- tags = g_ptr_array_new(); - if (has_members) { - GPtrArray *extracted; - - /* Now get the tags from tags_array and global_tags corresponding to type_name */ - if (theWorkspace->member_array) - find_scope_members_tags(theWorkspace->member_array, tags, type_name, lang); - if (theWorkspace->global_member_array) - find_scope_members_tags(theWorkspace->global_member_array, tags, type_name, lang); + tags = g_ptr_array_new(); + find_scope_members_tags(member_array, tags, type_name, lang); + if (tags->len == 0) + { + g_ptr_array_free(tags, TRUE); + tags = NULL; + } }
g_free(type_name); @@ -978,6 +958,65 @@ tm_workspace_find_scope_members (const GPtrArray * file_tags, const char *name, }
+static GPtrArray * +find_scope_members_all(const GPtrArray *var_array, const GPtrArray *searched_array, + GPtrArray *member_array, langType lang) +{ + GPtrArray *member_tags = NULL; + guint i; + + /* there may be several variables with the same name - try each of them until + * we find something */ + for (i = 0; i < var_array->len; i++) + { + TMTag *tag = TM_TAG(var_array->pdata[i]); + + if (tag->var_type) + { + member_tags = find_scope_members(searched_array, member_array, + tag->var_type, lang); + if (member_tags) + break; + } + } + + return member_tags; +} + + +/* Returns all matching members tags found in given struct/union/class name. + @param source_file TMSourceFile of the edited source file or NULL if not available + @param name Name of the variable whose members are searched + @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) +{ + langType lang = source_file ? source_file->lang : -1; + GPtrArray *tags, *member_tags = NULL; + + tags = tm_workspace_find(name, NULL, tm_tag_max_t, NULL, FALSE, lang); + + if (source_file) + { + GPtrArray *file_members = tm_tags_extract(source_file->tags_array, TM_MEMBER_TYPE_MASK); + + member_tags = find_scope_members_all(tags, source_file->tags_array, + file_members, lang); + g_ptr_array_free(file_members, TRUE); + } + if (!member_tags) + member_tags = find_scope_members_all(tags, theWorkspace->tags_array, + theWorkspace->member_array, lang); + if (!member_tags) + member_tags = find_scope_members_all(tags, theWorkspace->global_tags, + theWorkspace->global_member_array, lang); + + g_ptr_array_free(tags, TRUE); + + return member_tags; +} + + #ifdef TM_DEBUG
/* Dumps the workspace tree - useful for debugging */
Modified: tagmanager/src/tm_workspace.h 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -60,8 +60,8 @@ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **i GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type, TMTagAttrType *attrs, gboolean partial, langType lang);
-GPtrArray *tm_workspace_find_scope_members(const GPtrArray *file_tags, - const char *scope_name, langType lang); +GPtrArray *tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name); +
void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file);
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).