diff options
| author | Harald Jörg | 2022-02-02 22:30:09 +0100 |
|---|---|---|
| committer | Harald Jörg | 2022-02-02 22:42:05 +0100 |
| commit | c882b4ea02b705d866fbcdd886b577b9592479fe (patch) | |
| tree | dec72b06371f6e7ac460410ad800573be39e6ff7 /test | |
| parent | aa795a6223c31ec8804f2824c435dba3091c115f (diff) | |
| download | emacs-c882b4ea02b705d866fbcdd886b577b9592479fe.tar.gz emacs-c882b4ea02b705d866fbcdd886b577b9592479fe.zip | |
; 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
Diffstat (limited to 'test')
| -rw-r--r-- | test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl | 50 | ||||
| -rw-r--r-- | test/lisp/progmodes/cperl-mode-tests.el | 49 |
2 files changed, 99 insertions, 0 deletions
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 00000000000..7138bf631df --- /dev/null +++ b/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | # The next two lines are required as of 2022, but obsolescent | ||
| 2 | # as soon as signatures leave their "experimental" state | ||
| 3 | use feature 'signatures'; | ||
| 4 | no warnings 'experimental::signatures'; | ||
| 5 | |||
| 6 | # Tests for subroutine prototypes, signatures and the like | ||
| 7 | |||
| 8 | # Prototypes have syntactical properties different from "normal" Perl: | ||
| 9 | # Perl has a variable $), so ($)) is not an unbalanced parenthesis. | ||
| 10 | # On the other hand, in a prototype ($) is _not_ an open paren | ||
| 11 | # followed by the variable $), so the parens are balanced. Prototypes | ||
| 12 | # are somewhat frowned upon most of the times, but they are required | ||
| 13 | # for some Perl magic | ||
| 14 | |||
| 15 | # FIXME: 2022-02-02 CPerl mode does not handle subroutine signatures. | ||
| 16 | # In simple cases it mistakes them as prototypes, when attributes are | ||
| 17 | # present, it doesn't handle them at all. Variables in signatures | ||
| 18 | # SHOULD be fontified like variable declarations. | ||
| 19 | |||
| 20 | # Part 1: Named subroutines | ||
| 21 | # A prototype and a trivial subroutine attribute | ||
| 22 | { | ||
| 23 | no feature 'signatures'; # that's a prototype, not a signature | ||
| 24 | sub sub_1 ($) :lvalue { local $); } | ||
| 25 | } | ||
| 26 | |||
| 27 | # A prototype as an attribute (how it should be written these days) | ||
| 28 | sub sub_2 :prototype($) { ...; } | ||
| 29 | |||
| 30 | # A signature (these will soon-ish leave the experimental state) | ||
| 31 | sub sub_3 ($foo,$bar) { ...; } | ||
| 32 | |||
| 33 | # Attribute plus signature FIXME: Not yet supported | ||
| 34 | sub bad_sub_4 :prototype($$$) ($foo,$bar,$baz) { ...; } | ||
| 35 | |||
| 36 | # Part 2: Same constructs for anonymous subs | ||
| 37 | # A prototype and a trivial subroutine attribute | ||
| 38 | { | ||
| 39 | no feature 'signatures'; # that's a prototype, not a signature | ||
| 40 | my $subref_1 = sub ($) :lvalue { local $); }; | ||
| 41 | } | ||
| 42 | |||
| 43 | # A prototype as an attribute (how it should be written these days) | ||
| 44 | my $subref_2 = sub :prototype($) { ...; }; | ||
| 45 | |||
| 46 | # A signature (these will soon-ish leave the experimental state) | ||
| 47 | my $subref_3 = sub ($foo,$bar) { ...; }; | ||
| 48 | |||
| 49 | # Attribute plus signature | ||
| 50 | 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 0124dad6f17..b8a3bd97d8d 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. " | |||
| 154 | (should (equal (get-text-property (match-beginning 0) 'face) | 154 | (should (equal (get-text-property (match-beginning 0) 'face) |
| 155 | 'font-lock-keyword-face)))) | 155 | 'font-lock-keyword-face)))) |
| 156 | 156 | ||
| 157 | (ert-deftest cperl-test-fontify-attrs-and-signatures () | ||
| 158 | "Test fontification of the various combinations of subroutine | ||
| 159 | attributes, prototypes and signatures." | ||
| 160 | (skip-unless (eq cperl-test-mode #'cperl-mode)) | ||
| 161 | (let ((file (ert-resource-file "proto-and-attrs.pl"))) | ||
| 162 | (with-temp-buffer | ||
| 163 | (insert-file-contents file) | ||
| 164 | (goto-char (point-min)) | ||
| 165 | (funcall cperl-test-mode) | ||
| 166 | (font-lock-ensure) | ||
| 167 | |||
| 168 | ;; Named subroutines | ||
| 169 | (while (search-forward-regexp "\\_<sub_[[:digit:]]+" nil t) | ||
| 170 | (should (equal (get-text-property (match-beginning 0) 'face) | ||
| 171 | 'font-lock-function-name-face)) | ||
| 172 | (let ((start-of-sub (match-beginning 0)) | ||
| 173 | (end-of-sub (save-excursion (search-forward "}") (point)))) | ||
| 174 | |||
| 175 | ;; Prototypes are shown as strings | ||
| 176 | (when (search-forward-regexp " ([$%@*]*) " end-of-sub t) | ||
| 177 | (should (equal (get-text-property (1+ (match-beginning 0)) 'face) | ||
| 178 | 'font-lock-string-face))) | ||
| 179 | (goto-char start-of-sub) | ||
| 180 | (when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub t) | ||
| 181 | (should (equal (get-text-property (match-beginning 1) 'face) | ||
| 182 | 'font-lock-constant-face)) | ||
| 183 | (when (match-beginning 2) | ||
| 184 | (should (equal (get-text-property (match-beginning 2) 'face) | ||
| 185 | 'font-lock-string-face)))) | ||
| 186 | (goto-char end-of-sub))) | ||
| 187 | |||
| 188 | ;; Anonymous subroutines | ||
| 189 | (while (search-forward-regexp "= sub" nil t) | ||
| 190 | (let ((start-of-sub (match-beginning 0)) | ||
| 191 | (end-of-sub (save-excursion (search-forward "}") (point)))) | ||
| 192 | |||
| 193 | ;; Prototypes are shown as strings | ||
| 194 | (when (search-forward-regexp " ([$%@*]*) " end-of-sub t) | ||
| 195 | (should (equal (get-text-property (1+ (match-beginning 0)) 'face) | ||
| 196 | 'font-lock-string-face))) | ||
| 197 | (goto-char start-of-sub) | ||
| 198 | (when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub t) | ||
| 199 | (should (equal (get-text-property (match-beginning 1) 'face) | ||
| 200 | 'font-lock-constant-face)) | ||
| 201 | (when (match-beginning 2) | ||
| 202 | (should (equal (get-text-property (match-beginning 2) 'face) | ||
| 203 | 'font-lock-string-face)))) | ||
| 204 | (goto-char end-of-sub)))))) | ||
| 205 | |||
| 157 | (ert-deftest cperl-test-fontify-special-variables () | 206 | (ert-deftest cperl-test-fontify-special-variables () |
| 158 | "Test fontification of variables like $^T or ${^ENCODING}. | 207 | "Test fontification of variables like $^T or ${^ENCODING}. |
| 159 | These can occur as \"local\" aliases." | 208 | These can occur as \"local\" aliases." |