cc-mode: Make all parameters introduced in Emacs 26 optional

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

cc-mode: Make all parameters introduced in Emacs 26 optional

Jostein Kjønigsen
Hey everyone.

While cc-mode seems to be a foundation for lots of the major-modes shipped with Emacs, it's also used by third-party packages.

For major-modes shipped with Emacs, changes to the core cc-mode functions is not that big of a problem, since they can be changed in tandem with the changes to cc-mode itself.

For third party modules (like csharp-mode, which I maintain), changes to cc-mode core-functions are more problematic due to Emacs lacking reliable introspection capabilities.

As an example in the Emacs 26 branch c-font-lock-declarators is now declared like this:

(defun c-font-lock-declarators (limit list types not-top &optional template-class)
  ...)

While in Emacs 25.3 and earlier it's declared like this:

(defun c-font-lock-declarators (limit list types)
  ...)

Basically the number of mandatory parameters has been bumped from 3 to 4, with another optional parameter added.

These kinds of changes makes it harder for third party modules to maintain compatibility across Emacs-versions.

Wouldn't it be better to make all the new parameters optional and thus maintain compatibility? Are there any good reasons not to do so?

--
Regards
Jostein Kjønigsen


Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Alan Mackenzie
Hello, Jostein.

On Mon, Jan 22, 2018 at 09:09:21 +0100, Jostein Kjønigsen wrote:
> Hey everyone.

> While cc-mode seems to be a foundation for lots of the major-modes
> shipped with Emacs, it's also used by third-party packages.
> For major-modes shipped with Emacs, changes to the core cc-mode
> functions is not that big of a problem, since they can be changed in
> tandem with the changes to cc-mode itself.

> For third party modules (like csharp-mode, which I maintain), changes to
> cc-mode core-functions are more problematic due to Emacs lacking
> reliable introspection capabilities.

There's a convention in CC Mode that functions, macros, and variables
with a doc string are regarded as part of an "API" to derived modes, but
objects with merely a "doc comment" are regarded as internal to CC Mode,
and _much_ less secure against random changes.

> As an example in the Emacs 26 branch c-font-lock-declarators is now
> declared like this:
> (defun c-font-lock-declarators (limit list types not-top &optional template-
> class)  ...)
> While in Emacs 25.3 and earlier it's declared like this:

> (defun c-font-lock-declarators (limit list types)
>   ...)

> Basically the number of mandatory parameters has been bumped from 3 to
> 4, with another optional parameter added.

c-font-lock-declarators is one of these functions intended to be
"internal".  If a derived mode like csharp-mode is using it directly,
one of the following is true:
(i) There's a need for functionality which is currently lacking in CC
Mode.
(ii) The maintainer of the derived mode is unaware of existing CC Mode
functionality which would satisfy his need.
(iii) ???

> These kinds of changes makes it harder for third party modules to
> maintain compatibility across Emacs-versions.

Why is csharp-mode using c-font-lock-declarators at all?  Could it be
you're wanting to do something which currently can't be done with the
"API" functions/macros/variables?  If so, it might well be better to
amend CC Mode to provide this functionality.

> Wouldn't it be better to make *all *the new parameters optional and thus
> maintain compatibility? Are there any good reasons not to do so?

Well, to work properly, the caller of c-font-lock-declarators will need
to determine the `not-top' argument rather than just relying on a
randomish default.  The meaning of the function has changed.  `not-top'
doesn't seem suitable for being &optional.

Again, why is csharp-mode using this function?  Are there any other
"internal" functions/macros/variables it is using?

> --
> Regards
> Jostein Kjønigsen

> [hidden email] 🍵 [hidden email]
> https://jostein.kjonigsen.net

--
Alan Mackenzie (Nuremberg, Germany).

Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Matthew Carter-3
Alan Mackenzie <[hidden email]> writes:

> Hello, Jostein.
>
> On Mon, Jan 22, 2018 at 09:09:21 +0100, Jostein Kjønigsen wrote:
>> Hey everyone.
>
>> While cc-mode seems to be a foundation for lots of the major-modes
>> shipped with Emacs, it's also used by third-party packages.
>> For major-modes shipped with Emacs, changes to the core cc-mode
>> functions is not that big of a problem, since they can be changed in
>> tandem with the changes to cc-mode itself.
>
>> For third party modules (like csharp-mode, which I maintain), changes to
>> cc-mode core-functions are more problematic due to Emacs lacking
>> reliable introspection capabilities.
>
> There's a convention in CC Mode that functions, macros, and variables
> with a doc string are regarded as part of an "API" to derived modes, but
> objects with merely a "doc comment" are regarded as internal to CC Mode,
> and _much_ less secure against random changes.
>
>> As an example in the Emacs 26 branch c-font-lock-declarators is now
>> declared like this:
>> (defun c-font-lock-declarators (limit list types not-top &optional template-
>> class)  ...)
>> While in Emacs 25.3 and earlier it's declared like this:
>
>> (defun c-font-lock-declarators (limit list types)
>>   ...)
>
>> Basically the number of mandatory parameters has been bumped from 3 to
>> 4, with another optional parameter added.
>
> c-font-lock-declarators is one of these functions intended to be
> "internal".  If a derived mode like csharp-mode is using it directly,
> one of the following is true:
> (i) There's a need for functionality which is currently lacking in CC
> Mode.
> (ii) The maintainer of the derived mode is unaware of existing CC Mode
> functionality which would satisfy his need.
> (iii) ???
>
>> These kinds of changes makes it harder for third party modules to
>> maintain compatibility across Emacs-versions.
>
> Why is csharp-mode using c-font-lock-declarators at all?  Could it be
> you're wanting to do something which currently can't be done with the
> "API" functions/macros/variables?  If so, it might well be better to
> amend CC Mode to provide this functionality.
>
>> Wouldn't it be better to make *all *the new parameters optional and thus
>> maintain compatibility? Are there any good reasons not to do so?
>
> Well, to work properly, the caller of c-font-lock-declarators will need
> to determine the `not-top' argument rather than just relying on a
> randomish default.  The meaning of the function has changed.  `not-top'
> doesn't seem suitable for being &optional.
>
> Again, why is csharp-mode using this function?  Are there any other
> "internal" functions/macros/variables it is using?
>
>> --
>> Regards
>> Jostein Kjønigsen
>
>> [hidden email] 🍵 [hidden email]
>> https://jostein.kjonigsen.net

Somewhat on this subject - recent versions of Emacs have seemed to have
changed single quotes with text between the quotes with a length greater
than 1 to use a warn font face on the quotes, instead of the font string
face (likely because in C the single quote denotes a char, but in many
of the derived modes that cc-mode mentions in it's own comment set
(php-mode, dart-mode etc.), a single quoted string and double quoted
string are used interchangeably).

Does cc-mode have a setting to correct this and restore the old behavior?

--
Matthew Carter ([hidden email])
http://ahungry.com

Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Matthew Carter-3
Matthew Carter <[hidden email]> writes:

> Alan Mackenzie <[hidden email]> writes:
>
>> Hello, Jostein.
>>
>> On Mon, Jan 22, 2018 at 09:09:21 +0100, Jostein Kjønigsen wrote:
>>> Hey everyone.
>>
>>> While cc-mode seems to be a foundation for lots of the major-modes
>>> shipped with Emacs, it's also used by third-party packages.
>>> For major-modes shipped with Emacs, changes to the core cc-mode
>>> functions is not that big of a problem, since they can be changed in
>>> tandem with the changes to cc-mode itself.
>>
>>> For third party modules (like csharp-mode, which I maintain), changes to
>>> cc-mode core-functions are more problematic due to Emacs lacking
>>> reliable introspection capabilities.
>>
>> There's a convention in CC Mode that functions, macros, and variables
>> with a doc string are regarded as part of an "API" to derived modes, but
>> objects with merely a "doc comment" are regarded as internal to CC Mode,
>> and _much_ less secure against random changes.
>>
>>> As an example in the Emacs 26 branch c-font-lock-declarators is now
>>> declared like this:
>>> (defun c-font-lock-declarators (limit list types not-top &optional template-
>>> class)  ...)
>>> While in Emacs 25.3 and earlier it's declared like this:
>>
>>> (defun c-font-lock-declarators (limit list types)
>>>   ...)
>>
>>> Basically the number of mandatory parameters has been bumped from 3 to
>>> 4, with another optional parameter added.
>>
>> c-font-lock-declarators is one of these functions intended to be
>> "internal".  If a derived mode like csharp-mode is using it directly,
>> one of the following is true:
>> (i) There's a need for functionality which is currently lacking in CC
>> Mode.
>> (ii) The maintainer of the derived mode is unaware of existing CC Mode
>> functionality which would satisfy his need.
>> (iii) ???
>>
>>> These kinds of changes makes it harder for third party modules to
>>> maintain compatibility across Emacs-versions.
>>
>> Why is csharp-mode using c-font-lock-declarators at all?  Could it be
>> you're wanting to do something which currently can't be done with the
>> "API" functions/macros/variables?  If so, it might well be better to
>> amend CC Mode to provide this functionality.
>>
>>> Wouldn't it be better to make *all *the new parameters optional and thus
>>> maintain compatibility? Are there any good reasons not to do so?
>>
>> Well, to work properly, the caller of c-font-lock-declarators will need
>> to determine the `not-top' argument rather than just relying on a
>> randomish default.  The meaning of the function has changed.  `not-top'
>> doesn't seem suitable for being &optional.
>>
>> Again, why is csharp-mode using this function?  Are there any other
>> "internal" functions/macros/variables it is using?
>>
>>> --
>>> Regards
>>> Jostein Kjønigsen
>>
>>> [hidden email] 🍵 [hidden email]
>>> https://jostein.kjonigsen.net
>
> Somewhat on this subject - recent versions of Emacs have seemed to have
> changed single quotes with text between the quotes with a length greater
> than 1 to use a warn font face on the quotes, instead of the font string
> face (likely because in C the single quote denotes a char, but in many
> of the derived modes that cc-mode mentions in it's own comment set
> (php-mode, dart-mode etc.), a single quoted string and double quoted
> string are used interchangeably).
>
> Does cc-mode have a setting to correct this and restore the old behavior?

I hate to respond to my own post, but I have tracked this down to
#'c-parse-quotes-after-change (defined in cc-mode.el).  

--
Matthew Carter ([hidden email])
http://ahungry.com

Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Alan Mackenzie
Hello, Matthew.

On Sat, Feb 03, 2018 at 01:13:57 -0500, Matthew Carter wrote:
> Matthew Carter <[hidden email]> writes:

> > Somewhat on this subject - recent versions of Emacs have seemed to have
> > changed single quotes with text between the quotes with a length greater
> > than 1 to use a warn font face on the quotes, instead of the font string
> > face (likely because in C the single quote denotes a char, ....

That's indeed what's been changed.

> > .... but in many of the derived modes that cc-mode mentions in it's
> > own comment set (php-mode, dart-mode etc.), a single quoted string
> > and double quoted string are used interchangeably).

Ah.  This is indeed a CC Mode bug.

> > Does cc-mode have a setting to correct this and restore the old behavior?

It doesn't, but it will soon get one.  This will be a "lang variable", to
be set by each derived mode appropriately, as part of the language
definition.

> I hate to respond to my own post, but I have tracked this down to
> #'c-parse-quotes-after-change (defined in cc-mode.el).  

I don't hate it at all - it saves me work.  :-)

Thanks indeed for taking the trouble to report this bug.

> --
> Matthew Carter ([hidden email])
> http://ahungry.com

--
Alan Mackenzie (Nuremberg, Germany).

Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Jostein Kjønigsen
In reply to this post by Alan Mackenzie
Hey Alan.

Thanks for your answer!

There's a convention in CC Mode that functions, macros, and variables
with a doc string are regarded as part of an "API" to derived modes, but
objects with merely a "doc comment" are regarded as internal to CC Mode,
and _much_ less secure against random changes.

I was unaware of such a convention, but that's definitely useful to know for the future.

c-font-lock-declarators is one of these functions intended to be
"internal".  If a derived mode like csharp-mode is using it directly,
one of the following is true:
(i) There's a need for functionality which is currently lacking in CC
Mode.
(ii) The maintainer of the derived mode is unaware of existing CC Mode
functionality which would satisfy his need.
(iii) ???

That sounds like a valid assessment.

Why is csharp-mode using c-font-lock-declarators at all?  Could it be
you're wanting to do something which currently can't be done with the
"API" functions/macros/variables?  If so, it might well be better to
amend CC Mode to provide this functionality.

I'd hate to pass ball on this one, but I didn't write this original code.

It's fairly messy and dirty I picked up from the internet and decided to patch up when it started breaking with Emacs 24. Since then I've done my best to keep it working, but I've never had time to clean it properly up and I'm definitely not 100% in control w.r.t. what all parts of the code actually does.

Why this particular function was chosen is something I cannot directly answer for. This particular section of code has been unchanged since the first commit in any version-controlled version of this code I can find, by Dino Chiesa. As such, it's lacking a change/context which can further explain the choice of function.

Definitely not an optimal situation.

Well, to work properly, the caller of c-font-lock-declarators will need
to determine the `not-top' argument rather than just relying on a
randomish default.  The meaning of the function has changed.  `not-top'
doesn't seem suitable for being &optional.

That's a reasonable position indeed. I guess that puts me in the position where I need to better figure out how this particular part of the code actually works. I'm sure I'll appreciate that on some level further down the road.

When/if I can get that done, that leaves me in a position where I'll have to make a choice:

1. try to replace this broken section of code with something different (with a understanding of what it needs to do)
2. keep using c-font-lock-declarators, in case I don't have time for a rewrite.

In the latter case, I will face a compatibility-issue between Emacs versions.

Is there any way for package to know how many mandatory arguments a function has, to be able to branch out for compatibility reasons? My research so far haven't given me any obvious answer.

Again, why is csharp-mode using this function?  Are there any other
"internal" functions/macros/variables it is using?

That's indeed a good question. Seeing the kind of problems such usage lands me in, I'd definitely want to reduce the scope of that.

A quick skim of the source-code uncovers at least the following "internal" members used:

  • c-safe
  • c-put-character-property
  • c-put-font-lock-face
  • c-fontify-types-and-refs
  • c-forward-keyword-clause
  • c-font-lock-declarators
  • Not to mention it does monkey-patch/advice c-inside-bracelist-p and c-forward-objc-directive.

Like I said. This is dirty code, and I'm definitely not happy about the state of affairs. As such, any advice appreciated.

--
Regards
Jostein Kjønigsen




Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Stefan Monnier
> Is there any way for package to know how many mandatory arguments a
> function has, to be able to branch out for compatibility reasons?

The way I recommend is:

    (condition-case nil
        (call1 ...)
      (wrong-number-of-arguments
       (call2 ...)))


-- Stefan


Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Clément Pit-Claudel
On 2018-03-12 18:40, Stefan Monnier wrote:
>> Is there any way for package to know how many mandatory arguments a
>> function has, to be able to branch out for compatibility reasons?
>
> The way I recommend is:
>
>     (condition-case nil
>         (call1 ...)
>       (wrong-number-of-arguments
>        (call2 ...)))

Out of (mostly theoretical) curiosity: is there a way to restrict that condition-case to that specific function call? (rather than catching all incorrect calls in that call tree)

Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Stefan Monnier
>>     (condition-case nil
>>         (call1 ...)
>>       (wrong-number-of-arguments
>>        (call2 ...)))
>
> Out of (mostly theoretical) curiosity: is there a way to restrict that
> condition-case to that specific function call? (rather than catching all
> incorrect calls in that call tree)

No.  Actually just defining the notion of "that specific function call"
is already pretty tricky if you consider the case where `call1` is
advised, for example.


        Stefan


Reply | Threaded
Open this post in threaded view
|

Re: cc-mode: Make all parameters introduced in Emacs 26 optional

Jostein Kjønigsen
In reply to this post by Stefan Monnier
Thanks Stefan.

That's great help and for now will allow me to provide working C# support to Emacs 26 users, while I work out what to do with our troublesome usage of internal cc-mode functions. I really appreciate it.

I picked up this project as a community service when editing C# stopped working sometime in Emacs 24, and it would be pretty daft to simply give up on it now. :)

--
Regards
Jostein Kjønigsen


On Mon, Mar 12, 2018, at 11:40 PM, Stefan Monnier wrote:
Is there any way for package to know how many mandatory arguments a
function has, to be able to branch out for compatibility reasons?

The way I recommend is:

    (condition-case nil
        (call1 ...)
      (wrong-number-of-arguments
      (call2 ...)))


-- Stefan