* bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent
@ 2013-09-19 2:44 Ivan Andrus
2013-09-30 3:31 ` Ivan Andrus
0 siblings, 1 reply; 5+ messages in thread
From: Ivan Andrus @ 2013-09-19 2:44 UTC (permalink / raw)
To: 15415
[-- Attachment #1: Type: text/plain, Size: 1143 bytes --]
Font locking of C++ constructors is somewhat inconsistent. This is no
doubt complicated by the fact that unlike other function declarations
they "don't have a return type".
When a single argument is not used but named, the constructor is not
fontified (normally it's fontified with `font-lock-function-name-face').
If the keyword explicit is used, then the argument type is fontified as
a variable, and the constructor name is fontified as a type. Perhaps
interestingly, naming the parameter or adding another parameter causes
fontification to work correctly (with or without explicit).
I have included a sample file below with comments on what I see in `emacs -q`
class Bob
{
// string is `font-lock-type-face', Bob is `font-lock-function-name-face'
Bob( string bob );
// string and Bob are not fontified (though I sometimes see string fontified as a type)
Bob( string );
// string is `font-lock-variable-name-face', Bob is `font-lock-type-face'
explicit Bob( string );
// string is `font-lock-type-face', Bob is `font-lock-function-name-face'
explicit Bob( string, string );
};
[-- Attachment #2: constructors.pdf --]
[-- Type: application/pdf, Size: 33105 bytes --]
[-- Attachment #3: Type: text/plain, Size: 1340 bytes --]
Thanks,
Ivan
In GNU Emacs 24.3.50.1 (i386-apple-darwin12.5.0, NS apple-appkit-1187.39)
of 2013-09-16 on ivanandres-MacBookPro
Bzr revision: 114309 rgm@gnu.org-20130916192145-tr5qrfdmhcq3a563
Windowing system distributor `Apple', version 10.3.1187
Configured using:
`configure --with-ns --with-xml2'
Important settings:
locale-coding-system: nil
default enable-multibyte-characters: t
Major mode: C++/lah
Minor modes in effect:
diff-auto-refine-mode: t
eldoc-mode: t
highlight-parentheses-mode: t
hl-sexp-mode: t
highlight-symbol-mode: t
which-function-mode: t
show-paren-mode: t
msb-mode: t
minibuffer-depth-indicate-mode: t
global-hl-line-mode: t
delete-selection-mode: t
auto-image-file-mode: t
auto-insert-mode: t
yas-global-mode: t
yas-minor-mode: t
shell-dirtrack-mode: t
ido-everywhere: t
global-visible-mark-mode: t
visible-mark-mode: t
gvol-mode: t
recentf-mode: t
desktop-save-mode: t
drag-stuff-global-mode: t
drag-stuff-mode: t
tooltip-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
column-number-mode: t
line-number-mode: t
transient-mark-mode: t
abbrev-mode: t
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent
2013-09-19 2:44 bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent Ivan Andrus
@ 2013-09-30 3:31 ` Ivan Andrus
2013-10-12 20:45 ` Alan Mackenzie
2013-10-19 15:18 ` Alan Mackenzie
0 siblings, 2 replies; 5+ messages in thread
From: Ivan Andrus @ 2013-09-30 3:31 UTC (permalink / raw)
To: 15415
Ivan Andrus <darthandrus@gmail.com> writes:
> Font locking of C++ constructors is somewhat inconsistent. This is no
> doubt complicated by the fact that unlike other function declarations
> they "don't have a return type".
>
> When a single argument is not used but named, the constructor is not
> fontified (normally it's fontified with `font-lock-function-name-face').
> If the keyword explicit is used, then the argument type is fontified as
> a variable, and the constructor name is fontified as a type. Perhaps
> interestingly, naming the parameter or adding another parameter causes
> fontification to work correctly (with or without explicit).
>
> I have included a sample file below with comments on what I see in `emacs -q`
>
>
> class Bob
> {
> // string is `font-lock-type-face', Bob is `font-lock-function-name-face'
> Bob( string bob );
> // string and Bob are not fontified (though I sometimes see string fontified as a type)
> Bob( string );
> // string is `font-lock-variable-name-face', Bob is `font-lock-type-face'
> explicit Bob( string );
> // string is `font-lock-type-face', Bob is `font-lock-function-name-face'
> explicit Bob( string, string );
> };
In fact, it's not just constructors that have this problem. For example
the following function declaration:
string lookup( size_t ) const;
Removing const, or adding a name to the size_t parameter causes
fontification to work correctly.
-Ivan
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent
2013-09-30 3:31 ` Ivan Andrus
@ 2013-10-12 20:45 ` Alan Mackenzie
2013-10-18 22:00 ` Ivan Andrus
2013-10-19 15:18 ` Alan Mackenzie
1 sibling, 1 reply; 5+ messages in thread
From: Alan Mackenzie @ 2013-10-12 20:45 UTC (permalink / raw)
To: Ivan Andrus; +Cc: 15415
Hello, Ivan.
On Sun, Sep 29, 2013 at 09:31:13PM -0600, Ivan Andrus wrote:
> Ivan Andrus <darthandrus@gmail.com> writes:
> > Font locking of C++ constructors is somewhat inconsistent. This is
> > no doubt complicated by the fact that unlike other function
> > declarations they "don't have a return type".
This is, indeed, problematic.
> > When a single argument is not used but named, the constructor is not
> > fontified (normally it's fontified with
> > `font-lock-function-name-face'). If the keyword explicit is used,
> > then the argument type is fontified as a variable, and the
> > constructor name is fontified as a type. Perhaps interestingly,
> > naming the parameter or adding another parameter causes fontification
> > to work correctly (with or without explicit).
Yes. The pertinent function, `c-forward-decl-or-cast-1', is somewhat
probablistic. If it gets sufficient clues from the context, it gets
things right, otherwise it has to guess, and sometimes will get things
wrong, particularly in C++, which doesn't have a nice context-free
syntax.
> > I have included a sample file below with comments on what I see in
> > `emacs -q`
> > class Bob
> > {
> > // string is `font-lock-type-face', Bob is `font-lock-function-name-face'
1 > > Bob( string bob );
> > // string and Bob are not fontified (though I sometimes see string fontified as a type)
2 > > Bob( string );
> > // string is `font-lock-variable-name-face', Bob is `font-lock-type-face'
3 > > explicit Bob( string );
> > // string is `font-lock-type-face', Bob is `font-lock-function-name-face'
4 > > explicit Bob( string, string );
> > };
> In fact, it's not just constructors that have this problem. For
> example the following function declaration:
5 > string lookup( size_t ) const;
> Removing const, or adding a name to the size_t parameter causes
> fontification to work correctly.
Yes.
Of the lines of code you've illustrated, 1 and 4 were OK. I've corrected
3 and 5, which were relatively simple.
2 is a problem, because it looks like a normal function call. If the
identifier in the parentheses (here "string") can be positively
identified as a type (for example, some use elsewhere can only be a type,
or it's a standard type like "string") it gets fontified. Otherwise,
it's assumed the construct is a function call. It would no doubt be
possible to check that the enclosing braces are a class declaration, and
that "Bob" is the name of the class, but this would slow down the
fontification, probably by a lot.
Would you please try out the patch below, and let me know how it goes.
It is based on the current source in the bzr trunk.
Again, thanks for such a crisp and concise bug report.
=== modified file 'lisp/progmodes/cc-engine.el'
*** lisp/progmodes/cc-engine.el 2013-09-28 17:17:01 +0000
--- lisp/progmodes/cc-engine.el 2013-10-12 20:18:26 +0000
***************
*** 6917,6923 ****
;; can happen since we don't know if
;; `c-restricted-<>-arglists' will be correct inside the
;; arglist paren that gets entered.
! c-parse-and-markup-<>-arglists)
(goto-char id-start)
--- 6917,6925 ----
;; can happen since we don't know if
;; `c-restricted-<>-arglists' will be correct inside the
;; arglist paren that gets entered.
! c-parse-and-markup-<>-arglists
! ;; Start of the identifier for which `got-identifier' was set.
! name-start)
(goto-char id-start)
***************
*** 6935,6941 ****
;; If the third submatch matches in C++ then
;; we're looking at an identifier that's a
;; prefix only if it specifies a member pointer.
! (when (setq got-identifier (c-forward-name))
(if (looking-at "\\(::\\)")
;; We only check for a trailing "::" and
;; let the "*" that should follow be
--- 6937,6945 ----
;; If the third submatch matches in C++ then
;; we're looking at an identifier that's a
;; prefix only if it specifies a member pointer.
! (when (progn (setq pos (point))
! (setq got-identifier (c-forward-name)))
! (setq name-start pos)
(if (looking-at "\\(::\\)")
;; We only check for a trailing "::" and
;; let the "*" that should follow be
***************
*** 6961,6967 ****
;; Skip over an identifier.
(or got-identifier
(and (looking-at c-identifier-start)
! (setq got-identifier (c-forward-name))))
;; Skip over type decl suffix operators.
(while (if (looking-at c-type-decl-suffix-key)
--- 6965,6973 ----
;; Skip over an identifier.
(or got-identifier
(and (looking-at c-identifier-start)
! (setq pos (point))
! (setq got-identifier (c-forward-name))
! (setq name-start pos)))
;; Skip over type decl suffix operators.
(while (if (looking-at c-type-decl-suffix-key)
***************
*** 7052,7074 ****
;; declaration.
(throw 'at-decl-or-cast t))
- (when (and got-parens
- (not got-prefix)
- (not got-suffix-after-parens)
- (or backup-at-type
- maybe-typeless
- backup-maybe-typeless))
- ;; Got a declaration of the form "foo bar (gnu);" where we've
- ;; recognized "bar" as the type and "gnu" as the declarator.
- ;; In this case it's however more likely that "bar" is the
- ;; declarator and "gnu" a function argument or initializer (if
- ;; `c-recognize-paren-inits' is set), since the parens around
- ;; "gnu" would be superfluous if it's a declarator. Shift the
- ;; type one step backward.
- (c-fdoc-shift-type-backward)))
! ;; Found no identifier.
(if backup-at-type
(progn
--- 7058,7084 ----
;; declaration.
(throw 'at-decl-or-cast t))
! (when (and got-parens
! (not got-prefix)
! ;; (not got-suffix-after-parens)
! (or backup-at-type
! maybe-typeless
! backup-maybe-typeless
! (eq at-decl-or-cast t)
! (save-excursion
! (goto-char name-start)
! (not (memq (c-forward-type) '(nil maybe))))))
! ;; Got a declaration of the form "foo bar (gnu);" or "bar
! ;; (gnu);" where we've recognized "bar" as the type and "gnu"
! ;; as the declarator. In this case it's however more likely
! ;; that "bar" is the declarator and "gnu" a function argument
! ;; or initializer (if `c-recognize-paren-inits' is set),
! ;; since the parens around "gnu" would be superfluous if it's
! ;; a declarator. Shift the type one step backward.
! (c-fdoc-shift-type-backward)))
+ ;; Found no identifier.
(if backup-at-type
(progn
> -Ivan
--
Alan Mackenzie (Nuremberg, Germany).
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent
2013-10-12 20:45 ` Alan Mackenzie
@ 2013-10-18 22:00 ` Ivan Andrus
0 siblings, 0 replies; 5+ messages in thread
From: Ivan Andrus @ 2013-10-18 22:00 UTC (permalink / raw)
To: Alan Mackenzie; +Cc: 15415@debbugs.gnu.org
[-- Attachment #1: Type: text/plain, Size: 8227 bytes --]
Oops, forgot to CC the bug.
I've been using the patch for a week now and haven't noticed any ill
effects.
Thanks,
Ivan
On Sat, Oct 12, 2013 at 2:45 PM, Alan Mackenzie <acm@muc.de> wrote:
> Hello, Ivan.
>
> On Sun, Sep 29, 2013 at 09:31:13PM -0600, Ivan Andrus wrote:
> > Ivan Andrus <darthandrus@gmail.com> writes:
>
> > > Font locking of C++ constructors is somewhat inconsistent. This is
> > > no doubt complicated by the fact that unlike other function
> > > declarations they "don't have a return type".
>
> This is, indeed, problematic.
>
> > > When a single argument is not used but named, the constructor is not
> > > fontified (normally it's fontified with
> > > `font-lock-function-name-face'). If the keyword explicit is used,
> > > then the argument type is fontified as a variable, and the
> > > constructor name is fontified as a type. Perhaps interestingly,
> > > naming the parameter or adding another parameter causes fontification
> > > to work correctly (with or without explicit).
>
> Yes. The pertinent function, `c-forward-decl-or-cast-1', is somewhat
> probablistic. If it gets sufficient clues from the context, it gets
> things right, otherwise it has to guess, and sometimes will get things
> wrong, particularly in C++, which doesn't have a nice context-free
> syntax.
>
> > > I have included a sample file below with comments on what I see in
> > > `emacs -q`
>
>
> > > class Bob
> > > {
> > > // string is `font-lock-type-face', Bob is
> `font-lock-function-name-face'
> 1 > > Bob( string bob );
> > > // string and Bob are not fontified (though I sometimes see
> string fontified as a type)
> 2 > > Bob( string );
> > > // string is `font-lock-variable-name-face', Bob is
> `font-lock-type-face'
> 3 > > explicit Bob( string );
> > > // string is `font-lock-type-face', Bob is
> `font-lock-function-name-face'
> 4 > > explicit Bob( string, string );
> > > };
>
> > In fact, it's not just constructors that have this problem. For
> > example the following function declaration:
>
> 5 > string lookup( size_t ) const;
>
> > Removing const, or adding a name to the size_t parameter causes
> > fontification to work correctly.
>
> Yes.
>
> Of the lines of code you've illustrated, 1 and 4 were OK. I've corrected
> 3 and 5, which were relatively simple.
>
> 2 is a problem, because it looks like a normal function call. If the
> identifier in the parentheses (here "string") can be positively
> identified as a type (for example, some use elsewhere can only be a type,
> or it's a standard type like "string") it gets fontified. Otherwise,
> it's assumed the construct is a function call. It would no doubt be
> possible to check that the enclosing braces are a class declaration, and
> that "Bob" is the name of the class, but this would slow down the
> fontification, probably by a lot.
>
> Would you please try out the patch below, and let me know how it goes.
> It is based on the current source in the bzr trunk.
>
> Again, thanks for such a crisp and concise bug report.
>
>
>
> === modified file 'lisp/progmodes/cc-engine.el'
> *** lisp/progmodes/cc-engine.el 2013-09-28 17:17:01 +0000
> --- lisp/progmodes/cc-engine.el 2013-10-12 20:18:26 +0000
> ***************
> *** 6917,6923 ****
> ;; can happen since we don't know if
> ;; `c-restricted-<>-arglists' will be correct inside the
> ;; arglist paren that gets entered.
> ! c-parse-and-markup-<>-arglists)
>
> (goto-char id-start)
>
> --- 6917,6925 ----
> ;; can happen since we don't know if
> ;; `c-restricted-<>-arglists' will be correct inside the
> ;; arglist paren that gets entered.
> ! c-parse-and-markup-<>-arglists
> ! ;; Start of the identifier for which `got-identifier' was set.
> ! name-start)
>
> (goto-char id-start)
>
> ***************
> *** 6935,6941 ****
> ;; If the third submatch matches in C++ then
> ;; we're looking at an identifier that's a
> ;; prefix only if it specifies a member pointer.
> ! (when (setq got-identifier (c-forward-name))
> (if (looking-at "\\(::\\)")
> ;; We only check for a trailing "::" and
> ;; let the "*" that should follow be
> --- 6937,6945 ----
> ;; If the third submatch matches in C++ then
> ;; we're looking at an identifier that's a
> ;; prefix only if it specifies a member pointer.
> ! (when (progn (setq pos (point))
> ! (setq got-identifier
> (c-forward-name)))
> ! (setq name-start pos)
> (if (looking-at "\\(::\\)")
> ;; We only check for a trailing "::" and
> ;; let the "*" that should follow be
> ***************
> *** 6961,6967 ****
> ;; Skip over an identifier.
> (or got-identifier
> (and (looking-at c-identifier-start)
> ! (setq got-identifier (c-forward-name))))
>
> ;; Skip over type decl suffix operators.
> (while (if (looking-at c-type-decl-suffix-key)
> --- 6965,6973 ----
> ;; Skip over an identifier.
> (or got-identifier
> (and (looking-at c-identifier-start)
> ! (setq pos (point))
> ! (setq got-identifier (c-forward-name))
> ! (setq name-start pos)))
>
> ;; Skip over type decl suffix operators.
> (while (if (looking-at c-type-decl-suffix-key)
> ***************
> *** 7052,7074 ****
> ;; declaration.
> (throw 'at-decl-or-cast t))
>
> - (when (and got-parens
> - (not got-prefix)
> - (not got-suffix-after-parens)
> - (or backup-at-type
> - maybe-typeless
> - backup-maybe-typeless))
> - ;; Got a declaration of the form "foo bar (gnu);" where
> we've
> - ;; recognized "bar" as the type and "gnu" as the
> declarator.
> - ;; In this case it's however more likely that "bar" is the
> - ;; declarator and "gnu" a function argument or initializer
> (if
> - ;; `c-recognize-paren-inits' is set), since the parens
> around
> - ;; "gnu" would be superfluous if it's a declarator. Shift
> the
> - ;; type one step backward.
> - (c-fdoc-shift-type-backward)))
>
> ! ;; Found no identifier.
>
> (if backup-at-type
> (progn
>
> --- 7058,7084 ----
> ;; declaration.
> (throw 'at-decl-or-cast t))
>
>
> ! (when (and got-parens
> ! (not got-prefix)
> ! ;; (not got-suffix-after-parens)
> ! (or backup-at-type
> ! maybe-typeless
> ! backup-maybe-typeless
> ! (eq at-decl-or-cast t)
> ! (save-excursion
> ! (goto-char name-start)
> ! (not (memq (c-forward-type) '(nil
> maybe))))))
> ! ;; Got a declaration of the form "foo bar (gnu);" or "bar
> ! ;; (gnu);" where we've recognized "bar" as the type and
> "gnu"
> ! ;; as the declarator. In this case it's however more
> likely
> ! ;; that "bar" is the declarator and "gnu" a function
> argument
> ! ;; or initializer (if `c-recognize-paren-inits' is set),
> ! ;; since the parens around "gnu" would be superfluous if
> it's
> ! ;; a declarator. Shift the type one step backward.
> ! (c-fdoc-shift-type-backward)))
>
> + ;; Found no identifier.
> (if backup-at-type
> (progn
>
>
>
>
>
> > -Ivan
>
> --
> Alan Mackenzie (Nuremberg, Germany).
>
[-- Attachment #2: Type: text/html, Size: 10013 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent
2013-09-30 3:31 ` Ivan Andrus
2013-10-12 20:45 ` Alan Mackenzie
@ 2013-10-19 15:18 ` Alan Mackenzie
1 sibling, 0 replies; 5+ messages in thread
From: Alan Mackenzie @ 2013-10-19 15:18 UTC (permalink / raw)
To: 15415-done
Bug fixed.
--
Alan Mackenzie (Nuremberg, Germany).
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-10-19 15:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-19 2:44 bug#15415: 24.3.50; c++-mode fontification for constructors is inconsistent Ivan Andrus
2013-09-30 3:31 ` Ivan Andrus
2013-10-12 20:45 ` Alan Mackenzie
2013-10-18 22:00 ` Ivan Andrus
2013-10-19 15:18 ` Alan Mackenzie
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.