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 @@ # loads object 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; #$o->{'SHCUT'} = $flds->{'SHCUT'}; - 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'}; # GH-117 - my $g = glob("/usr/bin/*"); + my $g = glob("/usr/bin/*"); - return $o; + return $o; } __DATA__ @@ -39,4 +39,4 @@ =head1 NAME POD till the end of file - \ 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;