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 *
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();
TMSourceFile *last_file = NULL;
TMSourceFile *last_file = tag_file;
guint i;
for (i = 0; i < all->len; ++i)
@ -801,6 +802,7 @@ static GPtrArray *
find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
const char *name, langType lang)
{
TMSourceFile *typedef_file = NULL;
gboolean has_members = FALSE;
GPtrArray *tags = NULL;
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. */
for (i = 0; i < 5; i++)
{
guint j;
TMTag *tag = NULL;
GPtrArray *type_tags;
TMTagType types = (tm_tag_class_t | tm_tag_namespace_t |
@ -825,10 +828,19 @@ find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
tm_tag_union_t | tm_tag_enum_t);
type_tags = g_ptr_array_new();
fill_find_tags_array(type_tags, tags_array, type_name, NULL, types, FALSE, lang);
if (type_tags)
if (typedef_file)
{
guint j;
/* If we have typedef_file, which is the file where the typedef was
* defined, search in the file first. This helps for
* "typedef struct {...}" cases where the typedef resolves to
* anon_struct_* and searching for it in the whole workspace returns
* too many (wrong) results. */
fill_find_tags_array(type_tags, typedef_file->tags_array, type_name,
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]);
@ -836,7 +848,6 @@ find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
if (tag->type != tm_tag_typedef_t)
break;
}
}
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);
type_name = g_strdup(tag->var_type);
typedef_file = tag->file;
continue;
}
else /* real type with members */
@ -865,7 +877,7 @@ find_scope_members (const GPtrArray *tags_array, GPtrArray *member_array,
}
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);