[Github-comments] [geany/geany] Improve handling of anonymous tags (PR #3059)

Thomas Martitz notifications at xxxxx
Mon Dec 20 11:29:16 UTC 2021


@kugel- requested changes on this pull request.



> @@ -818,6 +818,28 @@ void tm_parser_verify_type_mappings(void)
 }
 
 
+/* determine anonymous tags from tag names only when corresponding
+ * ctags information is not available */
+gboolean tm_parser_is_anon_name(TMParserType lang, gchar *name)
+{
+	guint i;
+	char dummy;
+
+	if (lang == TM_PARSER_C || lang == TM_PARSER_CPP)
+	{
+		return sscanf(name, "anon_%*[a-z]_%u%c", &i, &dummy) == 1 ||

Does sscanf really understand regexes? This is also new over the old code in `tm_tag_is_anon()`

> @@ -695,7 +695,7 @@ static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src,
 	for (i = 0; i < count && num < max_num; ++i)
 	{
 		if (tm_parser_langs_compatible(lang, (*tag)->lang) &&
-			!tm_tag_is_anon(*tag) &&
+			!((*tag)->flags & tm_tag_flag_anon_t) &&

IMO the this is not an improvement. Might keep `tm_tag_is_anon()` and reduce its implementation to just test the flag

> @@ -51,6 +51,3 @@
 main_diff = set(main_src_files) - set(main_dst_files)
 if main_diff:
     print('Files added to main: ' + str(main_diff))
-
-os.chdir(dstdir)
-os.system('patch -p1 <ctags_changes.patch')

yay

> @@ -120,7 +120,15 @@ static gboolean init_tag(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag
 	tag->name = g_strdup(tag_entry->name);
 	tag->type = type;
 	tag->local = tag_entry->isFileScope;
-	tag->pointerOrder = 0;	/* backward compatibility (use var_type instead) */
+	tag->flags = tm_tag_flag_none_t;
+	if (isTagExtraBitMarked(tag_entry, XTAG_ANONYMOUS))
+	{
+		tag->flags |= tm_tag_flag_anon_t;
+		/* Temporarily store kind letter for anon name generation to flags
+		 * as we don't have any other place where to store it. This will
+		 * be cleared later in rename_anon_tags() */
+		tag->flags |= (guint)kind_letter << 16;

Can't you just add a member to `TMTag` instead of this workaround?

> +						/* set the name of the original anon tag and pretend
+						 * it wasn't a anon tag */
+						tag->name = g_strdup(typedef_tag->name);
+						tag->flags &= ~tm_tag_flag_anon_t;
+						new_name = tag->name;
+						/* the typedef tag will be removed */
+						g_ptr_array_add(removed_typedefs, GUINT_TO_POINTER(j));
+					}
+				}
+			}
+
+			/* there's no typedef name for the anon tag so let's generate one  */
+			if (!new_name)
+			{
+				gchar buf[50];
+				guint anon_counter = GPOINTER_TO_UINT(g_hash_table_lookup(anon_counter_table, kind_name));

I think a hash_table is a overweight here. Since `kind` is in the range 0...255 a simple array would sufficie

guint anon_counter = anon_counter_table[kind]++;

Alternatively, you could use a hash table that uses `kind` as the key and not a more expensive hash of `kind_name`

> +				if (nested_scope_len <= scope_len)
+					break;
+
+				pos = strstr(nested_tag->scope, orig_name);
+				/* We found the parent name in the nested tag scope - replace it
+				 * with the new name. Note: anonymous tag names generated by
+				 * ctags are unique enough that we don't have to check for
+				 * scope separators here. */
+				if (pos)
+				{
+					gchar *str = g_malloc(nested_scope_len + 50);
+					guint prefix_len = pos - nested_tag->scope;
+
+					strncpy(str, nested_tag->scope, prefix_len);
+					strcpy(str + prefix_len, new_name);
+					strcpy(str + prefix_len + new_name_len, pos + orig_name_len);

Such string building could use `asprintf()` (not requesting a change here; also I see that GLIB only provides `g_vasprintf()` but not `g_asprintf()`, very strange)

> @@ -11,6 +9,8 @@ Named5
 Named6�2�Constants�0
 Named7�2�Constants�0
 a�4�Enum#1�0
+anon_enum_1�2�Constants�1
+anon_enum_2�2�Constants�1

I wonder if the new naming is really appreciated by Fortran users? I guess we'll see ;-)

> +{
+	guint i;
+	char dummy;
+
+	if (lang == TM_PARSER_C || lang == TM_PARSER_CPP)
+	{
+		return sscanf(name, "anon_%*[a-z]_%u%c", &i, &dummy) == 1 ||
+			sscanf(name, "__anon%u%c", &i, &dummy) == 1;
+	}
+	else if (lang == TM_PARSER_FORTRAN || lang == TM_PARSER_F77)
+	{
+		return sscanf(name, "Structure#%u%c", &i, &dummy) == 1 ||
+			sscanf(name, "Interface#%u%c", &i, &dummy) == 1 ||
+			sscanf(name, "Enum#%u%c", &i, &dummy) == 1;
+	}
+	return FALSE;

The unit test files for java script indicate that the naming is changed. Why is that not handled here (I know it also wasn't in the old `tm_tag_is_anon()` but I would like to understand why)?

-- 
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/3059#pullrequestreview-836269780
You are receiving this because you are subscribed to this thread.

Message ID: <geany/geany/pull/3059/review/836269780 at github.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.geany.org/pipermail/github-comments/attachments/20211220/8da2aa52/attachment-0001.htm>


More information about the Github-comments mailing list