diff options
author | Eli Zaretskii <eliz@gnu.org> | 2016-01-30 14:16:36 +0200 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2016-01-30 14:16:36 +0200 |
commit | 25b79d7bc71079cd6ebb2700623e7e3b76b03287 (patch) | |
tree | 1654109110b07b8ebf8fd9b9196e73f2d4553972 /lib-src | |
parent | ccc3b3cd68312e1d69d9f9af943ee2b9a9d88198 (diff) |
Improve Ruby support in 'etags'
* lib-src/etags.c (Ruby_functions): Tag constants. Don't tag
singleton classes. Remove class qualifiers from tags generated
for method and constant names. (Bug#22241)
* doc/emacs/maintaining.texi (Tag Syntax): Mention that constants
are tagged by etags in Ruby.
* etc/NEWS: Mention that constants are tagged by etags in Ruby.
* test/etags/ruby-src/test1.ruby: Add more tests.
* test/etags/ETAGS.good_1:
* test/etags/ETAGS.good_2:
* test/etags/ETAGS.good_3:
* test/etags/ETAGS.good_4:
* test/etags/ETAGS.good_5:
* test/etags/ETAGS.good_6:
* test/etags/CTAGS.good: Adapt to the changes in etags and in Ruby
tests.
Diffstat (limited to 'lib-src')
-rw-r--r-- | lib-src/etags.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index 54ed1b428e..adc08a2367 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -4550,18 +4550,68 @@ Ruby_functions (FILE *inf) LOOP_ON_INPUT_LINES (inf, lb, cp) { + bool is_class = false; + bool is_method = false; + char *name; + cp = skip_spaces (cp); - if (LOOKING_AT (cp, "def") - || LOOKING_AT (cp, "class") - || LOOKING_AT (cp, "module")) + if (c_isalpha (*cp) && c_isupper (*cp)) /* constants */ { - char *name = cp; + char *bp, *colon = NULL; + + name = cp; + + for (cp++; c_isalnum (*cp) || *cp == '_' || *cp == ':'; cp++) + { + if (*cp == ':') + colon = cp; + } + if (cp > name + 1) + { + bp = skip_spaces (cp); + if (*bp == '=' && c_isspace (bp[1])) + { + if (colon && !c_isspace (colon[1])) + name = colon + 1; + make_tag (name, cp - name, false, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } + } + } + else if ((is_method = LOOKING_AT (cp, "def")) /* module/class/method */ + || (is_class = LOOKING_AT (cp, "class")) + || LOOKING_AT (cp, "module")) + { + const char self_name[] = "self."; + const size_t self_size1 = sizeof ("self.") - 1; + + name = cp; /* Ruby method names can end in a '='. Also, operator overloading can define operators whose names include '='. */ while (!notinname (*cp) || *cp == '=') cp++; + /* Remove "self." from the method name. */ + if (cp - name > self_size1 + && strneq (name, self_name, self_size1)) + name += self_size1; + + /* Remove the class/module qualifiers from method names. */ + if (is_method) + { + char *q; + + for (q = name; q < cp && *q != '.'; q++) + ; + if (q < cp - 1) /* punt if we see just "FOO." */ + name = q + 1; + } + + /* Don't tag singleton classes. */ + if (is_class && strneq (name, "<<", 2) && cp == name + 2) + continue; + make_tag (name, cp - name, true, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } |