X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b14e3e21ec6702d27257a1400681fc36ee10282f..732fd4c7e11debd61c97eaaba3038d61e6ec7024:/lisp/progmodes/cc-menus.el diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el index f53a7da518..784e5c6935 100644 --- a/lisp/progmodes/cc-menus.el +++ b/lisp/progmodes/cc-menus.el @@ -1,6 +1,6 @@ ;;; cc-menus.el --- imenu support for CC Mode -;; Copyright (C) 1985, 1987, 1992-2011 Free Software Foundation, Inc. +;; Copyright (C) 1985, 1987, 1992-2015 Free Software Foundation, Inc. ;; Authors: 1998- Martin Stjernholm ;; 1992-1999 Barry A. Warsaw @@ -63,10 +63,24 @@ For example: A sample value might look like: `\\(_P\\|_PROTO\\)'.") +;; *Warning for cc-mode developers* +;; +;; `cc-imenu-objc-generic-expression' elements depend on +;; `cc-imenu-c++-generic-expression'. So if you change this +;; expression, you need to change following variables, +;; `cc-imenu-objc-generic-expression-*-index', +;; too. `cc-imenu-objc-function' uses these *-index variables, in +;; order to know where the each regexp *group \\(foobar\\)* elements +;; are started. +;; +;; *-index variables are initialized during `cc-imenu-objc-generic-expression' +;; being initialized. +;; + (defvar cc-imenu-c++-generic-expression `( ;; Try to match ::operator definitions first. Otherwise `X::operator new ()' - ;; will be incorrectly recognised as function `new ()' because the regexps + ;; will be incorrectly recognized as function `new ()' because the regexps ;; work by backtracking from the end of the definition. (nil ,(concat @@ -108,8 +122,11 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.") "[^" c-alnum "_:<>~]" ; match any non-identifier char "\\([" c-alpha "_][" c-alnum "_:<>~]*\\)" ; match function name "\\([ \t\n]\\|\\\\\n\\)*(" ; see above, BUT the arg list - "\\([ \t\n]\\|\\\\\n\\)*\\([^ \t\n(*][^)]*\\)?)" ; must not start - "\\([ \t\n]\\|\\\\\n\\)*[^ \t\n;(]" ; with an asterisk or parentheses + "\\([ \t\n]\\|\\\\\n\\)*" ; must not start + "\\([^ \t\n(*]" ; with an asterisk or parentheses + "[^()]*\\(([^()]*)[^()]*\\)*" ; Maybe function pointer arguments + "\\)?)" + "\\([ \t\n]\\|\\\\\n\\)*[^ \t\n;(]" ) 1) ;; Special case for definitions using phony prototype macros like: ;; `int main _PROTO( (int argc,char *argv[]) )'. @@ -144,63 +161,131 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.") cc-imenu-c++-generic-expression "Imenu generic expression for C mode. See `imenu-generic-expression'.") -(defvar cc-imenu-java-generic-expression + +;; Auxiliary regexps for Java try to match their trailing whitespace where +;; appropriate, but _not_ starting whitespace. + +(defconst cc-imenu-java-ellipsis-regexp + (concat + "\\.\\{3\\}" + "[ \t\n\r]*")) + +(defun cc-imenu-java-build-type-args-regex (depth) + "Builds regexp for type arguments list with DEPTH allowed +nested angle brackets constructs." + (if (> depth 0) + (concat "<" + "[][.," c-alnum "_? \t\n\r]+" + (if (> depth 1) + "\\(") + (cc-imenu-java-build-type-args-regex (1- depth)) + (if (> depth 1) + (concat "[][.," c-alnum "_? \t\n\r]*" + "\\)*")) + ">"))) + +(defconst cc-imenu-java-type-spec-regexp + (concat + ;; zero or more identifiers followed by a dot + "\\(" + "[" c-alpha "_][" c-alnum "_]*\\." + "\\)*" + ;; a single mandatory identifier without a dot + "[" c-alpha "_][" c-alnum "_]*" + ;; then choice: + "\\(" + ;; (option 1) type arguments list which _may_ be followed with brackets + ;; and/or spaces, then optional variable arity + "[ \t\n\r]*" + (cc-imenu-java-build-type-args-regex 3) + "[][ \t\n\r]*" + "\\(" cc-imenu-java-ellipsis-regexp "\\)?" + "\\|" + ;; (option 2) just brackets and/or spaces (there should be at least one), + ;; then optional variable arity + "[][ \t\n\r]+" + "\\(" cc-imenu-java-ellipsis-regexp "\\)?" + "\\|" + ;; (option 3) just variable arity + cc-imenu-java-ellipsis-regexp + "\\)")) + +(defconst cc-imenu-java-comment-regexp + (concat + "/" + "\\(" + ;; a traditional comment + "\\*" + "\\(" + "[^*]" + "\\|" + "\\*+[^/*]" + "\\)*" + "\\*+/" + "\\|" + ;; an end-of-line comment + "/[^\n\r]*[\n\r]" + "\\)" + "[ \t\n\r]*" + )) + +;; Comments are allowed before the argument, after any of the +;; modifiers and after the identifier. +(defconst cc-imenu-java-method-arg-regexp + (concat + "\\(" cc-imenu-java-comment-regexp "\\)*" + ;; optional modifiers + "\\(" + ;; a modifier is either an annotation or "final" + "\\(" + "@[" c-alpha "_]" + "[" c-alnum "._]*" + ;; TODO support element-value pairs! + "\\|" + "final" + "\\)" + ;; a modifier ends with comments and/or ws + "\\(" + "\\(" cc-imenu-java-comment-regexp "\\)+" + "\\|" + "[ \t\n\r]+" + "\\(" cc-imenu-java-comment-regexp "\\)*" + "\\)" + "\\)*" + ;; type spec + cc-imenu-java-type-spec-regexp + ;; identifier + "[" c-alpha "_]" + "[" c-alnum "_]*" + ;; optional comments and/or ws + "[ \t\n\r]*" + "\\(" cc-imenu-java-comment-regexp "\\)*" + )) + +(defconst cc-imenu-java-generic-expression `((nil ,(concat - "[" c-alpha "_][\]\[." c-alnum "_<> ]+[ \t\n\r]+" ; type spec - "\\([" c-alpha "_][" c-alnum "_]*\\)" ; method name + cc-imenu-java-type-spec-regexp + "\\(" ; method name which gets captured + ; into index + "[" c-alpha "_]" + "[" c-alnum "_]*" + "\\)" "[ \t\n\r]*" - ;; An argument list htat is either empty or contains any number - ;; of arguments. An argument is any number of annotations - ;; followed by a type spec followed by a word. A word is an - ;; identifier. A type spec is an identifier, possibly followed - ;; by < typespec > possibly followed by []. - (concat "(" - "\\(" - "[ \t\n\r]*" - "\\(" - "@" - "[" c-alpha "_]" - "[" c-alnum "._]""*" - "[ \t\n\r]+" - "\\)*" - "\\(" - "[" c-alpha "_]" - "[\]\[" c-alnum "_.]*" - "\\(" - - "<" - "[ \t\n\r]*" - "[\]\[.," c-alnum "_<> \t\n\r]*" - ">" - "\\)?" - "\\(\\[\\]\\)?" - "[ \t\n\r]+" - "\\)" - "[" c-alpha "_]" - "[" c-alnum "_]*" - "[ \t\n\r,]*" - "\\)*" - ")" - "[.," c-alnum " \t\n\r]*" - "{" - )) 1)) - "Imenu generic expression for Java mode. See -`imenu-generic-expression'.") - -;; *Warning for cc-mode developers* -;; -;; `cc-imenu-objc-generic-expression' elements depend on -;; `cc-imenu-c++-generic-expression'. So if you change this -;; expression, you need to change following variables, -;; `cc-imenu-objc-generic-expression-*-index', -;; too. `cc-imenu-objc-function' uses these *-index variables, in -;; order to know where the each regexp *group \\(foobar\\)* elements -;; are started. -;; -;; *-index variables are initialized during `cc-imenu-objc-generic-expression' -;; being initialized. -;; + ;; An argument list that contains zero or more arguments. + (concat + "(" + "[ \t\n\r]*" + "\\(" + "\\(" cc-imenu-java-method-arg-regexp ",[ \t\n\r]*\\)*" + cc-imenu-java-method-arg-regexp + "\\)?" + ")" + "[.,_" c-alnum " \t\n\r]*" ; throws etc. + "{" + )) 7)) + "Imenu generic expression for Java mode. See `imenu-generic-expression'.") + ;; Internal variables (defvar cc-imenu-objc-generic-expression-noreturn-index nil) @@ -221,7 +306,7 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.") "\\|" ;; > General function name regexp ;; Pick a token by (match-string 3) - (car (cdr (nth 2 cc-imenu-c++-generic-expression))) ; -> index += 5 + (car (cdr (nth 2 cc-imenu-c++-generic-expression))) ; -> index += 6 (prog2 (setq cc-imenu-objc-generic-expression-general-func-index 3) "") ;; > Special case for definitions using phony prototype macros like: ;; > `int main _PROTO( (int argc,char *argv[]) )'. @@ -230,11 +315,11 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.") (concat "\\|" (car (cdr (nth 3 cc-imenu-c++-generic-expression))) ; -> index += 1 - (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 9) "") + (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 10) "") ) - (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 8) "") + (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 9) "") "") ; -> index += 0 - (prog2 (setq cc-imenu-objc-generic-expression-proto-index 8) "") + (prog2 (setq cc-imenu-objc-generic-expression-proto-index 9) "") ;; ;; For Objective-C ;; Pick a token by (match-string 8 or 9) @@ -397,14 +482,10 @@ Example: str2 "@protocol"))) (setq str (cc-imenu-objc-remove-white-space str)) (setq methodlist (cons (cons str2 - (match-beginning langnum)) + (match-beginning langnum)) methodlist)) - (setq toplist (cons nil (cons (cons str - methodlist) toplist)) + (setq toplist (cons (cons str methodlist) toplist) methodlist nil)))) - ;; - (if (eq (car toplist) nil) - (setq toplist (cdr toplist))) ;; In this buffer, there is only one or zero @{interface|implementation|protocol}. (if (< classcount 2)