[geany/geany] 1ed29f: ruby: Fix parsing qualified identifiers

Colomban Wendling git-noreply at xxxxx
Mon Mar 14 18:27:22 UTC 2016


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Mon, 14 Mar 2016 18:27:22 UTC
Commit:      1ed29f1d7b948e7d7fde70499491673e65a04954
             https://github.com/geany/geany/commit/1ed29f1d7b948e7d7fde70499491673e65a04954

Log Message:
-----------
ruby: Fix parsing qualified identifiers

The implementation is a bit hacky, but avoids the need for complex
logic to pop several scopes at once.

Closes universal-ctags/ctags#452.


Modified Paths:
--------------
    tagmanager/ctags/ruby.c
    tests/ctags/Makefile.am
    tests/ctags/ruby-namespaced-class.rb
    tests/ctags/ruby-namespaced-class.rb.tags

Modified: tagmanager/ctags/ruby.c
40 lines changed, 36 insertions(+), 4 deletions(-)
===================================================================
@@ -43,6 +43,8 @@ static kindOption RubyKinds [] = {
 
 static stringList* nesting = NULL;
 
+#define SCOPE_SEPARATOR '.'
+
 /*
 *   FUNCTION DEFINITIONS
 */
@@ -66,7 +68,8 @@ static vString* stringListToScope (const stringList* list)
 	    vString* chunk = stringListItem (list, i);
 	    if (vStringLength (chunk) > 0)
 	    {
-	        vStringCatS (result, (chunks_output++ > 0) ? "." : "");
+	        if (chunks_output++ > 0)
+	            vStringPut (result, SCOPE_SEPARATOR);
 	        vStringCatS (result, vStringValue (chunk));
 	    }
 	}
@@ -165,6 +168,8 @@ static void emitRubyTag (vString* name, rubyKind kind)
 {
 	tagEntryInfo tag;
 	vString* scope;
+	const char *unqualified_name;
+	const char *qualified_name;
 
 	if (!RubyKinds[kind].enabled) {
 		return;
@@ -173,7 +178,23 @@ static void emitRubyTag (vString* name, rubyKind kind)
 	vStringTerminate (name);
 	scope = stringListToScope (nesting);
 
-	initTagEntry (&tag, vStringValue (name));
+	qualified_name = vStringValue (name);
+	unqualified_name = strrchr (qualified_name, SCOPE_SEPARATOR);
+	if (unqualified_name && unqualified_name[1])
+	{
+		if (unqualified_name > qualified_name)
+		{
+			if (vStringLength (scope) > 0)
+				vStringPut (scope, SCOPE_SEPARATOR);
+			vStringNCatS (scope, qualified_name,
+			              unqualified_name - qualified_name);
+		}
+		unqualified_name++;
+	}
+	else
+		unqualified_name = qualified_name;
+
+	initTagEntry (&tag, unqualified_name);
 	if (vStringLength (scope) > 0) {
 	    tag.extensionFields.scope [0] = "class";
 	    tag.extensionFields.scope [1] = vStringValue (scope);
@@ -215,6 +236,7 @@ static rubyKind parseIdentifier (
 	 * point or equals sign. These are all part of the name.
 	 * A method name may also contain a period if it's a singleton method.
 	 */
+	boolean had_sep = FALSE;
 	const char* also_ok;
 	if (kind == K_METHOD)
 	{
@@ -251,11 +273,21 @@ static rubyKind parseIdentifier (
 	}
 
 	/* Copy the identifier into 'name'. */
-	while (**cp != 0 && (isalnum (**cp) || charIsIn (**cp, also_ok)))
+	while (**cp != 0 && (**cp == ':' || isalnum (**cp) || charIsIn (**cp, also_ok)))
 	{
 		char last_char = **cp;
 
-		vStringPut (name, last_char);
+		if (last_char == ':')
+			had_sep = TRUE;
+		else
+		{
+			if (had_sep)
+			{
+				vStringPut (name, SCOPE_SEPARATOR);
+				had_sep = FALSE;
+			}
+			vStringPut (name, last_char);
+		}
 		++*cp;
 
 		if (kind == K_METHOD)


Modified: tests/ctags/Makefile.am
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -257,6 +257,7 @@ test_sources = \
 	return-types.go					\
 	ruby-block-call.rb				\
 	ruby-doc.rb						\
+	ruby-namespaced-class.rb		\
 	ruby-sf-bug-364.rb				\
 	rules.t2t						\
 	sample.t2t						\


Modified: tests/ctags/ruby-namespaced-class.rb
8 lines changed, 8 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,8 @@
+module A
+  module B
+  end
+end
+
+class A::B::C; end
+
+puts A::B::C


Modified: tests/ctags/ruby-namespaced-class.rb.tags
4 lines changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,4 @@
+# format=tagmanager
+A�256�0
+B�256�A�0
+C�1�A.B�0



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