[geany/geany] b6b930: Get scope members only from corresponding tag arrays

Jiří Techet git-noreply at xxxxx
Thu Feb 11 14:35:50 UTC 2016


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Sun, 10 Jan 2016 11:31:02 UTC
Commit:      b6b93036f682bbc73399b3372168849d0b31fc4f
             https://github.com/geany/geany/commit/b6b93036f682bbc73399b3372168849d0b31fc4f

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).


More information about the Commits mailing list