diff options
| author | Alan Mackenzie | 2017-09-18 08:52:24 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2017-09-18 08:52:24 +0000 |
| commit | 61a5c30e70926f48480b03b79f4f531c8d64418e (patch) | |
| tree | 504d5533ad5177b4156dcc691cffc62ba510ee3e | |
| parent | 198ba449845ffa557ac272c3219c703148648f53 (diff) | |
| download | emacs-61a5c30e70926f48480b03b79f4f531c8d64418e.tar.gz emacs-61a5c30e70926f48480b03b79f4f531c8d64418e.zip | |
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.
| -rw-r--r-- | lisp/progmodes/cc-fonts.el | 149 | ||||
| -rw-r--r-- | lisp/progmodes/cc-langs.el | 11 |
2 files changed, 55 insertions, 105 deletions
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 5aefdea3305..02b685d240d 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el | |||
| @@ -1026,7 +1026,8 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1026 | (goto-char pos))))) | 1026 | (goto-char pos))))) |
| 1027 | nil) | 1027 | nil) |
| 1028 | 1028 | ||
| 1029 | (defun c-font-lock-declarators (limit list types not-top) | 1029 | (defun c-font-lock-declarators (limit list types not-top |
| 1030 | &optional template-class) | ||
| 1030 | ;; Assuming the point is at the start of a declarator in a declaration, | 1031 | ;; Assuming the point is at the start of a declarator in a declaration, |
| 1031 | ;; fontify the identifier it declares. (If TYPES is set, it does this via | 1032 | ;; fontify the identifier it declares. (If TYPES is set, it does this via |
| 1032 | ;; the macro `c-fontify-types-and-refs'.) | 1033 | ;; the macro `c-fontify-types-and-refs'.) |
| @@ -1040,6 +1041,11 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1040 | ;; non-nil, we are not at the top-level ("top-level" includes being directly | 1041 | ;; non-nil, we are not at the top-level ("top-level" includes being directly |
| 1041 | ;; inside a class or namespace, etc.). | 1042 | ;; inside a class or namespace, etc.). |
| 1042 | ;; | 1043 | ;; |
| 1044 | ;; TEMPLATE-CLASS is non-nil when the declaration is in template delimiters | ||
| 1045 | ;; and was introduced by, e.g. "typename" or "class", such that if there is | ||
| 1046 | ;; a default (introduced by "="), it will be fontified as a type. | ||
| 1047 | ;; E.g. "<class X = Y>". | ||
| 1048 | ;; | ||
| 1043 | ;; Nil is always returned. The function leaves point at the delimiter after | 1049 | ;; Nil is always returned. The function leaves point at the delimiter after |
| 1044 | ;; the last declarator it processes. | 1050 | ;; the last declarator it processes. |
| 1045 | ;; | 1051 | ;; |
| @@ -1112,6 +1118,13 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1112 | 1118 | ||
| 1113 | (goto-char next-pos) | 1119 | (goto-char next-pos) |
| 1114 | (setq pos nil) ; So as to terminate the enclosing `while' form. | 1120 | (setq pos nil) ; So as to terminate the enclosing `while' form. |
| 1121 | (if (and template-class | ||
| 1122 | (eq got-init ?=) ; C++ "<class X = Y>"? | ||
| 1123 | (c-forward-token-2 1 nil limit) ; Over "=" | ||
| 1124 | (let ((c-promote-possible-types t)) | ||
| 1125 | (c-forward-type t))) ; Over "Y" | ||
| 1126 | (setq list nil)) ; Shouldn't be needed. We can't have a list, here. | ||
| 1127 | |||
| 1115 | (when list | 1128 | (when list |
| 1116 | ;; Jump past any initializer or function prototype to see if | 1129 | ;; Jump past any initializer or function prototype to see if |
| 1117 | ;; there's a ',' to continue at. | 1130 | ;; there's a ',' to continue at. |
| @@ -1340,8 +1353,12 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1340 | (c-backward-syntactic-ws) | 1353 | (c-backward-syntactic-ws) |
| 1341 | (and (c-simple-skip-symbol-backward) | 1354 | (and (c-simple-skip-symbol-backward) |
| 1342 | (looking-at c-paren-stmt-key)))) | 1355 | (looking-at c-paren-stmt-key)))) |
| 1343 | t))) | 1356 | t)) |
| 1344 | 1357 | (template-class (and (eq context '<>) | |
| 1358 | (save-excursion | ||
| 1359 | (goto-char match-pos) | ||
| 1360 | (c-forward-syntactic-ws) | ||
| 1361 | (looking-at c-template-typename-key))))) | ||
| 1345 | ;; Fix the `c-decl-id-start' or `c-decl-type-start' property | 1362 | ;; Fix the `c-decl-id-start' or `c-decl-type-start' property |
| 1346 | ;; before the first declarator if it's a list. | 1363 | ;; before the first declarator if it's a list. |
| 1347 | ;; `c-font-lock-declarators' handles the rest. | 1364 | ;; `c-font-lock-declarators' handles the rest. |
| @@ -1353,10 +1370,9 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1353 | (if (cadr decl-or-cast) | 1370 | (if (cadr decl-or-cast) |
| 1354 | 'c-decl-type-start | 1371 | 'c-decl-type-start |
| 1355 | 'c-decl-id-start))))) | 1372 | 'c-decl-id-start))))) |
| 1356 | |||
| 1357 | (c-font-lock-declarators | 1373 | (c-font-lock-declarators |
| 1358 | (min limit (point-max)) decl-list | 1374 | (min limit (point-max)) decl-list |
| 1359 | (cadr decl-or-cast) (not toplev))) | 1375 | (cadr decl-or-cast) (not toplev) template-class)) |
| 1360 | 1376 | ||
| 1361 | ;; A declaration has been successfully identified, so do all the | 1377 | ;; A declaration has been successfully identified, so do all the |
| 1362 | ;; fontification of types and refs that've been recorded. | 1378 | ;; fontification of types and refs that've been recorded. |
| @@ -1650,7 +1666,8 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1650 | ;; font-lock-keyword-face. It always returns NIL to inhibit this and | 1666 | ;; font-lock-keyword-face. It always returns NIL to inhibit this and |
| 1651 | ;; prevent a repeat invocation. See elisp/lispref page "Search-based | 1667 | ;; prevent a repeat invocation. See elisp/lispref page "Search-based |
| 1652 | ;; fontification". | 1668 | ;; fontification". |
| 1653 | (let ((decl-search-lim (c-determine-limit 1000)) | 1669 | (let ((here (point)) |
| 1670 | (decl-search-lim (c-determine-limit 1000)) | ||
| 1654 | paren-state encl-pos token-end context decl-or-cast | 1671 | paren-state encl-pos token-end context decl-or-cast |
| 1655 | start-pos top-level c-restricted-<>-arglists | 1672 | start-pos top-level c-restricted-<>-arglists |
| 1656 | c-recognize-knr-p) ; Strictly speaking, bogus, but it | 1673 | c-recognize-knr-p) ; Strictly speaking, bogus, but it |
| @@ -1667,26 +1684,27 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1667 | (when (or (bobp) | 1684 | (when (or (bobp) |
| 1668 | (memq (char-before) '(?\; ?{ ?}))) | 1685 | (memq (char-before) '(?\; ?{ ?}))) |
| 1669 | (setq token-end (point)) | 1686 | (setq token-end (point)) |
| 1670 | (c-forward-syntactic-ws) | 1687 | (c-forward-syntactic-ws here) |
| 1671 | ;; We're now putatively at the declaration. | 1688 | (when (< (point) here) |
| 1672 | (setq start-pos (point)) | 1689 | ;; We're now putatively at the declaration. |
| 1673 | (setq paren-state (c-parse-state)) | 1690 | (setq start-pos (point)) |
| 1674 | ;; At top level or inside a "{"? | 1691 | (setq paren-state (c-parse-state)) |
| 1675 | (if (or (not (setq encl-pos | 1692 | ;; At top level or inside a "{"? |
| 1676 | (c-most-enclosing-brace paren-state))) | 1693 | (if (or (not (setq encl-pos |
| 1677 | (eq (char-after encl-pos) ?\{)) | 1694 | (c-most-enclosing-brace paren-state))) |
| 1678 | (progn | 1695 | (eq (char-after encl-pos) ?\{)) |
| 1679 | (setq top-level (c-at-toplevel-p)) | 1696 | (progn |
| 1680 | (let ((got-context (c-get-fontification-context | 1697 | (setq top-level (c-at-toplevel-p)) |
| 1681 | token-end nil top-level))) | 1698 | (let ((got-context (c-get-fontification-context |
| 1682 | (setq context (car got-context) | 1699 | token-end nil top-level))) |
| 1683 | c-restricted-<>-arglists (cdr got-context))) | 1700 | (setq context (car got-context) |
| 1684 | (setq decl-or-cast | 1701 | c-restricted-<>-arglists (cdr got-context))) |
| 1685 | (c-forward-decl-or-cast-1 token-end context nil)) | 1702 | (setq decl-or-cast |
| 1686 | (when (consp decl-or-cast) | 1703 | (c-forward-decl-or-cast-1 token-end context nil)) |
| 1687 | (goto-char start-pos) | 1704 | (when (consp decl-or-cast) |
| 1688 | (c-font-lock-single-decl limit decl-or-cast token-end | 1705 | (goto-char start-pos) |
| 1689 | context top-level))))))) | 1706 | (c-font-lock-single-decl limit decl-or-cast token-end |
| 1707 | context top-level)))))))) | ||
| 1690 | nil)) | 1708 | nil)) |
| 1691 | 1709 | ||
| 1692 | (defun c-font-lock-enclosing-decls (limit) | 1710 | (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'." | |||
| 1996 | 2 font-lock-type-face) | 2014 | 2 font-lock-type-face) |
| 1997 | `(,(concat "\\<\\(" re "\\)\\>") | 2015 | `(,(concat "\\<\\(" re "\\)\\>") |
| 1998 | 1 'font-lock-type-face))) | 2016 | 1 'font-lock-type-face))) |
| 1999 | |||
| 2000 | ;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct"). | ||
| 2001 | ,@(when (c-lang-const c-type-prefix-kwds) | ||
| 2002 | `((,(byte-compile | ||
| 2003 | `(lambda (limit) | ||
| 2004 | (c-fontify-types-and-refs | ||
| 2005 | ((c-promote-possible-types t) | ||
| 2006 | ;; The font-lock package in Emacs is known to clobber | ||
| 2007 | ;; `parse-sexp-lookup-properties' (when it exists). | ||
| 2008 | (parse-sexp-lookup-properties | ||
| 2009 | (cc-eval-when-compile | ||
| 2010 | (boundp 'parse-sexp-lookup-properties)))) | ||
| 2011 | (save-restriction | ||
| 2012 | ;; Narrow to avoid going past the limit in | ||
| 2013 | ;; `c-forward-type'. | ||
| 2014 | (narrow-to-region (point) limit) | ||
| 2015 | (while (re-search-forward | ||
| 2016 | ,(concat "\\<\\(" | ||
| 2017 | (c-make-keywords-re nil | ||
| 2018 | (c-lang-const c-type-prefix-kwds)) | ||
| 2019 | "\\)\\>") | ||
| 2020 | limit t) | ||
| 2021 | (unless (c-skip-comments-and-strings limit) | ||
| 2022 | (c-forward-syntactic-ws) | ||
| 2023 | ;; Handle prefix declaration specifiers. | ||
| 2024 | (while | ||
| 2025 | (or | ||
| 2026 | (when (or (looking-at c-prefix-spec-kwds-re) | ||
| 2027 | (and (c-major-mode-is 'java-mode) | ||
| 2028 | (looking-at "@[A-Za-z0-9]+"))) | ||
| 2029 | (c-forward-keyword-clause 1) | ||
| 2030 | t) | ||
| 2031 | (when (and c-opt-cpp-prefix | ||
| 2032 | (looking-at | ||
| 2033 | c-noise-macro-with-parens-name-re)) | ||
| 2034 | (c-forward-noise-clause) | ||
| 2035 | t))) | ||
| 2036 | ,(if (c-major-mode-is 'c++-mode) | ||
| 2037 | `(when (and (c-forward-type) | ||
| 2038 | (eq (char-after) ?=)) | ||
| 2039 | ;; In C++ we additionally check for a "class | ||
| 2040 | ;; X = Y" construct which is used in | ||
| 2041 | ;; templates, to fontify Y as a type. | ||
| 2042 | (forward-char) | ||
| 2043 | (c-forward-syntactic-ws) | ||
| 2044 | (c-forward-type)) | ||
| 2045 | `(c-forward-type)) | ||
| 2046 | ))))))))) | ||
| 2047 | |||
| 2048 | ;; Fontify symbols after closing braces as declaration | ||
| 2049 | ;; identifiers under the assumption that they are part of | ||
| 2050 | ;; declarations like "class Foo { ... } foo;". It's too | ||
| 2051 | ;; expensive to check this accurately by skipping past the | ||
| 2052 | ;; brace block, so we use the heuristic that it's such a | ||
| 2053 | ;; declaration if the first identifier is on the same line as | ||
| 2054 | ;; the closing brace. `c-font-lock-declarations' will later | ||
| 2055 | ;; override it if it turns out to be an new declaration, but | ||
| 2056 | ;; it will be wrong if it's an expression (see the test | ||
| 2057 | ;; decls-8.cc). | ||
| 2058 | ;; ,@(when (c-lang-const c-opt-block-decls-with-vars-key) | ||
| 2059 | ;; `((,(c-make-font-lock-search-function | ||
| 2060 | ;; (concat "}" | ||
| 2061 | ;; (c-lang-const c-single-line-syntactic-ws) | ||
| 2062 | ;; "\\(" ; 1 + c-single-line-syntactic-ws-depth | ||
| 2063 | ;; (c-lang-const c-type-decl-prefix-key) | ||
| 2064 | ;; "\\|" | ||
| 2065 | ;; (c-lang-const c-symbol-key) | ||
| 2066 | ;; "\\)") | ||
| 2067 | ;; `((c-font-lock-declarators limit t nil) ; That nil says use `font-lock-variable-name-face'; | ||
| 2068 | ;; ; t would mean `font-lock-function-name-face'. | ||
| 2069 | ;; (progn | ||
| 2070 | ;; (c-put-char-property (match-beginning 0) 'c-type | ||
| 2071 | ;; 'c-decl-id-start) | ||
| 2072 | ;; ; 'c-decl-type-start) | ||
| 2073 | ;; (goto-char (match-beginning | ||
| 2074 | ;; ,(1+ (c-lang-const | ||
| 2075 | ;; c-single-line-syntactic-ws-depth))))) | ||
| 2076 | ;; (goto-char (match-end 0))))))) | ||
| 2077 | |||
| 2078 | ;; Fontify the type in C++ "new" expressions. | 2017 | ;; Fontify the type in C++ "new" expressions. |
| 2079 | ,@(when (c-major-mode-is 'c++-mode) | 2018 | ,@(when (c-major-mode-is 'c++-mode) |
| 2080 | ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)" | 2019 | ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)" |
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 7a285f93d34..9495d602e09 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el | |||
| @@ -1891,6 +1891,17 @@ the type of that expression." | |||
| 1891 | t (c-make-keywords-re t (c-lang-const c-typeof-kwds))) | 1891 | t (c-make-keywords-re t (c-lang-const c-typeof-kwds))) |
| 1892 | (c-lang-defvar c-typeof-key (c-lang-const c-typeof-key)) | 1892 | (c-lang-defvar c-typeof-key (c-lang-const c-typeof-key)) |
| 1893 | 1893 | ||
| 1894 | (c-lang-defconst c-template-typename-kwds | ||
| 1895 | "Keywords which, within a template declaration, can introduce a | ||
| 1896 | declaration with a type as a default value. This is used only in | ||
| 1897 | C++ Mode, e.g. \"<typename X = Y>\"." | ||
| 1898 | t nil | ||
| 1899 | c++ '("class" "typename")) | ||
| 1900 | |||
| 1901 | (c-lang-defconst c-template-typename-key | ||
| 1902 | t (c-make-keywords-re t (c-lang-const c-template-typename-kwds))) | ||
| 1903 | (c-lang-defvar c-template-typename-key (c-lang-const c-template-typename-key)) | ||
| 1904 | |||
| 1894 | (c-lang-defconst c-type-prefix-kwds | 1905 | (c-lang-defconst c-type-prefix-kwds |
| 1895 | "Keywords where the following name - if any - is a type name, and | 1906 | "Keywords where the following name - if any - is a type name, and |
| 1896 | where the keyword together with the symbol works as a type in | 1907 | where the keyword together with the symbol works as a type in |