[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master c882b4ea02: ; cperl-mode.el: Detect prototypes in anonymous subro
From: |
Harald Jörg |
Subject: |
master c882b4ea02: ; cperl-mode.el: Detect prototypes in anonymous subroutines |
Date: |
Wed, 2 Feb 2022 16:42:58 -0500 (EST) |
branch: master
commit c882b4ea02b705d866fbcdd886b577b9592479fe
Author: Harald Jörg <haj@posteo.de>
Commit: Harald Jörg <haj@posteo.de>
; cperl-mode.el: Detect prototypes in anonymous subroutines
My commit 3d49ad73e5a 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
---
lisp/progmodes/cperl-mode.el | 2 +-
.../cperl-mode-resources/proto-and-attrs.pl | 50 ++++++++++++++++++++++
test/lisp/progmodes/cperl-mode-tests.el | 49 +++++++++++++++++++++
3 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 8f33b3e3b7..94ecc45b15 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -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
diff --git a/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
b/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
new file mode 100644
index 0000000000..7138bf631d
--- /dev/null
+++ b/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
@@ -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) { ...; };
diff --git a/test/lisp/progmodes/cperl-mode-tests.el
b/test/lisp/progmodes/cperl-mode-tests.el
index 0124dad6f1..b8a3bd97d8 100644
--- a/test/lisp/progmodes/cperl-mode-tests.el
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -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."
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master c882b4ea02: ; cperl-mode.el: Detect prototypes in anonymous subroutines,
Harald Jörg <=