diff options
author | Alan Mackenzie <acm@muc.de> | 2017-09-16 11:31:38 +0000 |
---|---|---|
committer | Alan Mackenzie <acm@muc.de> | 2017-09-16 11:31:38 +0000 |
commit | 4ea37c2b8b0c5a68fde59770c3536195e0972217 (patch) | |
tree | 4d961e699f3379139974cef30e8b7d26e0e7b4a1 | |
parent | 2d53f8783ff8e48d91809741adab6a2402587fad (diff) | |
download | emacs-4ea37c2b8b0c5a68fde59770c3536195e0972217.tar.gz emacs-4ea37c2b8b0c5a68fde59770c3536195e0972217.tar.bz2 emacs-4ea37c2b8b0c5a68fde59770c3536195e0972217.zip |
Cope better with C++ and Objective-C protection keywords in class declarations
This fix fixes the fontification of a method inside a class at the time it is
typed, when there is a protection keyword clause preceding it.
* lisp/progmodes/cc-engine.el (c-forward-keyword-clause): Handle protection
keywords.
(c-looking-at-decl-block): Avoid scanning forward over protection keyword
clauses too eagerly.
* lisp/progmodes/cc-langs.el (c-protection-key c-post-protection-token): New
lang defconsts and defvars.
* lisp/progmodes/cc-mode.el (c-fl-decl-start): When we encounter a protection
keyword following a semicolon or brace, move forward over it before attempting
to parse a type.
-rw-r--r-- | lisp/progmodes/cc-engine.el | 25 | ||||
-rw-r--r-- | lisp/progmodes/cc-langs.el | 12 | ||||
-rw-r--r-- | lisp/progmodes/cc-mode.el | 19 |
3 files changed, 45 insertions, 11 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index d5083ed2481..05b391a3d38 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -6924,7 +6924,7 @@ comment at the start of cc-engine.el for more info." ;; recognized are those specified by `c-type-list-kwds', ;; `c-ref-list-kwds', `c-colon-type-list-kwds', ;; `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds', - ;; and `c-<>-arglist-kwds'. + ;; `c-<>-arglist-kwds', and `c-protection-kwds'. ;; ;; This function records identifier ranges on ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if @@ -6994,6 +6994,17 @@ comment at the start of cc-engine.el for more info." (not (looking-at c-symbol-start)) (c-safe (c-forward-sexp) t)) (c-forward-syntactic-ws) + (setq safe-pos (point))) + + ((and (c-keyword-member kwd-sym 'c-protection-kwds) + (or (null c-post-protection-token) + (and (looking-at c-post-protection-token) + (save-excursion + (goto-char (match-end 0)) + (not (c-end-of-current-token)))))) + (if c-post-protection-token + (goto-char (match-end 0))) + (c-forward-syntactic-ws) (setq safe-pos (point)))) (when (c-keyword-member kwd-sym 'c-colon-type-list-kwds) @@ -10169,8 +10180,16 @@ comment at the start of cc-engine.el for more info." ;; Could be more restrictive wrt invalid keywords, ;; but that'd only occur in invalid code so there's ;; no use spending effort on it. - (let ((end (match-end 0))) - (unless (c-forward-keyword-clause 0) + (let ((end (match-end 0)) + (kwd-sym (c-keyword-sym (match-string 0)))) + (unless + (and kwd-sym + ;; Moving over a protection kwd and the following + ;; ":" (in C++ Mode) to the next token could take + ;; us all the way up to `kwd-start', leaving us + ;; no chance to update `first-specifier-pos'. + (not (c-keyword-member kwd-sym 'c-protection-kwds)) + (c-forward-keyword-clause 0)) (goto-char end) (c-forward-syntactic-ws))) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index ef6b88c3727..7a285f93d34 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -2284,6 +2284,18 @@ one of `c-type-list-kwds', `c-ref-list-kwds', c++ '("private" "protected" "public") objc '("@private" "@protected" "@public")) +(c-lang-defconst c-protection-key + ;; A regexp match an element of `c-protection-kwds' cleanly. + t (c-make-keywords-re t (c-lang-const c-protection-kwds))) +(c-lang-defvar c-protection-key (c-lang-const c-protection-key)) + +(c-lang-defconst c-post-protection-token + "The token which (may) follow a protection keyword, +e.g. the \":\" in C++ Mode's \"public:\". nil if there is no such token." + t nil + c++ ":") +(c-lang-defvar c-post-protection-token (c-lang-const c-post-protection-token)) + (c-lang-defconst c-block-decls-with-vars "Keywords introducing declarations that can contain a block which might be followed by variable declarations, e.g. like \"foo\" in diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 354dee82df9..8867453e85c 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -1526,14 +1526,17 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".") (> (point) bod-lim) (progn (c-forward-syntactic-ws) (setq bo-decl (point)) - ;; Are we looking at a keyword such as "template" or - ;; "typedef" which can decorate a type, or the type itself? - (when (or (looking-at c-prefix-spec-kwds-re) - (c-forward-type t)) - ;; We've found another candidate position. - (setq new-pos (min new-pos bo-decl)) - (goto-char bo-decl)) - t) + (or (not (looking-at c-protection-key)) + (c-forward-keyword-clause 1))) + (progn + ;; Are we looking at a keyword such as "template" or + ;; "typedef" which can decorate a type, or the type itself? + (when (or (looking-at c-prefix-spec-kwds-re) + (c-forward-type t)) + ;; We've found another candidate position. + (setq new-pos (min new-pos bo-decl)) + (goto-char bo-decl)) + t) ;; Try and go out a level to search again. (progn (c-backward-syntactic-ws bod-lim) |