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.
This commit is contained in:
parent
eaf6c82af8
commit
1ed29f1d7b
@ -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)
|
||||
|
@ -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 \
|
||||
|
8
tests/ctags/ruby-namespaced-class.rb
Normal file
8
tests/ctags/ruby-namespaced-class.rb
Normal file
@ -0,0 +1,8 @@
|
||||
module A
|
||||
module B
|
||||
end
|
||||
end
|
||||
|
||||
class A::B::C; end
|
||||
|
||||
puts A::B::C
|
4
tests/ctags/ruby-namespaced-class.rb.tags
Normal file
4
tests/ctags/ruby-namespaced-class.rb.tags
Normal file
@ -0,0 +1,4 @@
|
||||
# format=tagmanager
|
||||
AÌ256Ö0
|
||||
BÌ256ÎAÖ0
|
||||
CÌ1ÎA.BÖ0
|
Loading…
x
Reference in New Issue
Block a user