unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#67523: check-declare doesn't account for shorthands
@ 2023-11-29  8:03 Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-11-29  9:56 ` João Távora
  0 siblings, 1 reply; 5+ messages in thread
From: Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-11-29  8:03 UTC (permalink / raw)
  To: 67523; +Cc: Adam Porter, Jonas Bernoulli, João Távora

On Emacs 29.1, when running `check-declare-file' on a file with
`declare-function' forms, I get

Warning (check-declare): said ‘some-nice-string-utils-foobar’ was defined in
some-nice-string-utils.el: function not found

The problem is that `check-declare-verify' attempts to search for the
full symbol name using this regular expression:

(setq re (format (if cflag
                     "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\""
                   "^[ \t]*(\\(fset[ \t]+'\\|\
cl-def\\(?:generic\\|method\\|un\\)\\|\
def\\(?:un\\|subst\\|foo\\|method\\|class\\|\
ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\\|\
\\(?:ine-obsolete-function-\\)?alias[ \t]+'\\|\
ine-overloadable-function\\)\\)\
[ \t]*%s\\([ \t;]+\\|$\\)")
                 (regexp-opt (mapcar 'cadr fnlist) t)))
(while (re-search-forward re nil t)
  ...
  )

where (mapcar 'cadr fnlist) is the full symbol name.

Since the full symbol name never appears in the file in which it was
defined, re-search-forward never finds it, and so "function not found".

A potential solution could be to convert the longhand symbol into its
shorthand form and pass that into re-search-forward.  This is tricky
since there may be multiple different shorthands which could yield the
same longhand form.  It might be more feasible to run re-search-forward
on a known common suffix portion of the symbol name, then with point on
the suspected definition, run `intern-soft' to get the full symbol name.

A workaround is to not use shorthands in function definitions.

Thoughts?

Joseph





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#67523: check-declare doesn't account for shorthands
  2023-11-29  8:03 bug#67523: check-declare doesn't account for shorthands Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-11-29  9:56 ` João Távora
  2023-11-29 10:35   ` João Távora
  0 siblings, 1 reply; 5+ messages in thread
From: João Távora @ 2023-11-29  9:56 UTC (permalink / raw)
  To: Joseph Turner; +Cc: 67523, Adam Porter, Jonas Bernoulli

On Wed, Nov 29, 2023 at 9:12 AM Joseph Turner <joseph@ushin.org> wrote:

> A potential solution could be to convert the longhand symbol into its
> shorthand form and pass that into re-search-forward.  This is tricky
> since there may be multiple different shorthands which could yield the
> same longhand form.  It might be more feasible to run re-search-forward
> on a known common suffix portion of the symbol name, then with point on
> the suspected definition, run `intern-soft' to get the full symbol name.

No, this is brittle.  Check-declare, if it's to be useful (is it?)
is probably meant to be as precise as possible.

> A workaround is to not use shorthands in function definitions.

That's letting the bad guys win :-)

> Thoughts?

As usual, my thoughts are that tools that read Lisp code
should use the Lisp reader, not regular expressions.

Here, check-declare should just walk the whole file.
When it finds a a symbol atom that matches a definition
form,  look in the next atom and check if it matches the probe.
If you don't want to intern all the symbols in the you can read
to a separate obarray I think.

João





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#67523: check-declare doesn't account for shorthands
  2023-11-29  9:56 ` João Távora
@ 2023-11-29 10:35   ` João Távora
  2023-11-29 11:12     ` João Távora
  0 siblings, 1 reply; 5+ messages in thread
From: João Távora @ 2023-11-29 10:35 UTC (permalink / raw)
  To: Joseph Turner; +Cc: 67523, Adam Porter, Jonas Bernoulli

On Wed, Nov 29, 2023 at 9:56 AM João Távora <joaotavora@gmail.com> wrote:
>
> On Wed, Nov 29, 2023 at 9:12 AM Joseph Turner <joseph@ushin.org> wrote:
>
> > A potential solution could be to convert the longhand symbol into its
> > shorthand form and pass that into re-search-forward.  This is tricky
> > since there may be multiple different shorthands which could yield the
> > same longhand form.  It might be more feasible to run re-search-forward
> > on a known common suffix portion of the symbol name, then with point on
> > the suspected definition, run `intern-soft' to get the full symbol name.
>
> No, this is brittle.  Check-declare, if it's to be useful (is it?)
> is probably meant to be as precise as possible.
>
> > A workaround is to not use shorthands in function definitions.
>
> That's letting the bad guys win :-)
>
> > Thoughts?
>
> As usual, my thoughts are that tools that read Lisp code
> should use the Lisp reader, not regular expressions.
>
> Here, check-declare should just walk the whole file.

Or maybe just this 100% guaranteed untested patch would work:

diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el
index c887d95210c..00440276643 100644
--- a/lisp/emacs-lisp/check-declare.el
+++ b/lisp/emacs-lisp/check-declare.el
@@ -145,6 +145,7 @@ check-declare-verify
     (if (file-regular-p fnfile)
         (with-temp-buffer
           (insert-file-contents fnfile)
+          (hack-local-variables) ;; for shorthands
           ;; defsubst's don't _have_ to be known at compile time.
           (setq re (format (if cflag
                                "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\""
@@ -158,7 +159,7 @@ check-declare-verify
                            (regexp-opt (mapcar 'cadr fnlist) t)))
           (while (re-search-forward re nil t)
             (skip-chars-forward " \t\n")
-            (setq fn (match-string 2)
+            (setq fn (symbol-name (car (read-from-string (match-string 2))))
                   type (match-string 1)
                   ;; (min . max) for a fixed number of arguments, or
                   ;; arglists with optional elements.





^ permalink raw reply related	[flat|nested] 5+ messages in thread

* bug#67523: check-declare doesn't account for shorthands
  2023-11-29 10:35   ` João Távora
@ 2023-11-29 11:12     ` João Távora
  2023-12-10 10:57       ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 5+ messages in thread
From: João Távora @ 2023-11-29 11:12 UTC (permalink / raw)
  To: Joseph Turner; +Cc: 67523, Adam Porter, Jonas Bernoulli

On Wed, Nov 29, 2023 at 10:35 AM João Távora <joaotavora@gmail.com> wrote:
>
> On Wed, Nov 29, 2023 at 9:56 AM João Távora <joaotavora@gmail.com> wrote:
> >
> > On Wed, Nov 29, 2023 at 9:12 AM Joseph Turner <joseph@ushin.org> wrote:
> >
> > > A potential solution could be to convert the longhand symbol into its
> > > shorthand form and pass that into re-search-forward.  This is tricky
> > > since there may be multiple different shorthands which could yield the
> > > same longhand form.  It might be more feasible to run re-search-forward
> > > on a known common suffix portion of the symbol name, then with point on
> > > the suspected definition, run `intern-soft' to get the full symbol name.
> >
> > No, this is brittle.  Check-declare, if it's to be useful (is it?)
> > is probably meant to be as precise as possible.
> >
> > > A workaround is to not use shorthands in function definitions.
> >
> > That's letting the bad guys win :-)
> >
> > > Thoughts?
> >
> > As usual, my thoughts are that tools that read Lisp code
> > should use the Lisp reader, not regular expressions.
> >
> > Here, check-declare should just walk the whole file.
>
> Or maybe just this 100% guaranteed untested patch would work:

Sorry, that was 100% untested indeed.  This patch seems to work:

diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el
index c887d95210c..bc3844ca9be 100644
--- a/lisp/emacs-lisp/check-declare.el
+++ b/lisp/emacs-lisp/check-declare.el
@@ -145,21 +145,26 @@ check-declare-verify
     (if (file-regular-p fnfile)
         (with-temp-buffer
           (insert-file-contents fnfile)
+          (unless cflag
+            ;; for syntax and shorthands
+            (lisp-data-mode)
+            (hack-local-variables))
           ;; defsubst's don't _have_ to be known at compile time.
-          (setq re (format (if cflag
-                               "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\""
-                             "^[ \t]*(\\(fset[ \t]+'\\|\
+          (setq re (if cflag
+                       (format "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\""
+                               (regexp-opt (mapcar 'cadr fnlist) t))
+                     "^[ \t]*(\\(fset[ \t]+'\\|\
 cl-def\\(?:generic\\|method\\|un\\)\\|\
 def\\(?:un\\|subst\\|foo\\|method\\|class\\|\
 ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\\|\
 \\(?:ine-obsolete-function-\\)?alias[ \t]+'\\|\
 ine-overloadable-function\\)\\)\
-[ \t]*%s\\([ \t;]+\\|$\\)")
-                           (regexp-opt (mapcar 'cadr fnlist) t)))
+[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\([ \t;]+\\|$\\)"))
           (while (re-search-forward re nil t)
             (skip-chars-forward " \t\n")
-            (setq fn (match-string 2)
-                  type (match-string 1)
+            (setq fn (symbol-name (car (read-from-string (match-string 2)))))
+            (when (member fn (mapcar 'cadr fnlist))
+            (setq type (match-string 1)
                   ;; (min . max) for a fixed number of arguments, or
                   ;; arglists with optional elements.
                   ;; (min) for arglists with &rest.
@@ -202,7 +207,7 @@ check-declare-verify
                             (t
                              'err))
                   ;; alist of functions and arglist signatures.
-                  siglist (cons (cons fn sig) siglist)))))
+                  siglist (cons (cons fn sig) siglist))))))
     (dolist (e fnlist)
       (setq arglist (nth 2 e)
             type





^ permalink raw reply related	[flat|nested] 5+ messages in thread

* bug#67523: check-declare doesn't account for shorthands
  2023-11-29 11:12     ` João Távora
@ 2023-12-10 10:57       ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 5+ messages in thread
From: Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-12-10 10:57 UTC (permalink / raw)
  To: João Távora; +Cc: 67523, Adam Porter, Jonas Bernoulli


João Távora <joaotavora@gmail.com> writes:

> On Wed, Nov 29, 2023 at 10:35 AM João Távora <joaotavora@gmail.com> wrote:
>>
>> On Wed, Nov 29, 2023 at 9:56 AM João Távora <joaotavora@gmail.com> wrote:
>> >
>> > On Wed, Nov 29, 2023 at 9:12 AM Joseph Turner <joseph@ushin.org> wrote:
>> >
>> > > A potential solution could be to convert the longhand symbol into its
>> > > shorthand form and pass that into re-search-forward.  This is tricky
>> > > since there may be multiple different shorthands which could yield the
>> > > same longhand form.  It might be more feasible to run re-search-forward
>> > > on a known common suffix portion of the symbol name, then with point on
>> > > the suspected definition, run `intern-soft' to get the full symbol name.
>> >
>> > No, this is brittle.  Check-declare, if it's to be useful (is it?)
>> > is probably meant to be as precise as possible.
>> >
>> > > A workaround is to not use shorthands in function definitions.
>> >
>> > That's letting the bad guys win :-)
>> >
>> > > Thoughts?
>> >
>> > As usual, my thoughts are that tools that read Lisp code
>> > should use the Lisp reader, not regular expressions.
>> >
>> > Here, check-declare should just walk the whole file.
>>
>> Or maybe just this 100% guaranteed untested patch would work:
>
> Sorry, that was 100% untested indeed.  This patch seems to work:
>
> diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el
> index c887d95210c..bc3844ca9be 100644
> --- a/lisp/emacs-lisp/check-declare.el
> +++ b/lisp/emacs-lisp/check-declare.el
> @@ -145,21 +145,26 @@ check-declare-verify
>      (if (file-regular-p fnfile)
>          (with-temp-buffer
>            (insert-file-contents fnfile)
> +          (unless cflag
> +            ;; for syntax and shorthands
> +            (lisp-data-mode)
> +            (hack-local-variables))
>            ;; defsubst's don't _have_ to be known at compile time.
> -          (setq re (format (if cflag
> -                               "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\""
> -                             "^[ \t]*(\\(fset[ \t]+'\\|\
> +          (setq re (if cflag
> +                       (format "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\""
> +                               (regexp-opt (mapcar 'cadr fnlist) t))
> +                     "^[ \t]*(\\(fset[ \t]+'\\|\
>  cl-def\\(?:generic\\|method\\|un\\)\\|\
>  def\\(?:un\\|subst\\|foo\\|method\\|class\\|\
>  ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\\|\
>  \\(?:ine-obsolete-function-\\)?alias[ \t]+'\\|\
>  ine-overloadable-function\\)\\)\
> -[ \t]*%s\\([ \t;]+\\|$\\)")
> -                           (regexp-opt (mapcar 'cadr fnlist) t)))
> +[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\([ \t;]+\\|$\\)"))
>            (while (re-search-forward re nil t)
>              (skip-chars-forward " \t\n")
> -            (setq fn (match-string 2)
> -                  type (match-string 1)
> +            (setq fn (symbol-name (car (read-from-string (match-string 2)))))
> +            (when (member fn (mapcar 'cadr fnlist))
> +            (setq type (match-string 1)
>                    ;; (min . max) for a fixed number of arguments, or
>                    ;; arglists with optional elements.
>                    ;; (min) for arglists with &rest.
> @@ -202,7 +207,7 @@ check-declare-verify
>                              (t
>                               'err))
>                    ;; alist of functions and arglist signatures.
> -                  siglist (cons (cons fn sig) siglist)))))
> +                  siglist (cons (cons fn sig) siglist))))))
>      (dolist (e fnlist)
>        (setq arglist (nth 2 e)
>              type

IIUC, this patch is being merged in response to bug#67390.





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-12-10 10:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-29  8:03 bug#67523: check-declare doesn't account for shorthands Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-29  9:56 ` João Távora
2023-11-29 10:35   ` João Távora
2023-11-29 11:12     ` João Távora
2023-12-10 10:57       ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).