[geany/geany] 748137: C, C++, C#, D: Improve return type and var type recognition

Colomban Wendling git-noreply at xxxxx
Thu Feb 11 14:36:06 UTC 2016


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Tue, 26 Jan 2016 15:18:11 UTC
Commit:      748137bd1dfa648948d9d127aa3e27b6857db764
             https://github.com/geany/geany/commit/748137bd1dfa648948d9d127aa3e27b6857db764

Log Message:
-----------
C, C++, C#, D: Improve return type and var type recognition

This is far from perfect and contains a lot of guessing.  It showed
good results based on our tests cases, fixing several issues and not
introducing any more issues (admittedly, after working around a subtle
one regarding D static ifs).

Closes #845.


Modified Paths:
--------------
    tagmanager/ctags/c.c
    tests/ctags/Makefile.am
    tests/ctags/bit_field.c.tags
    tests/ctags/bug1799340.cpp.tags
    tests/ctags/bug1907083.cpp.tags
    tests/ctags/bug1924919.cpp.tags
    tests/ctags/c-digraphs.c.tags
    tests/ctags/c-trigraphs.c.tags
    tests/ctags/indexer.cs.tags
    tests/ctags/interface_indexers.cs.tags
    tests/ctags/keyword_const.cs.tags
    tests/ctags/keyword_virtual.cs.tags
    tests/ctags/keyword_volatile.cs.tags
    tests/ctags/simple.d.tags
    tests/ctags/var-and-return-type.cpp
    tests/ctags/var-and-return-type.cpp.tags

Modified: tagmanager/ctags/c.c
70 lines changed, 61 insertions(+), 9 deletions(-)
===================================================================
@@ -518,7 +518,8 @@ static const keywordDesc KeywordTable [] = {
 */
 static void createTags (const unsigned int nestLevel, statementInfo *const parent);
 static void copyToken (tokenInfo *const dest, const tokenInfo *const src);
-static const char *getVarType (const statementInfo *const st);
+static const char *getVarType (const statementInfo *const st,
+							   const tokenInfo *const token);
 
 /*
 *   FUNCTION DEFINITIONS
@@ -1186,6 +1187,7 @@ static const char* accessField (const statementInfo *const st)
 }
 
 static void addOtherFields (tagEntryInfo* const tag, const tagType type,
+							const tokenInfo *const nameToken,
 							const statementInfo *const st, vString *const scope)
 {
 	/*  For selected tag types, append an extension flag designating the
@@ -1254,40 +1256,90 @@ static void addOtherFields (tagEntryInfo* const tag, const tagType type,
 		if (((TOKEN_NAME == st->firstToken->type) || isDataTypeKeyword(st->firstToken))
 			&& (0 != strcmp(vStringValue(st->firstToken->name), tag->name)))
 		{
-			tag->extensionFields.varType = getVarType(st);
+			tag->extensionFields.varType = getVarType(st, nameToken);
 		}
 	}
 }
 
-static const char *getVarType (const statementInfo *const st)
+static const char *getVarType (const statementInfo *const st,
+							   const tokenInfo *const nameToken)
 {
 	static vString *vt = NULL;
 	unsigned int i;
+	unsigned int end = st->tokenIndex;
+	boolean seenType = FALSE;
 
-	if (! st->gotArgs)
-		return vStringValue(st->firstToken->name);	/* ignore non-functions */
+	switch (st->declaration) {
+		case DECL_BASE:
+		case DECL_FUNCTION:
+		case DECL_FUNCTION_TEMPLATE:
+			break;
+		default:
+			return vStringValue(st->firstToken->name);
+	}
 
 	if (vt == NULL)
 		vt = vStringNew();
 	else
 		vStringClear(vt);
 
+	/* find the end of the type signature in the token list */
 	for (i = 0; i < st->tokenIndex; i++)
 	{
+		const tokenInfo *const t = st->token[i];
+
+		/* stop if we find the token used to generate the tag name, or
+		 * a name token in the middle yet not preceded by a scope separator */
+		if ((t == nameToken ||
+		     (t->type == nameToken->type &&
+		      t->keyword == nameToken->keyword &&
+		      t->lineNumber == nameToken->lineNumber &&
+		      strcmp(vStringValue(t->name), vStringValue(nameToken->name)) == 0)) ||
+		    (t->type == TOKEN_NAME && seenType &&
+		     (i > 0 && st->token[i - 1]->type != TOKEN_DOUBLE_COLON)))
+		{
+			break;
+		}
+		if (t->type != TOKEN_DOUBLE_COLON)
+			end = i + 1;
+		if (t->type == TOKEN_NAME)
+			seenType = TRUE;
+		else if (t->type == TOKEN_KEYWORD && isDataTypeKeyword(t))
+			seenType = TRUE;
+	}
+
+	/* ugly historic workaround when we can't figure out the type */
+	if (end < 2 && ! st->gotArgs)
+		return vStringValue(st->firstToken->name);
+
+	for (i = 0; i < end; i++)
+	{
 		tokenInfo *t = st->token[i];
 
 		switch (t->type)
 		{
 			case TOKEN_NAME:	/* user typename */
-				if (strcmp(vStringValue(t->name), vStringValue(st->firstToken->name)) != 0)
-					continue;
 				break;
 			case TOKEN_KEYWORD:
-				if (t->keyword != KEYWORD_EXTERN && t->keyword != KEYWORD_STATIC)	/* uninteresting keywords */
+				if ((t->keyword != KEYWORD_EXTERN && t->keyword != KEYWORD_STATIC) &&	/* uninteresting keywords */
+				    (st->gotArgs ||
+				     /* ignore uninteresting keywords for non-functions */
+				     (t->keyword != KEYWORD_PUBLIC &&
+				      t->keyword != KEYWORD_PRIVATE &&
+				      t->keyword != KEYWORD_PROTECTED &&
+				      t->keyword != KEYWORD_FINAL &&
+				      t->keyword != KEYWORD_TYPEDEF &&
+				      /* hack for D static conditions */
+				      t->keyword != KEYWORD_IF)))
+				{
 					break;
+				}
 				continue;
 			case TOKEN_STAR: vStringCatS(vt, " *"); continue;
 			case TOKEN_ARRAY: vStringCatS(vt, "[]"); continue;
+			case TOKEN_DOUBLE_COLON:
+				vStringCatS(vt, "::");
+				continue;
 			default: continue;
 		}
 		if (vStringLength(vt) > 0)
@@ -1426,7 +1478,7 @@ static void makeTag (const tokenInfo *const token,
 		e.type = type;
 
 		findScopeHierarchy (scope, st);
-		addOtherFields (&e, type, st, scope);
+		addOtherFields (&e, type, token, st, scope);
 
 #ifdef DEBUG_C
 		printTagEntry(&e);


Modified: tests/ctags/Makefile.am
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -301,6 +301,7 @@ test_sources = \
 	ui5.controller.js				\
 	union.f							\
 	value.f							\
+	var-and-return-type.cpp			\
 	whitespaces.php					\
 	$(NULL)
 test_results = $(test_sources:=.tags)


Modified: tests/ctags/bit_field.c.tags
8 lines changed, 4 insertions(+), 4 deletions(-)
===================================================================
@@ -1,18 +1,18 @@
 # format=tagmanager
-a�64�bit_fields�0�int
+a�64�bit_fields�0�unsigned int
 anon_struct_0�2048�0
 anon_struct_1�2048�0
 anon_struct_2�2048�0
-b�64�bit_fields�0�int
+b�64�bit_fields�0�unsigned int
 bad2�64�anon_struct_1�0�BYTE
 bit_fields�2048�0
 bitfield_flags�4096�0�anon_struct_1
-c�64�bit_fields�0�int
+c�64�bit_fields�0�unsigned int
 exp�64�anon_struct_0�0
 frac0�64�anon_struct_0�0
 frac1�64�anon_struct_0�0
 group�64�anon_struct_1�0�BYTE
-lower�64�shortname_info�0�char
+lower�64�shortname_info�0�unsigned char
 mystruct�4096�0�anon_struct_2
 personal�64�anon_struct_1�0�BYTE
 private�64�anon_struct_2�0�BYTE


Modified: tests/ctags/bug1799340.cpp.tags
6 lines changed, 3 insertions(+), 3 deletions(-)
===================================================================
@@ -1,4 +1,4 @@
 # format=tagmanager
-f1�16�()�0�std
-f2�16�()�0�const std
-f3�16�()�std�0�std const
+f1�16�()�0�std::string
+f2�16�()�0�const std::string
+f3�16�()�std�0�std::string const


Modified: tests/ctags/bug1907083.cpp.tags
8 lines changed, 4 insertions(+), 4 deletions(-)
===================================================================
@@ -1,5 +1,5 @@
 # format=tagmanager
-m1�16�()�C::C�0�C *C
-m2�16�()�C::C�0�C *const C
-m3�16�()�C::C�0�C const *C
-m4�16�()�C::C�0�C const *const C
+m1�16�()�C::C�0�C::T *
+m2�16�()�C::C�0�C::T *const
+m3�16�()�C::C�0�C::T const *
+m4�16�()�C::C�0�C::T const *const


Modified: tests/ctags/bug1924919.cpp.tags
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -1,4 +1,4 @@
 # format=tagmanager
-MajorVersion�64�mud�0�std
-MinorVersion�64�mud�0�std
+MajorVersion�64�mud�0�std::string
+MinorVersion�64�mud�0�std::string
 mud�256�0


Modified: tests/ctags/c-digraphs.c.tags
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -4,8 +4,8 @@ B
 M3_INIT�131072�(a, b, c)�0
 STRINGIFY�131072�(x)�0
 STRINGIFY_INTERN�131072�(x)�0
-buf�64�str�0�char
-len�64�str�0�int
+buf�64�str�0�char *
+len�64�str�0�unsigned int
 main�16�(void)�0�int
 matrix3�4096�0�int
 size�64�str�0�int


Modified: tests/ctags/c-trigraphs.c.tags
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -7,8 +7,8 @@ F
 M3_INIT�131072�(a, b, c)�0
 STRINGIFY�131072�(x)�0
 STRINGIFY_INTERN�131072�(x)�0
-buf�64�str�0�char
-len�64�str�0�int
+buf�64�str�0�char *
+len�64�str�0�unsigned int
 main�16�(void)�0�int
 matrix3�4096�0�int
 size�64�str�0�int


Modified: tests/ctags/indexer.cs.tags
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -2,4 +2,4 @@
 IndexerClass�1�0
 Main�128�()�MainClass�0�public void
 MainClass�1�0
-myArray�8�IndexerClass�0�int
+myArray�8�IndexerClass�0�int[]


Modified: tests/ctags/interface_indexers.cs.tags
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -3,4 +3,4 @@ IMyInterface
 IndexerClass�1�0
 Main�128�()�MainClass�0�public void
 MainClass�1�0
-myArray�8�IndexerClass�0�int
+myArray�8�IndexerClass�0�int[]


Modified: tests/ctags/keyword_const.cs.tags
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -3,7 +3,7 @@ ConstTest
 Main�128�()�ConstTest�0�public void
 MyClass�1�ConstTest�0
 MyClass�128�(int p1, int p2)�ConstTest.MyClass�0
-c1�8�ConstTest.MyClass�0�int
-c2�8�ConstTest.MyClass�0�int
+c1�8�ConstTest.MyClass�0�const int
+c2�8�ConstTest.MyClass�0�const int
 x�8�ConstTest.MyClass�0�int
 y�8�ConstTest.MyClass�0�int


Modified: tests/ctags/keyword_virtual.cs.tags
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -14,6 +14,6 @@ Main
 Sphere�1�TestClass�0
 Sphere�128�(double r)�TestClass.Sphere�0
 TestClass�1�0
-pi�8�TestClass.Dimensions�0�double
+pi�8�TestClass.Dimensions�0�const double
 x�8�TestClass.Dimensions�0�double
 y�8�TestClass.Dimensions�0�double


Modified: tests/ctags/keyword_volatile.cs.tags
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -2,4 +2,4 @@
 Main�128�()�Test�0�public void
 Test�1�0
 Test�128�(int _i)�Test�0
-i�8�Test�0�int
+i�8�Test�0�volatile int


Modified: tests/ctags/simple.d.tags
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -13,7 +13,7 @@ bar
 bar�1024�()�Interface�0�public AliasInt
 conditional�16384�0�T
 foo�4�Enum�0
-globalVar�16384�0�__gshared
+globalVar�16384�0�__gshared int
 i�16384�0�int
 main�16�(string[] args)�0�void
 obj�16384�0�Object


Modified: tests/ctags/var-and-return-type.cpp
40 lines changed, 40 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,40 @@
+
+const volatile unsigned int func1();
+const volatile unsigned int var1 = 0;
+
+struct type1 {
+	unsigned int memb1;
+	struct type1 *next;
+};
+
+const struct type1 func2();
+const struct type1 var2 = { 0, 0 };
+
+typedef type1 type1_t;
+
+const type1_t func3();
+const type1_t var3 = { 0, 0 };
+
+struct type1 func4();
+struct type1 var4 = { 0, 0 };
+
+type1_t func5();
+type1_t var5 = { 0, 0 };
+
+typedef unsigned long int type2_t;
+
+/* scoped stuff */
+
+#include <string>
+
+const std::string func6();
+const std::string var6 = "hello";
+
+std::string func7();
+std::string var7 = "hello";
+
+/* this shows a different bug in the parser, adding scope std to the symbol.
+ * ignore this for now.
+std::string const func8();
+std::string const var8 = "hello";
+*/


Modified: tests/ctags/var-and-return-type.cpp.tags
20 lines changed, 20 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,20 @@
+# format=tagmanager
+func1�1024�()�0�const volatile unsigned int
+func2�1024�()�0�type1
+func3�1024�()�0�const type1_t
+func4�1024�()�0�type1
+func5�1024�()�0�type1_t
+func6�1024�()�0�const std::string
+func7�1024�()�0�std::string
+memb1�64�type1�0�unsigned int
+next�64�type1�0�type1
+type1�2048�0
+type1_t�4096�0�type1
+type2_t�4096�0�unsigned long int
+var1�16384�0�const volatile unsigned int
+var2�16384�0�type1
+var3�16384�0�const type1_t
+var4�16384�0�type1
+var5�16384�0�type1_t
+var6�16384�0�const std::string
+var7�16384�0�std::string



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