aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2017-09-18 08:52:24 +0000
committerAlan Mackenzie2017-09-18 08:52:24 +0000
commit61a5c30e70926f48480b03b79f4f531c8d64418e (patch)
tree504d5533ad5177b4156dcc691cffc62ba510ee3e
parent198ba449845ffa557ac272c3219c703148648f53 (diff)
downloademacs-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.el149
-rw-r--r--lisp/progmodes/cc-langs.el11
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
1896declaration with a type as a default value. This is used only in
1897C++ 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
1896where the keyword together with the symbol works as a type in 1907where the keyword together with the symbol works as a type in