summaryrefslogtreecommitdiff
path: root/lib-src
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2016-01-30 14:16:36 +0200
committerEli Zaretskii <eliz@gnu.org>2016-01-30 14:16:36 +0200
commit25b79d7bc71079cd6ebb2700623e7e3b76b03287 (patch)
tree1654109110b07b8ebf8fd9b9196e73f2d4553972 /lib-src
parentccc3b3cd68312e1d69d9f9af943ee2b9a9d88198 (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.c58
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);
}