diff --git a/CHANGES.md b/CHANGES.md
index 322f1a3864..21f37ea581 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,9 +4,11 @@ Core Grammars:
- fix(css) fix overly greedy pseudo class matching [Bradley Mackey][]
- enh(arcade) updated to ArcGIS Arcade version 1.24 [Kristian Ekenes][]
+- enh(perl) add support for the new class system [Bruno Meneguele][]
[Bradley Mackey]: https://github.com/bradleymackey
[Kristian Ekenes]: https://github.com/ekenes
+[Bruno Meneguele]: https://github.com/bmeneg
## Version 11.9.0
diff --git a/src/languages/perl.js b/src/languages/perl.js
index 36ca7868db..f8923b8884 100644
--- a/src/languages/perl.js
+++ b/src/languages/perl.js
@@ -26,6 +26,7 @@ export default function(hljs) {
'chown',
'chr',
'chroot',
+ 'class',
'close',
'closedir',
'connect',
@@ -55,6 +56,7 @@ export default function(hljs) {
'exit',
'exp',
'fcntl',
+ 'field',
'fileno',
'flock',
'for',
@@ -114,6 +116,7 @@ export default function(hljs) {
'lt',
'ma',
'map',
+ 'method',
'mkdir',
'msgctl',
'msgget',
@@ -258,19 +261,45 @@ export default function(hljs) {
end: /\}/
// contains defined later
};
- const VAR = { variants: [
- { begin: /\$\d/ },
- { begin: regex.concat(
- /[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,
- // negative look-ahead tries to avoid matching patterns that are not
- // Perl at all like $ident$, @ident@, etc.
- `(?![A-Za-z])(?![@$%])`
- ) },
- {
- begin: /[$%@][^\s\w{]/,
- relevance: 0
- }
- ] };
+ const ATTR = {
+ scope: 'attr',
+ match: /\s+:\s*\w+(\s*\(.*?\))?/,
+ };
+ const VAR = {
+ scope: 'variable',
+ variants: [
+ { begin: /\$\d/ },
+ { begin: regex.concat(
+ /[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,
+ // negative look-ahead tries to avoid matching patterns that are not
+ // Perl at all like $ident$, @ident@, etc.
+ `(?![A-Za-z])(?![@$%])`
+ )
+ },
+ {
+ // Only $= is a special Perl variable and one can't declare @= or %=.
+ begin: /[$%@][^\s\w{=]|\$=/,
+ relevance: 0
+ }
+ ],
+ contains: [ ATTR ],
+ };
+ const NUMBER = {
+ className: 'number',
+ variants: [
+ // decimal numbers:
+ // include the case where a number starts with a dot (eg. .9), and
+ // the leading 0? avoids mixing the first and second match on 0.x cases
+ { match: /0?\.[0-9][0-9_]+\b/ },
+ // include the special versioned number (eg. v5.38)
+ { match: /\bv?(0|[1-9][0-9_]*(\.[0-9_]+)?|[1-9][0-9_]*)\b/ },
+ // non-decimal numbers:
+ { match: /\b0[0-7][0-7_]*\b/ },
+ { match: /\b0x[0-9a-fA-F][0-9a-fA-F_]*\b/ },
+ { match: /\b0b[0-1][0-1_]*\b/ },
+ ],
+ relevance: 0
+ }
const STRING_CONTAINS = [
hljs.BACKSLASH_ESCAPE,
SUBST,
@@ -385,11 +414,7 @@ export default function(hljs) {
}
]
},
- {
- className: 'number',
- begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
- relevance: 0
- },
+ NUMBER,
{ // regexp container
begin: '(\\/\\/|' + hljs.RE_STARTERS_RE + '|\\b(split|return|print|reverse|grep)\\b)\\s*',
keywords: 'split return print reverse grep',
@@ -431,11 +456,19 @@ export default function(hljs) {
},
{
className: 'function',
- beginKeywords: 'sub',
+ beginKeywords: 'sub method',
end: '(\\s*\\(.*?\\))?[;{]',
excludeEnd: true,
relevance: 5,
- contains: [ hljs.TITLE_MODE ]
+ contains: [ hljs.TITLE_MODE, ATTR ]
+ },
+ {
+ className: 'class',
+ beginKeywords: 'class',
+ end: '[;{]',
+ excludeEnd: true,
+ relevance: 5,
+ contains: [ hljs.TITLE_MODE, ATTR, NUMBER ]
},
{
begin: '-\\w\\b',
diff --git a/test/markup/mojolicious/default.expect.txt b/test/markup/mojolicious/default.expect.txt
index 692ae8d1fd..2238141169 100644
--- a/test/markup/mojolicious/default.expect.txt
+++ b/test/markup/mojolicious/default.expect.txt
@@ -1,21 +1,21 @@
-%layout 'bootstrap';
+% layout 'bootstrap';
% title "Import your subs";
%= form_for '/settings/import' => (method => 'post', enctype => 'multipart/form-data') => begin
%= file_field 'opmlfile' => multiple => 'true'
%= submit_button 'Import', 'class' => 'btn'
% end
<div>
-% if ($subs) {
+% if ($subs) {
<dl>
-% for my $item (@$subs) {
-% my ($dir, $align) = ($item->{rtl}) ? ('rtl', 'right') : ('ltr', 'left');
-<dt align="<%= $align %>"><a href="<%= $item->{'xmlUrl'} %>"><i class="icon-rss"></i> rss</a>
-<a dir="<%= $dir %>" href="<%= $item->{htmlUrl} %>"><%== $item->{title} %></a>
+% for my $item (@$subs) {
+% my ($dir, $align) = ($item->{rtl}) ? ('rtl', 'right') : ('ltr', 'left');
+<dt align="<%= $align %>"><a href="<%= $item->{'xmlUrl'} %>"><i class="icon-rss"></i> rss</a>
+<a dir="<%= $dir %>" href="<%= $item->{htmlUrl} %>"><%== $item->{title} %></a>
</dt>
<dd><b>Categories</b>
-%= join q{, }, sort @{ $item->{categories} || [] };
+%= join q{, }, sort @{ $item->{categories} || [] };
</dd>
</dl>
% }
</div>
-
\ No newline at end of file
+
diff --git a/test/markup/mojolicious/default.txt b/test/markup/mojolicious/default.txt
index 2cd9426f3e..bcd3f42a64 100644
--- a/test/markup/mojolicious/default.txt
+++ b/test/markup/mojolicious/default.txt
@@ -1,4 +1,4 @@
-%layout 'bootstrap';
+% layout 'bootstrap';
% title "Import your subs";
%= form_for '/settings/import' => (method => 'post', enctype => 'multipart/form-data') => begin
%= file_field 'opmlfile' => multiple => 'true'
diff --git a/test/markup/perl/class.expect.txt b/test/markup/perl/class.expect.txt
new file mode 100644
index 0000000000..f410d4b73f
--- /dev/null
+++ b/test/markup/perl/class.expect.txt
@@ -0,0 +1,10 @@
+use v5.38;
+
+class Example::Subclass :isa(Example::Base 2.345) {
+ field $_config :param :param :param;
+ field $_name : param = 'Test';
+
+ method test() {
+ $_name == 'Test' ? 'y' : 'n';
+ }
+}
diff --git a/test/markup/perl/class.txt b/test/markup/perl/class.txt
new file mode 100644
index 0000000000..a63f4064f5
--- /dev/null
+++ b/test/markup/perl/class.txt
@@ -0,0 +1,10 @@
+use v5.38;
+
+class Example::Subclass :isa(Example::Base 2.345) {
+ field $_config :param :param :param;
+ field $_name : param = 'Test';
+
+ method test() {
+ $_name == 'Test' ? 'y' : 'n';
+ }
+}
diff --git a/test/markup/perl/default.expect.txt b/test/markup/perl/default.expect.txt
index c12eb5ed56..715278d4fe 100644
--- a/test/markup/perl/default.expect.txt
+++ b/test/markup/perl/default.expect.txt
@@ -1,31 +1,31 @@
sub load
{
- my $flds = $c->db_load($id,@_) || do {
- Carp::carp "Can`t load (class: $c, id: $id): '$!'"; return undef
+ my $flds = $c->db_load($id,@_) || do {
+ Carp::carp "Can`t load (class: $c, id: $id): '$!'"; return undef
};
- my $o = $c->_perl_new();
- $id12 = $id / 24 / 3600;
- $o->{'ID'} = $id12 + 123;
+ my $o = $c->_perl_new();
+ $id12 = $id / 24 / 3600;
+ $o->{'ID'} = $id12 + 123;
- my $p = $o->props;
- my $vt;
- $string =~ m/^sought_text$/;
- $items = split //, 'abc';
- $string //= "bar";
- for my $key (keys %$p)
+ my $p = $o->props;
+ my $vt;
+ $string =~ m/^sought_text$/;
+ $items = split //, 'abc';
+ $string //= "bar";
+ for my $key (keys %$p)
{
- if(${$vt.'::property'}) {
- $o->{$key . '_real'} = $flds->{$key};
- tie $o->{$key}, 'CMSBuilder::Property', $o, $key;
+ if(${$vt.'::property'}) {
+ $o->{$key . '_real'} = $flds->{$key};
+ tie $o->{$key}, 'CMSBuilder::Property', $o, $key;
}
}
- $o->save if delete $o->{'_save_after_load'};
+ $o->save if delete $o->{'_save_after_load'};
- my $g = glob("/usr/bin/*");
+ my $g = glob("/usr/bin/*");
- return $o;
+ return $o;
}
__DATA__
@@ -39,4 +39,4 @@
\ No newline at end of file
+
diff --git a/test/markup/perl/number.expect.txt b/test/markup/perl/number.expect.txt
new file mode 100644
index 0000000000..eacb05cf6e
--- /dev/null
+++ b/test/markup/perl/number.expect.txt
@@ -0,0 +1,21 @@
+use v5.38;
+use 5.0020;
+
+my $number = 9;
+$number = 0;
+$number = 0_;
+$number = 00;
+$number = 0.99;
+$number = 99;
+$number = 99.9;
+$number = 99.99;
+$number = ._99;
+$number = 0x99FF;
+$number = 0x99_EE_FF;
+$number = 0x_99_FF;
+$number = 0b00101011;
+$number = 0b0010_1011;
+$number = 0b_0010_1011;
+$number = 0777;
+$number = 07_7_7;
+$number = 0_777;
diff --git a/test/markup/perl/number.txt b/test/markup/perl/number.txt
new file mode 100644
index 0000000000..5ce8913ba0
--- /dev/null
+++ b/test/markup/perl/number.txt
@@ -0,0 +1,21 @@
+use v5.38;
+use 5.0020;
+
+my $number = 9;
+$number = 0;
+$number = 0_;
+$number = 00;
+$number = 0.99;
+$number = 99;
+$number = 99.9;
+$number = 99.99;
+$number = ._99;
+$number = 0x99FF;
+$number = 0x99_EE_FF;
+$number = 0x_99_FF;
+$number = 0b00101011;
+$number = 0b0010_1011;
+$number = 0b_0010_1011;
+$number = 0777;
+$number = 07_7_7;
+$number = 0_777;