mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-08 00:33:13 -08:00
; cperl-mode.el: Detect prototypes in anonymous subroutines
My commit 3d49ad73e5 from 2021-09-143 had a flaw causing bad
fontification and indentation after anonymous subroutines with
a prototype.
* lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Correctly
process prototypes in anonymous subroutines
* test/lisp/progmodes/cperl-mode-tests.el
(cperl-test-fontify-attrs-and-signatures): new tests for various
combinations of attributes, prototypes, and signatures
* test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl: new
test source
This commit is contained in:
parent
aa795a6223
commit
c882b4ea02
3 changed files with 100 additions and 1 deletions
|
|
@ -3834,7 +3834,7 @@ recursive calls in starting lines of here-documents."
|
|||
"\\<" cperl-sub-regexp "\\>" ; sub with proto/attr
|
||||
"\\("
|
||||
cperl-white-and-comment-rex
|
||||
(rx (group (eval cperl--normal-identifier-rx)))
|
||||
(rx (opt (group (eval cperl--normal-identifier-rx))))
|
||||
"\\)"
|
||||
"\\("
|
||||
cperl-maybe-white-and-comment-rex
|
||||
|
|
|
|||
50
test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
Normal file
50
test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# The next two lines are required as of 2022, but obsolescent
|
||||
# as soon as signatures leave their "experimental" state
|
||||
use feature 'signatures';
|
||||
no warnings 'experimental::signatures';
|
||||
|
||||
# Tests for subroutine prototypes, signatures and the like
|
||||
|
||||
# Prototypes have syntactical properties different from "normal" Perl:
|
||||
# Perl has a variable $), so ($)) is not an unbalanced parenthesis.
|
||||
# On the other hand, in a prototype ($) is _not_ an open paren
|
||||
# followed by the variable $), so the parens are balanced. Prototypes
|
||||
# are somewhat frowned upon most of the times, but they are required
|
||||
# for some Perl magic
|
||||
|
||||
# FIXME: 2022-02-02 CPerl mode does not handle subroutine signatures.
|
||||
# In simple cases it mistakes them as prototypes, when attributes are
|
||||
# present, it doesn't handle them at all. Variables in signatures
|
||||
# SHOULD be fontified like variable declarations.
|
||||
|
||||
# Part 1: Named subroutines
|
||||
# A prototype and a trivial subroutine attribute
|
||||
{
|
||||
no feature 'signatures'; # that's a prototype, not a signature
|
||||
sub sub_1 ($) :lvalue { local $); }
|
||||
}
|
||||
|
||||
# A prototype as an attribute (how it should be written these days)
|
||||
sub sub_2 :prototype($) { ...; }
|
||||
|
||||
# A signature (these will soon-ish leave the experimental state)
|
||||
sub sub_3 ($foo,$bar) { ...; }
|
||||
|
||||
# Attribute plus signature FIXME: Not yet supported
|
||||
sub bad_sub_4 :prototype($$$) ($foo,$bar,$baz) { ...; }
|
||||
|
||||
# Part 2: Same constructs for anonymous subs
|
||||
# A prototype and a trivial subroutine attribute
|
||||
{
|
||||
no feature 'signatures'; # that's a prototype, not a signature
|
||||
my $subref_1 = sub ($) :lvalue { local $); };
|
||||
}
|
||||
|
||||
# A prototype as an attribute (how it should be written these days)
|
||||
my $subref_2 = sub :prototype($) { ...; };
|
||||
|
||||
# A signature (these will soon-ish leave the experimental state)
|
||||
my $subref_3 = sub ($foo,$bar) { ...; };
|
||||
|
||||
# Attribute plus signature
|
||||
my $subref_4 = sub :prototype($$$) ($foo,$bar,$baz) { ...; };
|
||||
|
|
@ -154,6 +154,55 @@ point in the distant past, and is still broken in perl-mode. "
|
|||
(should (equal (get-text-property (match-beginning 0) 'face)
|
||||
'font-lock-keyword-face))))
|
||||
|
||||
(ert-deftest cperl-test-fontify-attrs-and-signatures ()
|
||||
"Test fontification of the various combinations of subroutine
|
||||
attributes, prototypes and signatures."
|
||||
(skip-unless (eq cperl-test-mode #'cperl-mode))
|
||||
(let ((file (ert-resource-file "proto-and-attrs.pl")))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(goto-char (point-min))
|
||||
(funcall cperl-test-mode)
|
||||
(font-lock-ensure)
|
||||
|
||||
;; Named subroutines
|
||||
(while (search-forward-regexp "\\_<sub_[[:digit:]]+" nil t)
|
||||
(should (equal (get-text-property (match-beginning 0) 'face)
|
||||
'font-lock-function-name-face))
|
||||
(let ((start-of-sub (match-beginning 0))
|
||||
(end-of-sub (save-excursion (search-forward "}") (point))))
|
||||
|
||||
;; Prototypes are shown as strings
|
||||
(when (search-forward-regexp " ([$%@*]*) " end-of-sub t)
|
||||
(should (equal (get-text-property (1+ (match-beginning 0)) 'face)
|
||||
'font-lock-string-face)))
|
||||
(goto-char start-of-sub)
|
||||
(when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub t)
|
||||
(should (equal (get-text-property (match-beginning 1) 'face)
|
||||
'font-lock-constant-face))
|
||||
(when (match-beginning 2)
|
||||
(should (equal (get-text-property (match-beginning 2) 'face)
|
||||
'font-lock-string-face))))
|
||||
(goto-char end-of-sub)))
|
||||
|
||||
;; Anonymous subroutines
|
||||
(while (search-forward-regexp "= sub" nil t)
|
||||
(let ((start-of-sub (match-beginning 0))
|
||||
(end-of-sub (save-excursion (search-forward "}") (point))))
|
||||
|
||||
;; Prototypes are shown as strings
|
||||
(when (search-forward-regexp " ([$%@*]*) " end-of-sub t)
|
||||
(should (equal (get-text-property (1+ (match-beginning 0)) 'face)
|
||||
'font-lock-string-face)))
|
||||
(goto-char start-of-sub)
|
||||
(when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub t)
|
||||
(should (equal (get-text-property (match-beginning 1) 'face)
|
||||
'font-lock-constant-face))
|
||||
(when (match-beginning 2)
|
||||
(should (equal (get-text-property (match-beginning 2) 'face)
|
||||
'font-lock-string-face))))
|
||||
(goto-char end-of-sub))))))
|
||||
|
||||
(ert-deftest cperl-test-fontify-special-variables ()
|
||||
"Test fontification of variables like $^T or ${^ENCODING}.
|
||||
These can occur as \"local\" aliases."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue