Fix irregularities with CC Mode fontification, particularly with "known types"
* lisp/progmodes/cc-fonts.el (c-font-lock-declarators): Introduce a new optional parameter, template-class. In "class <X = Y>", fontify "Y" as a type. (c-font-lock-single-decl): New variable template-class, set to non-nil when we have a construct like the above. Pass this as argument to c-font-lock-declarators. (c-font-lock-cut-off-declarators): Check more rigorously that a declaration being processed starts before the function's starting position. (c-complex-decl-matchers): Remove the redundant clause which fontified "types preceded by, e.g., "struct"". * lisp/progmodes/cc-langs.el (c-template-typename-kwds) (c-template-typename-key): New lang defconsts and defvar.
This commit is contained in:
parent
bd5326f879
commit
57ab49f7da
2 changed files with 55 additions and 105 deletions
|
@ -1026,7 +1026,8 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(goto-char pos)))))
|
||||
nil)
|
||||
|
||||
(defun c-font-lock-declarators (limit list types not-top)
|
||||
(defun c-font-lock-declarators (limit list types not-top
|
||||
&optional template-class)
|
||||
;; Assuming the point is at the start of a declarator in a declaration,
|
||||
;; fontify the identifier it declares. (If TYPES is set, it does this via
|
||||
;; the macro `c-fontify-types-and-refs'.)
|
||||
|
@ -1040,6 +1041,11 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
;; non-nil, we are not at the top-level ("top-level" includes being directly
|
||||
;; inside a class or namespace, etc.).
|
||||
;;
|
||||
;; TEMPLATE-CLASS is non-nil when the declaration is in template delimiters
|
||||
;; and was introduced by, e.g. "typename" or "class", such that if there is
|
||||
;; a default (introduced by "="), it will be fontified as a type.
|
||||
;; E.g. "<class X = Y>".
|
||||
;;
|
||||
;; Nil is always returned. The function leaves point at the delimiter after
|
||||
;; the last declarator it processes.
|
||||
;;
|
||||
|
@ -1112,6 +1118,13 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
|
||||
(goto-char next-pos)
|
||||
(setq pos nil) ; So as to terminate the enclosing `while' form.
|
||||
(if (and template-class
|
||||
(eq got-init ?=) ; C++ "<class X = Y>"?
|
||||
(c-forward-token-2 1 nil limit) ; Over "="
|
||||
(let ((c-promote-possible-types t))
|
||||
(c-forward-type t))) ; Over "Y"
|
||||
(setq list nil)) ; Shouldn't be needed. We can't have a list, here.
|
||||
|
||||
(when list
|
||||
;; Jump past any initializer or function prototype to see if
|
||||
;; there's a ',' to continue at.
|
||||
|
@ -1340,8 +1353,12 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(c-backward-syntactic-ws)
|
||||
(and (c-simple-skip-symbol-backward)
|
||||
(looking-at c-paren-stmt-key))))
|
||||
t)))
|
||||
|
||||
t))
|
||||
(template-class (and (eq context '<>)
|
||||
(save-excursion
|
||||
(goto-char match-pos)
|
||||
(c-forward-syntactic-ws)
|
||||
(looking-at c-template-typename-key)))))
|
||||
;; Fix the `c-decl-id-start' or `c-decl-type-start' property
|
||||
;; before the first declarator if it's a list.
|
||||
;; `c-font-lock-declarators' handles the rest.
|
||||
|
@ -1353,10 +1370,9 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(if (cadr decl-or-cast)
|
||||
'c-decl-type-start
|
||||
'c-decl-id-start)))))
|
||||
|
||||
(c-font-lock-declarators
|
||||
(min limit (point-max)) decl-list
|
||||
(cadr decl-or-cast) (not toplev)))
|
||||
(cadr decl-or-cast) (not toplev) template-class))
|
||||
|
||||
;; A declaration has been successfully identified, so do all the
|
||||
;; fontification of types and refs that've been recorded.
|
||||
|
@ -1650,7 +1666,8 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
;; font-lock-keyword-face. It always returns NIL to inhibit this and
|
||||
;; prevent a repeat invocation. See elisp/lispref page "Search-based
|
||||
;; fontification".
|
||||
(let ((decl-search-lim (c-determine-limit 1000))
|
||||
(let ((here (point))
|
||||
(decl-search-lim (c-determine-limit 1000))
|
||||
paren-state encl-pos token-end context decl-or-cast
|
||||
start-pos top-level c-restricted-<>-arglists
|
||||
c-recognize-knr-p) ; Strictly speaking, bogus, but it
|
||||
|
@ -1667,26 +1684,27 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(when (or (bobp)
|
||||
(memq (char-before) '(?\; ?{ ?})))
|
||||
(setq token-end (point))
|
||||
(c-forward-syntactic-ws)
|
||||
;; We're now putatively at the declaration.
|
||||
(setq start-pos (point))
|
||||
(setq paren-state (c-parse-state))
|
||||
;; At top level or inside a "{"?
|
||||
(if (or (not (setq encl-pos
|
||||
(c-most-enclosing-brace paren-state)))
|
||||
(eq (char-after encl-pos) ?\{))
|
||||
(progn
|
||||
(setq top-level (c-at-toplevel-p))
|
||||
(let ((got-context (c-get-fontification-context
|
||||
token-end nil top-level)))
|
||||
(setq context (car got-context)
|
||||
c-restricted-<>-arglists (cdr got-context)))
|
||||
(setq decl-or-cast
|
||||
(c-forward-decl-or-cast-1 token-end context nil))
|
||||
(when (consp decl-or-cast)
|
||||
(goto-char start-pos)
|
||||
(c-font-lock-single-decl limit decl-or-cast token-end
|
||||
context top-level)))))))
|
||||
(c-forward-syntactic-ws here)
|
||||
(when (< (point) here)
|
||||
;; We're now putatively at the declaration.
|
||||
(setq start-pos (point))
|
||||
(setq paren-state (c-parse-state))
|
||||
;; At top level or inside a "{"?
|
||||
(if (or (not (setq encl-pos
|
||||
(c-most-enclosing-brace paren-state)))
|
||||
(eq (char-after encl-pos) ?\{))
|
||||
(progn
|
||||
(setq top-level (c-at-toplevel-p))
|
||||
(let ((got-context (c-get-fontification-context
|
||||
token-end nil top-level)))
|
||||
(setq context (car got-context)
|
||||
c-restricted-<>-arglists (cdr got-context)))
|
||||
(setq decl-or-cast
|
||||
(c-forward-decl-or-cast-1 token-end context nil))
|
||||
(when (consp decl-or-cast)
|
||||
(goto-char start-pos)
|
||||
(c-font-lock-single-decl limit decl-or-cast token-end
|
||||
context top-level))))))))
|
||||
nil))
|
||||
|
||||
(defun c-font-lock-enclosing-decls (limit)
|
||||
|
@ -1996,85 +2014,6 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
|
|||
2 font-lock-type-face)
|
||||
`(,(concat "\\<\\(" re "\\)\\>")
|
||||
1 'font-lock-type-face)))
|
||||
|
||||
;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct").
|
||||
,@(when (c-lang-const c-type-prefix-kwds)
|
||||
`((,(byte-compile
|
||||
`(lambda (limit)
|
||||
(c-fontify-types-and-refs
|
||||
((c-promote-possible-types t)
|
||||
;; The font-lock package in Emacs is known to clobber
|
||||
;; `parse-sexp-lookup-properties' (when it exists).
|
||||
(parse-sexp-lookup-properties
|
||||
(cc-eval-when-compile
|
||||
(boundp 'parse-sexp-lookup-properties))))
|
||||
(save-restriction
|
||||
;; Narrow to avoid going past the limit in
|
||||
;; `c-forward-type'.
|
||||
(narrow-to-region (point) limit)
|
||||
(while (re-search-forward
|
||||
,(concat "\\<\\("
|
||||
(c-make-keywords-re nil
|
||||
(c-lang-const c-type-prefix-kwds))
|
||||
"\\)\\>")
|
||||
limit t)
|
||||
(unless (c-skip-comments-and-strings limit)
|
||||
(c-forward-syntactic-ws)
|
||||
;; Handle prefix declaration specifiers.
|
||||
(while
|
||||
(or
|
||||
(when (or (looking-at c-prefix-spec-kwds-re)
|
||||
(and (c-major-mode-is 'java-mode)
|
||||
(looking-at "@[A-Za-z0-9]+")))
|
||||
(c-forward-keyword-clause 1)
|
||||
t)
|
||||
(when (and c-opt-cpp-prefix
|
||||
(looking-at
|
||||
c-noise-macro-with-parens-name-re))
|
||||
(c-forward-noise-clause)
|
||||
t)))
|
||||
,(if (c-major-mode-is 'c++-mode)
|
||||
`(when (and (c-forward-type)
|
||||
(eq (char-after) ?=))
|
||||
;; In C++ we additionally check for a "class
|
||||
;; X = Y" construct which is used in
|
||||
;; templates, to fontify Y as a type.
|
||||
(forward-char)
|
||||
(c-forward-syntactic-ws)
|
||||
(c-forward-type))
|
||||
`(c-forward-type))
|
||||
)))))))))
|
||||
|
||||
;; Fontify symbols after closing braces as declaration
|
||||
;; identifiers under the assumption that they are part of
|
||||
;; declarations like "class Foo { ... } foo;". It's too
|
||||
;; expensive to check this accurately by skipping past the
|
||||
;; brace block, so we use the heuristic that it's such a
|
||||
;; declaration if the first identifier is on the same line as
|
||||
;; the closing brace. `c-font-lock-declarations' will later
|
||||
;; override it if it turns out to be an new declaration, but
|
||||
;; it will be wrong if it's an expression (see the test
|
||||
;; decls-8.cc).
|
||||
;; ,@(when (c-lang-const c-opt-block-decls-with-vars-key)
|
||||
;; `((,(c-make-font-lock-search-function
|
||||
;; (concat "}"
|
||||
;; (c-lang-const c-single-line-syntactic-ws)
|
||||
;; "\\(" ; 1 + c-single-line-syntactic-ws-depth
|
||||
;; (c-lang-const c-type-decl-prefix-key)
|
||||
;; "\\|"
|
||||
;; (c-lang-const c-symbol-key)
|
||||
;; "\\)")
|
||||
;; `((c-font-lock-declarators limit t nil) ; That nil says use `font-lock-variable-name-face';
|
||||
;; ; t would mean `font-lock-function-name-face'.
|
||||
;; (progn
|
||||
;; (c-put-char-property (match-beginning 0) 'c-type
|
||||
;; 'c-decl-id-start)
|
||||
;; ; 'c-decl-type-start)
|
||||
;; (goto-char (match-beginning
|
||||
;; ,(1+ (c-lang-const
|
||||
;; c-single-line-syntactic-ws-depth)))))
|
||||
;; (goto-char (match-end 0)))))))
|
||||
|
||||
;; Fontify the type in C++ "new" expressions.
|
||||
,@(when (c-major-mode-is 'c++-mode)
|
||||
;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)"
|
||||
|
|
|
@ -1896,6 +1896,17 @@ the type of that expression."
|
|||
t (c-make-keywords-re t (c-lang-const c-typeof-kwds)))
|
||||
(c-lang-defvar c-typeof-key (c-lang-const c-typeof-key))
|
||||
|
||||
(c-lang-defconst c-template-typename-kwds
|
||||
"Keywords which, within a template declaration, can introduce a
|
||||
declaration with a type as a default value. This is used only in
|
||||
C++ Mode, e.g. \"<typename X = Y>\"."
|
||||
t nil
|
||||
c++ '("class" "typename"))
|
||||
|
||||
(c-lang-defconst c-template-typename-key
|
||||
t (c-make-keywords-re t (c-lang-const c-template-typename-kwds)))
|
||||
(c-lang-defvar c-template-typename-key (c-lang-const c-template-typename-key))
|
||||
|
||||
(c-lang-defconst c-type-prefix-kwds
|
||||
"Keywords where the following name - if any - is a type name, and
|
||||
where the keyword together with the symbol works as a type in
|
||||
|
|
Loading…
Add table
Reference in a new issue