Improve tag searching for "typedef struct {...}" cases

When resolving typedef, search for the subsequent type in the file where
the typedef was defined. For more info see the comment in the patch.
This commit is contained in:
Jiří Techet 2015-05-10 11:41:04 +02:00
parent 13755122f2
commit bf17c90bd6

View File

@ -762,10 +762,11 @@ GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type
static GPtrArray * static GPtrArray *
find_scope_members_tags (const GPtrArray * all, const char *scope, langType lang) find_scope_members_tags (const GPtrArray * all, const char *scope, langType lang,
TMSourceFile *tag_file)
{ {
GPtrArray *tags = g_ptr_array_new(); GPtrArray *tags = g_ptr_array_new();
TMSourceFile *last_file = NULL; TMSourceFile *last_file = tag_file;
guint i; guint i;
for (i = 0; i < all->len; ++i) for (i = 0; i < all->len; ++i)
@ -801,6 +802,7 @@ static GPtrArray *
find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array, find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
const char *name, langType lang) const char *name, langType lang)
{ {
TMSourceFile *typedef_file = NULL;
gboolean has_members = FALSE; gboolean has_members = FALSE;
GPtrArray *tags = NULL; GPtrArray *tags = NULL;
gchar *type_name; gchar *type_name;
@ -818,6 +820,7 @@ find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
* loop when typedefs create a cycle by adding some limits. */ * loop when typedefs create a cycle by adding some limits. */
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
{ {
guint j;
TMTag *tag = NULL; TMTag *tag = NULL;
GPtrArray *type_tags; GPtrArray *type_tags;
TMTagType types = (tm_tag_class_t | tm_tag_namespace_t | TMTagType types = (tm_tag_class_t | tm_tag_namespace_t |
@ -825,17 +828,25 @@ find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
tm_tag_union_t | tm_tag_enum_t); tm_tag_union_t | tm_tag_enum_t);
type_tags = g_ptr_array_new(); type_tags = g_ptr_array_new();
fill_find_tags_array(type_tags, tags_array, type_name, NULL, types, FALSE, lang); if (typedef_file)
if (type_tags)
{ {
guint j; /* If we have typedef_file, which is the file where the typedef was
for (j = 0; j < type_tags->len; j++) * defined, search in the file first. This helps for
{ * "typedef struct {...}" cases where the typedef resolves to
tag = TM_TAG(type_tags->pdata[j]); * anon_struct_* and searching for it in the whole workspace returns
/* prefer non-typedef tags because we can be sure they contain members */ * too many (wrong) results. */
if (tag->type != tm_tag_typedef_t) fill_find_tags_array(type_tags, typedef_file->tags_array, type_name,
break; NULL, types, FALSE, lang);
} }
if (type_tags->len == 0)
fill_find_tags_array(type_tags, tags_array, type_name, NULL, types, FALSE, lang);
for (j = 0; j < type_tags->len; j++)
{
tag = TM_TAG(type_tags->pdata[j]);
/* prefer non-typedef tags because we can be sure they contain members */
if (tag->type != tm_tag_typedef_t)
break;
} }
g_ptr_array_free(type_tags, TRUE); g_ptr_array_free(type_tags, TRUE);
@ -848,6 +859,7 @@ find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
{ {
g_free(type_name); g_free(type_name);
type_name = g_strdup(tag->var_type); type_name = g_strdup(tag->var_type);
typedef_file = tag->file;
continue; continue;
} }
else /* real type with members */ else /* real type with members */
@ -865,7 +877,7 @@ find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
} }
if (has_members) if (has_members)
tags = find_scope_members_tags(member_array, type_name, lang); tags = find_scope_members_tags(member_array, type_name, lang, typedef_file);
g_free(type_name); g_free(type_name);